简体   繁体   English

单击以打开和关闭菜单,不使用jquery

[英]Javascript click to open and close menu, NOT using jquery

I want to have a menu, that I can click on to open, and click on to close. 我想要一个菜单​​,我可以点击打开,然后点击关闭。 Similar to a hover menu, but with clicking, to open, and clicking to close. 与悬停菜单类似,但点击,打开,然后单击关闭。 I have three visible list items, with submenu's under. 我有三个可见的列表项,子菜单下。

These are hidden with css, display:none. 这些隐藏着css,display:none。 I can get them to show, with the keyword "this", and a for loop for checking if any 'ul', have more then 1 item, then list will open when clicked. 我可以使用关键字“this”显示它们,并使用for循环检查是否有'ul',有多个项目,然后单击时将打开列表。

As far as I could understand this code, I got some help here earlier. 据我所知,这段代码我早些时候得到了一些帮助。 Now I have read, and watched tutorials from buckysroom, and feel I understand a lot more, at least about arrays, and everything in the code, I can now understand, at least. 现在我已经阅读,并观看了来自buckysroom的教程,并且感觉我理解了更多,至少关于数组,以及代码中的所有内容,我现在至少可以理解。 I have this code at the moment. 我现在有这个代码。

function showMenu(parentElement){
    var uls= parentElement.getElementsByTagName("ul");
    if (uls.length > 0)
        uls[0].setAttribute("style","display: block");

 }

function load(){ 
    var lis = document.getElementsByTagName("li"); 
    for (var i = 0; i < lis.length; i++) {
        lis[i].addEventListener("click", function(){
            showMenu(this);
        }); 
    }
}

