简体   繁体   English

Javascript - 单击图标显示下拉菜单

[英]Javascript - On click of icon show drop down menu

I am attempting to show a drop down menu on click of an icon.我试图在单击图标时显示下拉菜单。 At the moment, upon clicking on the icon that is wrapped inside of an anchor tag with an onclick function nothing happens which can be seen in the first example.目前,单击包含在带有 onclick function 的anchor标记内的图标时,没有任何反应,这在第一个示例中可以看到。

I attempted to work around this by inputting text inside of the onclick anchor tag that says DOWNLOAD REPORT upon clicking on the text, the drop down menu appears as expected but if I were to icon on the right, the drop down menu doesn't to appear.我试图通过在 onclick 锚标签中输入文本来解决此问题,该标签在单击文本时显示DOWNLOAD REPORT ,下拉菜单按预期显示,但如果我要在右侧图标,下拉菜单不会出现。

How can I get the drop down menu to display on click of the icon and not the text?如何在单击图标而不是文本时显示下拉菜单?

Here is my code samples:这是我的代码示例:

 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>

I went through your code and found a couple of errors.我浏览了你的代码,发现了几个错误。

Error 1 in your example you have the same function named twice, so I'm assuming that's just for testing, but make sure you update your function names when testing eg.错误 1在您的示例中,您有相同的 function 命名两次,所以我假设这只是为了测试,但请确保在测试时更新您的 function 名称,例如。 your JS has myFunction() and myFunction(), try myFunction() and myFunction2().你的 JS 有 myFunction() 和 myFunction(),试试 myFunction() 和 myFunction2()。

Error 2 your windows.onClick event needs to be rewritten more like this:错误 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');
            }
        }
    }
}

Explanation your original code was iterating through your classList already so you were essentially comparing characters, this line specifically:说明您的原始代码已经在遍历您的 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');
    }
}

notice how you're using getElementsByClassName() , this is going to return an array of class names within the element, by the time you get to your for loop, you're already in class names, so essentially you're iterating through the strings within your indices.注意你是如何使用getElementsByClassName()的,这将在元素中返回一个 class 名称的数组,当你进入你的 for 循环时,你已经在 class 名称中,所以基本上你正在迭代索引中的字符串。

Error 3 Your event trigger is looking for the .dropbtn class but your anchor tag has that class, not your actual icon.错误 3您的事件触发器正在寻找.dropbtn class 但您的锚标记具有 class,而不是您的实际图标。 Here is the line I'm referring to:这是我所指的行:

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

This should be rewritten like this:应该这样重写:

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

If you prefer the other way, you'll need to add dropbtn class to your material-icons span.如果您更喜欢另一种方式,则需要将 dropbtn class 添加到您的材质图标范围。 I hope this makes sense, let me know if you need help.我希望这是有道理的,如果您需要帮助,请告诉我。 :) :)

Codepen密码笔

I restructured the javascript a bit, removing the onclick attribute from the HTML and added a function that can be run in a forEach loop.我对 javascript 进行了一点重构,从 HTML 中删除了 onclick 属性,并在 aC 中添加了一个 ZC1C425268E1 run for for 785D14ZA4Z 属性。 Rather than adding the same named function myFunction() on both your buttons, query the button elements using querySelectorAll and run the nodeList through a loop.不要在两个按钮上添加同名的 function myFunction() ,而是使用querySelectorAll查询按钮元素并通过循环运行 nodeList。 Run a function that uses the event.targets parent elements to find the drop down element and then toggle the show class for that element using the event listener click .运行使用event.targets父元素的 function 来查找下拉元素,然后使用事件侦听器click切换该元素的show class 。

You can use: e.target.parentNode.nextElementSibling.classList.toggle('show') event.target ( this is your ICON ) => .parentNode => ( this is your.dropbtn class ) => .nextElementSibling => ( .dropdown-download - this is your hidden element ) => .classList.toggle('show') ( toggles the class .show )您可以使用: e.target.parentNode.nextElementSibling.classList.toggle('show') event.target这是你的图标)=> .parentNode =>(这是你的.dropbtn class )=> .nextElementSibling =>( .dropdown-download - 这是你的隐藏元素)=> .classList.toggle('show')切换 class .show

NOTE: Also, not sure if you intended to have the second DOWNLOAD LIST included in your a tag unlike the first.注意:另外,不确定您是否打算将第二个DOWNLOAD LIST包含在您的 a 标签中,这与第一个不同。 If so the code would need an additional conditional to run as I have it laid out.如果是这样,代码将需要一个额外的条件来运行,因为我已经布置好了。

 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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM