skip to Main Content

How can I change this to where when I hover the pointer outside the button and search-list div the search-list disappears? As it is, the search-list cannot be hidden when hovering outside the div or button.

I realize I likely need to change the javascript code, but I’m having trouble understanding how to do this. Thanks.

function ListToggle() {
  var L = document.getElementById("search-list");
  L.style.display = "block"; // <-- Set it to block
}
#search-list {
  width: 150px;
  height: 150px;
  background-color: aquamarine;
}
<button onclick="ListToggle()">Tests</button>

<div id="search-list" style="display:none">
  search-list
</div>

3

Answers


  1. EDIT: I just found out you want to hide the list when the mouse exits which @RoryMcCrossan already showed correctly. I just showed how to toggle the list using the same button. I will keep this answer anyway as it might give you some ideas.

    There are plenty of ways to handle such a thing. But all of them need the if statement. I will show you 3 examples.

    1. Check the current styles using style property:

    You can easily check the current style of the element and tell JS that if it is block set it to none or vice versa:

    function ListToggle() {
      // let's use a better name
      var searchList = document.getElementById("search-list");
    
      if(searchList.style.display === "block") {
         searchList.style.display = "none";
      } else {
         searchList.style.display = "black";
      }
     
      // or a simpler way:
      searchList.style.display = searchList.style.display === "block" ? "none" : "block";
    }
    
    2. outer variable

    You can define a variable outside of the function and set it the true or false which describes the state of the searchList.

    var isOpened = false;
    
    function ListToggle() {
      isOpened = !isOpened;  
      var searchList = document.getElementById("search-list");
    
      if(isOpened) {
         searchList.style.display = "block";
      } else {
         searchList.style.display = "none";
      }
    }
    
    3. Dataset (mix of CSS, JS, and HTML)

    If you are going to have many elements with the same functionality. You can do it using this approach. Here, we can set a dataset to our elements and switch the styles based on it using CSS. (read more about the dataset in Mozilla documentation) I will show you how:

    function ListToggle() {
      var searchList = document.getElementById("search-list");
    
      if(searchList.dataset.isOpened === "1") {
         searchList.dataset.isOpened = "0";
      } else {
         searchList.dataset.isOpened = "1";
      }
    }
    
    #search-list {
      display: none;
    }
    
    #search-list[data-is-opened="1"] {
      display: block;
    }
    

    You can also set the default state using HTML (optional in this example):

    <div id="search-list" data-is-opened="0">
      search-list
    </div>
    
    Login or Signup to reply.
  2. To do what you require you can hook a mousemove event to the document. In that event handler you can interrogate the event.target to see if it’s the button trigger or the search list, if it’s not, then hide the content.

    Note the use of addEventListener() in the JS instead of onX attributes in the HTML. The latter is bad practice and should be avoided where possible. In addition, note that I moved the CSS styling in to the stylesheet. Don’t put CSS in your HTML.

    const button = document.querySelector('#trigger');
    const searchList = document.querySelector('#search-list');
    
    button.addEventListener('click', () => {
      searchList.style.display = "block";
    });
    
    const updateListState = e => {
      const targetId = e.target.id;
      if (targetId !== 'trigger' && targetId !== 'search-list') {
        searchList.style.display = "none";
      }
    }
    document.addEventListener('mousemove', updateListState);
    #search-list {
      width: 150px;
      height: 150px;
      background-color: aquamarine;
      display: none;
    }
    <button id="trigger">Tests</button>
    <div id="search-list">
      search-list
    </div>

    That being said, it would be possible to achieve your desired affect much more simply by using CSS alone, assuming that having the list appear when the mouse hovers the trigger button meets your requirements:

    #search-list {
      width: 150px;
      height: 150px;
      background-color: aquamarine;
      display: none;
    }
    
    #search-list:hover,
    #trigger:hover + #search-list {
      display: block;
    }
    <button id="trigger">Tests</button>
    <div id="search-list">
      search-list
    </div>
    Login or Signup to reply.
  3. It is much better not to use inline styles or scripts, as most typical content-security-policy ‘s will ban both for being unsafe. You should do styles on a stylesheet, and code in a JS file.

      function ListToggle() {
        var L = document.getElementById("search-list");
    //        L.style.display = "block";  // <-- Set it to block
        L.classList.remove("hide");
      }
      #search-list {
        width: 150px;
        height: 150px;
        background-color: aquamarine;
      }
    
      .hide {
        display:none;
      }
      <button onclick="ListToggle()">Tests</button>
    
      <div id="search-list" class="hide">
        search-list
      </div>
      <script>
        document.querySelector("#search-list").addEventListener("mouseout", (e) => 
          {
             e.target.classList.add("hide");
          });
      </script>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search