【问题标题】:Javascript - On click of icon show drop down menuJavascript - 单击图标显示下拉菜单
【发布时间】:2021-05-04 22:26:08
【问题描述】:

我试图在单击图标时显示下拉菜单。目前,单击包含在带有 onclick 功能的 anchor 标记内的图标时,没有任何反应,这在第一个示例中可以看到。

我试图通过在 onclick 锚标记内输入文本来解决此问题,该标记显示 DOWNLOAD REPORT 在单击文本时,下拉菜单按预期显示,但如果我要在右侧的图标,下拉菜单不会出现。

如何在单击图标而不是文本时显示下拉菜单?

这是我的代码示例:

function myFunction() {
    document.getElementById("myDropdown").classList.toggle("show");
}

function myFunction() {
    document.getElementById("myDropdown2").classList.toggle("show");
}



// Close the dropdown menu if the user clicks outside of it
window.onclick = function (event) {
    if (!event.target.matches('.dropbtn')) {
        var dropdowns = document.getElementsByClassName("dropdown-download");
        var i;
        for (i = 0; i < dropdowns.length; i++) {
            var openDropdown = dropdowns[i];
            if (openDropdown.classList.contains('show')) {
                openDropdown.classList.remove('show');
            }
        }
    }
}
a {
cursor: pointer;
}

.download-btn-container {
    display: inline-block;
    float: right;
   
}

.download-btn-container a {
    font-weight: 700;
    letter-spacing: .5px;
    color: #c94927;
}

/* Dropdown Content (Hidden by Default) */
.dropdown-download {
    display: none;
    position: absolute;
    background-color: #f1f1f1;
    min-width: 160px;
    box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
    z-index: 1;
}

    /* Links inside the dropdown */
    .dropdown-download a {
        color: black;
        padding: 12px 16px;
        text-decoration: none;
        display: block;
    }

        /* Change color of dropdown links on hover */
        .dropdown-download a:hover {
            background-color: #ddd
        }

/* Show the dropdown menu (use JS to add this class to the .dropdown-content container when the user clicks on the dropdown button) */
.show {
    display: block;
}
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet">
    

<div class="download-btn-container">
<span>DOWNLOAD LIST </span>
    <a onclick="myFunction()" title="Download List"  class="dropbtn"><span class='material-icons'>save_alt</span></a>
            <div id="myDropdown" class="dropdown-download">
              <a href="#">Link 1</a>
              <a href="#">Link 2</a>
              <a href="#">Link 3</a>
            </div>
        </div>
        
 
<br/>
<br/>
<br/>
 
 <div class="download-btn-container">
    <a onclick="myFunction()" title="Download List"  class="dropbtn"> DOWNLOAD LIST<span class='material-icons'>save_alt</span></a>
            <div id="myDropdown2" class="dropdown-download">
              <a href="#">Link 1</a>
              <a href="#">Link 2</a>
              <a href="#">Link 3</a>
            </div>
        </div>
        