As I understood, finally, the 'for' loop, I see that this code opens any array, or like, any 'li' that has more than 1 ( [0] ) item, as 0 is 1 in array, and loops through to see if it has children. 据我所知,最后,'for'循环,我看到这个代码打开任何数组,或者像任何'li',它有多于1([0])项,因为0在数组中是1,并循环通过看看它是否有孩子。 If it does, it opens 'this' 'li's' 'ul'. 如果确实如此,它会打开'this''li'''ul'。

Since the load function, contains the showMenu function, and I have learned a little, to use functions inside functions, rather than copy myself, use arrays and variables, and assign them to eachother somehow. 由于load函数,包含了showMenu函数,并且我学到了一点,要在函数内部使用函数,而不是自己复制,使用数组和变量,并以某种方式将它们分配给彼此。 Buckysroom tutorials, at least helped me understand as much. Buckysroom教程,至少帮助我理解了。

Now.. My problem is I do not know enough Javascript to get my mind around this, and I would rather not use jQuery, but learn how this could be achieved with plain Javascript. 现在..我的问题是我不知道足够的Javascript来解决这个问题,我宁愿不使用jQuery,但要了解如何使用普通的Javascript实现这一点。

Any pointers would help alot, I have tried the following; 任何指针都会有所帮助,我尝试过以下几点;

Adding unique Id's to my three ul's, so I know can in fact open them with the above code, and I am able to close them, with another code, setting it back to "display:none". 添加我的三个ul的唯一ID,所以我知道可以用上面的代码打开它们,我可以用另一个代码关闭它们,将它设置回“display:none”。

The problem then, is I do not have the opportunity to open them again, and I understand that I am missing some piece, like stopPropagation or maybe, using addEventListener - Click, for this second part. 那么问题是,我没有机会再打开它们,我明白我错过了一些文章,比如stopPropagation,或者使用addEventListener - Click,这是第二部分。 As you may understand, the addeventListener, is something I got from a code in here. 您可能已经理解,addeventListener是我从这里的代码中获得的东西。

 function Meny1(){

    var unorderedList = document.getElementById("ul_1");

            var lis = unorderedList.getElementsByTagName("li");
            for (var i = 0; i < lis.length; i++) {

            lis[i].setAttribute("style","display: none");

            }
}

I figured out, that I can specify each menu-item with numbers, like [23], instead of [i], to target a single menu item, copy that line like this: 我想,我可以用数字指定每个菜单项,比如[23],而不是[i],以单个菜单项为目标,复制该行如下:

lis[23].setAttribute("style","display: none");
lis[24].setAttribute("style","display: none");

But as I understand, that is a bad practice, as it is terrible if I am to add another menu item, or remove one, and also is way to much copy-coding.. 但据我所知,这是一个不好的做法,因为如果我要添加另一个菜单项,或删除一个菜单项,这是很糟糕的,也是很多复制编码的方式..

My thought, is that I want something like this: html: 我的想法是,我想要这样的东西:html:

<div id ="cssmenu"></div>
<ul id="ul_1"><li>I have many li's in each 'ul'</li></ul>
<ul id="ul_2"><li>I have many li's in each 'ul'</li></ul>
<ul id="ul_3"><li>I have many li's in each 'ul'</li></ul>

css: CSS:

#cssmenu{display:block;}
#cssmenu ul li ul{display:none}

My thinking of how the js should be, and I DON'T use CLASSES: (I didn't do this, as w3c validator pointed out that I shouldn't). 我想到js应该如何,我不使用CLASSES :(我没有这样做,因为w3c验证器指出我不应该)。

function showAndCloseMenu1(){
var ul_1 = document.getElementbyId("ul_1");
    if(mouseclicked on ul_2 || mouseclicked on ul_3){
        close.ul_1(this)
    }
        if(mouseClicked ul_1){
         style.display = "block";
        }
}

And then the same naturally for ul_2 and ul_3, I have not gotten good enough yet to think about implementing all into one code, but I know that it is possible of course, with global variables, and by using attributes. 然后对于ul_2和ul_3自然也是如此,我还没有考虑将所有实现都集成到一个代码中,但我知道当然可以使用全局变量和使用属性。

Is there Anyone who can help me with this? 有没有人可以帮我这个?

I have tried to use jQuery, with no success, and as I said, would rather not, as I am eager to learn Javascript to the fullest extend! 我试图使用jQuery,没有成功,正如我所说,宁愿不,因为我渴望最大限度地学习Javascript! And I can read Javascript, jQuery is just a bunch of dollarsigns to me, with simplified Javascript inside. 我可以阅读Javascript,jQuery只是一堆美元符号给我,里面有简化的Javascript。

http://fiddle.jshell.net/ufcsccy3/ http://fiddle.jshell.net/ufcsccy3/

Here is a fiddle, but the menu doesn't work as it does in browsers, but you get the idea if you look there, its the menu on the left. 这是一个小提琴,但菜单不像在浏览器中那样工作,但如果你看到它,你就会明白它的左边菜单。

How can I have a show/hide function, in my navigation with Javascript? 如何在我的Javascript导航中有一个显示/隐藏功能? Am I thinking in the correct path here, as I see it, classes makes little difference, but maybe saves me some coding space thou. 我在这里思考正确的道路,正如我所看到的,班级没什么区别,但也许可以为我节省一些编码空间。

Thanks for any help whatsoever on this, cannot seem to get my head around a working solution for this! 感谢您对此提供的任何帮助,似乎无法解决这个问题的工作解决方案! I would like to have it like when I click on ul_1 first time, it opens. 我希望能够像第一次点击ul_1一样,打开它。 If I click it again, I want it to close. 如果我再次点击它,我希望它关闭。 If ul_1 is open, and I click ul_2, or ul_3, I want to open that one, and close ul_1 again, kinda standard menu navigation in my perspective. 如果ul_1已打开,我点击ul_2或ul_3,我想打开那个,然后再次关闭ul_1,在我的视角中有点标准菜单导航。

Just toggle an ID for the open menu. 只需切换打开菜单的ID即可。 One method, onclick , which does it all. 一种方法, onclick ,它可以完成所有工作。

 function showmenu(elem) { // Clear any currently open menu var openMenu = document.getElementById("activeMenu"); if (openMenu) { openMenu.removeAttribute("id"); // Stop if we're just closing the current menu if (openMenu === elem) { return; } } // Only apply it if the element actually has LI child nodes. // OPTIONAL: Will still work without if statement. if (elem.getElementsByTagName("li").length > 0) { elem.setAttribute("id", "activeMenu"); } } 
 ul { list-style: none; margin: 0; padding: 0; } ul li { float: left; padding: 0 10px; } ul ul { display: none; } ul ul li { float: none; } #activeMenu ul { display: block; } 
 <ul> <li onclick="showmenu(this)">Menu Item 1</li> <li onclick="showmenu(this)">Drop Down 1 <ul> <li>DD1 Item 1</li> <li>DD1 Item 2</li> </ul> </li> <li onclick="showmenu(this)">Drop Down 2 <ul> <li>DD2 Item 1</li> <li>DD2 Item 2</li> </ul> </li> </ul> 

Note that I used onclick just for simplicity. 请注意,我使用onclick只是为了简单起见。 Adding the click event you did is the right way. 添加您所做的点击事件是正确的方法。

function showMenu(elem) {
      // Clear any currently open menu
      var openMenu = document.getElementById("activeMenu");
  if (openMenu) {
        openMenu.removeAttribute("id");
        // Stop if we're just closing the current menu
        if (openMenu === elem) {
          return;
    }
  }

      // Only apply it if the element actually has LI child nodes.
      // OPTIONAL: Will still work without if statement.
      if (elem.getElementsByTagName("ul").length > 0) {
        elem.setAttribute("id", "activeMenu");
      }
    }

        function showSubMenu(elem) {
      // Clear any currently open menu
          var openMenu = document.getElementById("activeMenu");
      if (openMenu)
        openMenu.removeAttribute("id");
      var openSubMenu = document.getElementById("activeSubMenu");
      if (openSubMenu) {
        openSubMenu.removeAttribute("id");
        // Stop if we're just closing the current menu

      }

      // Only apply it if the element actually has LI child nodes.
      // OPTIONAL: Will still work without if statement.
      if (elem.getElementsByTagName("ul").length > 0) {
        elem.setAttribute("id", "activeSubMenu");
      }
    }
        function showLastSubMenu(elem) {
      // Clear any currently open menu
          var openMenu = document.getElementById("activeMenu");
      if (openMenu)
        openMenu.removeAttribute("id");
      var openSubMenu = document.getElementById("activeSubMenu");
      if (openSubMenu) 
        openSubMenu.removeAttribute("id");
        // Stop if we're just closing the current menu
    var openLastSubMenu = document.getElementById("activeSubMenu");
      if (openLastSubMenu) {
        openLastSubMenu.removeAttribute("id");

}
      // Only apply it if the element actually has LI child nodes.
      // OPTIONAL: Will still work without if statement.
      if (elem.getElementsByTagName("ul").length > 0) {
        elem.setAttribute("id", "activeLastSubMenu");
      }
    }

I post the full code, that with much help from @David resultet in a clickable menu solution, Thanks alot :) 我发布了完整的代码,在@David resultet的帮助下,在一个可点击的菜单解决方案中,非常感谢:)

the css items #someMenu ul, #somemenu ul li, and #someMenu ul ul had to be changed to classes, so .someMenu ul etc. #activeMenu > ul { display: block; cs项目#someMenu ul,#somemenu ul li和#someMenu ul ul必须更改为类,所以.someMenu ul等。#activeMenu> ul {display:block; } }

#activeSubMenu > ul {
  display: block;
}
#activeLastSubMenu > ul {

  display: block;
}  

And in the html, 在HTML中,

<nav id ="someMenu" class="someMenu">
function showMenu on the first level li's, 
function showSubMenu for next level
function showLastSubMenu for the last sub's (I had max 3 levels)

Alot of repeating, so I will try and make it into less code, with array and addEventListener, as you stated in you answer that is more correct! 很多重复,所以我会尝试使用array和addEventListener将它变成更少的代码,正如你在答案中所说的那样更正确!

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

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