【问题讨论】:

    标签: javascript html css


    【解决方案1】:

    我浏览了您的代码,发现了几个错误。

    错误 1 在您的示例中,您有两次命名的相同函数,所以我假设这只是为了测试,但请确保在测试时更新您的函数名称,例如。你的 JS 有 myFunction() 和 myFunction(),试试 myFunction() 和 myFunction2()。

    错误 2 您的 windows.onClick 事件需要重写如下:

    // Close the dropdown menu if the user clicks outside of it
    window.onclick = function (event) {
        if (!event.target.matches('.dropbtn')) {
            var dropdowns = document.getElementsByClassName("dropdown-download"),
                showEvent = 'show';
            for (var i = 0; i < dropdowns.length; i++) {
                var currentElement = dropdowns[i],
                    currentElementAsString = dropdowns[i].toString();
                if (currentElementAsString.localeCompare(showEvent)) {
                    currentElement.classList.remove('show');
                }
            }
        }
    }
    

    解释您的原始代码已经在您的 classList 中进行迭代,因此您实际上是在比较字符,特别是这一行:

    var dropdowns = document.getElementsByClassName("dropdown-download");
    var i;
    for (i = 0; i < dropdowns.length; i++) {
        var openDropdown = dropdowns[i];
        if (openDropdown.classList.contains('show')) {
            openDropdown.classList.remove('show');
        }
    }
    

    注意你是如何使用getElementsByClassName()的,这将在元素中返回一个类名数组,当你到达你的for循环时,你已经在类名中了,所以基本上你是遍历索引中的字符串。

    错误 3 您的事件触发器正在寻找 .dropbtn 类,但您的锚标记具有该类,而不是您的实际图标。这是我指的那一行:

    <a onclick="myFunction()" title="Download List"  class="dropbtn"><span class='material-icons'>save_alt</span></a>
    

    这应该改写成这样:

    <a onclick="myFunction()" title="Download List"  class="dropbtn material-icons">save_alt</a>
    

    如果您更喜欢另一种方式,则需要将 dropbtn 类添加到您的 material-icons span 中。我希望这是有道理的,如果您需要帮助,请告诉我。 :)

    Codepen

    【讨论】:

      【解决方案2】:

      我稍微重构了 javascript,从 HTML 中删除了 onclick 属性,并添加了一个可以在 forEach 循环中运行的函数。不要在两个按钮上添加相同的命名函数myFunction(),而是使用querySelectorAll 查询按钮元素并通过循环运行nodeList。运行一个使用 event.targets 父元素的函数来查找下拉元素,然后使用事件监听器为该元素切换 show点击

      您可以使用:e.target.parentNode.nextElementSibling.classList.toggle('show') event.target (这是你的 ICON) => .parentNode => (这是你的 .dropbtn 类) => .nextElementSibling => (.dropdown-download - 这是你的隐藏元素) => .classList.toggle('show') (切换类.show)

      注意:另外,不确定您是否打算将第二个 DOWNLOAD LIST 包含在您的 a 标记中,这与第一个不同。如果是这样,代码将需要一个额外的条件来运行,就像我所布置的那样。

      let btns = document.querySelectorAll('.dropbtn')
      // This returns a nodeList which can use the forEach method to loop over the list of nodes
      
      // simple one line function to get the event targets parent and nextElementsSibling
      function showDrpDown(e) {
          e.target.parentNode.nextElementSibling.classList.toggle('show')
      }
      
      // loop and eventListener to handle each nodeLists click event
      btns.forEach(btn => {
        btn.addEventListener('click', showDrpDown)
      })
      a {
        cursor: pointer;
      }
      
      .download-btn-container {
        display: inline-block;
        float: right;
      }
      
      .download-btn-container a {
        font-weight: 700;
        letter-spacing: .5px;
        color: #c94927;
      }
      
      
      /* Dropdown Content (Hidden by Default) */
      
      .dropdown-download {
        display: none;
        position: absolute;
        background-color: #f1f1f1;
        min-width: 160px;
        box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
        z-index: 1;
      }
      
      
      /* Links inside the dropdown */
      
      .dropdown-download a {
        color: black;
        padding: 12px 16px;
        text-decoration: none;
        display: block;
      }
      
      
      /* Change color of dropdown links on hover */
      
      .dropdown-download a:hover {
        background-color: #ddd
      }
      
      
      /* Show the dropdown menu (use JS to add this class to the .dropdown-content container when the user clicks on the dropdown button) */
      
      .show {
        display: block;
      }
      <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
      
      
      <div class="download-btn-container">
        <span>DOWNLOAD LIST </span>
        <a title="Download List" class="dropbtn"><span class='material-icons'>save_alt</span></a>
        <div id="myDropdown" class="dropdown-download">
          <a href="#">Link 1 - drpdown1</a>
          <a href="#">Link 2 - drpdown1</a>
          <a href="#">Link 3 - drpdown1</a>
        </div>
      </div>
      
      
      <br/>
      <br/>
      <br/>
      
      <div class="download-btn-container">
        <span>DOWNLOAD LIST </span>
        <a title="Download List" class="dropbtn"><span class='material-icons'>save_alt</span></a>
        <div id="myDropdown2" class="dropdown-download">
          <a href="#">Link 1 - drpdown2</a>
          <a href="#">Link 2 - drpdown2</a>
          <a href="#">Link 3 - drpdown2</a>
        </div>
      </div>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-04-18
        • 1970-01-01
        • 1970-01-01
        • 2020-11-29
        • 2013-06-05
        • 2021-09-09
        • 2016-12-06
        相关资源
        最近更新 更多