简体   繁体   English

如何在 JavaScript 中使用切换 function?

[英]How to use toggle function in JavaScript?

So I am running into a couple of problems when I try to use JavaScript to toggle between classes on click.因此,当我尝试使用 JavaScript 在单击时在类之间切换时遇到了一些问题。

What is going on.. Also when I run it on my localhost it runs but only on the first link.发生了什么事.. 当我在本地主机上运行它时,它只在第一个链接上运行。 not on the second.不是第二个。 I tried recreating the same problem but here it becomes even more a mess..我尝试重新创建相同的问题,但在这里它变得更加混乱..

Now for some reason if I use this code even in the snippet, when you click the event happends, then dissapears completely.现在由于某种原因,如果我甚至在片段中使用此代码,当您单击事件发生时,就会完全消失。

 var pill = document.querySelector(".navpill"); var sub = document.querySelector(".submenu"); pill.onclick = () => { sub.classList.toggle("collapse"); }
 .mainmenu { background-color: #1f1f1f; }.navpill { padding: 15px; }.navpill a { text-decoration: none; color: white; }.submenu { display: none; }.submenu.collapse { display: block; }
 <div> <ul class="mainmenu"> <li class="navpill"><a href="">Link collapse 1</a> <ul class="submenu"> <li class="navpill"><a href="">sub Link 1</a></li> <li class="navpill"><a href="">sub Link 1</a></li> <li class="navpill"><a href="">sub Link 1</a></li> <li class="navpill"><a href="">sub Link 1</a></li> </ul> </li> <li class="navpill"><a href="">Link collapse 2</a> <ul class="submenu"> <li class="navpill"><a href="">sub Link 1</a></li> <li class="navpill"><a href="">sub Link 1</a></li> <li class="navpill"><a href="">sub Link 1</a></li> <li class="navpill"><a href="">sub Link 1</a></li> </ul> </li> <li class="navpill"><a href="">no link</a></li> <li class="navpill"><a href="">no link</a></li> </ul> </div>

href="" makes it try to navigate to another page. href=""使它尝试导航到另一个页面。 Either try href="#" or just don't user hyperlinks if they're not actually intended to be real links.尝试使用href="#"或者如果它们实际上不是真正的链接,则不要使用超链接。 <li class="navpill">sub Link 1</li> ought to be just fine for you I'd expect. <li class="navpill">sub Link 1</li>对你来说应该没问题。

Also, querySelector only selects the first element in the selected set.此外, querySelector仅选择所选集中的第一个元素。 So it only acts on your first link.所以它只作用于你的第一个链接。 You need to use querySelectorAll , loop through the results and add a click to each.您需要使用querySelectorAll ,遍历结果并为每个结果添加点击。

Identifying the specific sublink to act on needs to be done within the click callback, so you can find the one within the menu item which has just been clicked.识别要操作的特定子链接需要在点击回调中完成,因此您可以在菜单项中找到刚刚被点击的那个。 Also you can't use navpill as the class selector for handling the expand/collapse clicks, as it'll crash if you click on one of the sublinks with that class.此外,您不能将navpill用作 class 选择器来处理展开/折叠点击,因为如果您点击带有该 class 的子链接之一,它会崩溃。 So I added a new class for the outer, clickable items.所以我为外部的可点击项目添加了一个新的 class。

Demo:演示:

 var pills = document.querySelectorAll(".expand"); pills.forEach(function(pill) { pill.onclick = () => { var sub = pill.querySelector(".submenu"); sub.classList.toggle("collapse"); } });
 .mainmenu { background-color: #1f1f1f; }.navpill { padding: 15px; color: white; }.submenu { display: none; }.submenu.collapse { display: block; }
 <div> <ul class="mainmenu"> <li class="navpill expand">Link collapse 1 <ul class="submenu"> <li class="navpill">sub Link 1</li> <li class="navpill">sub Link 1</li> <li class="navpill">sub Link 1</li> <li class="navpill">sub Link 1</li> </ul> </li> <li class="navpill expand">Link collapse 2 <ul class="submenu"> <li class="navpill">sub Link 1</li> <li class="navpill">sub Link 1</li> <li class="navpill">sub Link 1</li> <li class="navpill">sub Link 1</li> </ul> </li> <li class="navpill">no link</li> <li class="navpill">no link</li> </ul> </div>

By using the same class for all of your nav, both main and sub you will need to change how you are calling your nav.通过对所有导航使用相同的 class,无论是主导航还是子导航,您都需要更改调用导航的方式。

using QuerySelectorALL and > you can get just the main nav.使用 QuerySelectorALL 和>你可以获得主导航。 Then using nextElementSibling you can get the next navigation.然后使用nextElementSibling你可以获得下一个导航。

I'm also looking for an already open menu and hiding it.我也在寻找一个已经打开的菜单并将其隐藏。

 var pills = document.querySelectorAll(".mainmenu >.navpill"); pills.forEach((pill) => { pill.onclick = (e) => { sub = e.target.nextElementSibling; open = document.querySelector(".submenu.collapse") if(open) open.classList.remove("collapse"); if(sub) sub.classList.toggle("collapse"); e.preventDefault(); } });
 .mainmenu { background-color: #1f1f1f; }.navpill { padding: 15px; }.navpill a { text-decoration: none; color: white; }.submenu { display: none; }.submenu.collapse { display: block; }
 <div> <ul class="mainmenu"> <li class="navpill"><a href="">Link collapse 1</a> <ul class="submenu"> <li class="navpill"><a href="">sub Link 1</a></li> <li class="navpill"><a href="">sub Link 1</a></li> <li class="navpill"><a href="">sub Link 1</a></li> <li class="navpill"><a href="">sub Link 1</a></li> </ul> </li> <li class="navpill"><a href="">Link collapse 2</a> <ul class="submenu"> <li class="navpill"><a href="">sub Link 1</a></li> <li class="navpill"><a href="">sub Link 1</a></li> <li class="navpill"><a href="">sub Link 1</a></li> <li class="navpill"><a href="">sub Link 1</a></li> </ul> </li> <li class="navpill"><a href="">no link</a></li> <li class="navpill"><a href="">no link</a></li> </ul> </div>

querySelector selects just one element. querySelector只选择一个元素。 Use querySelectorAll .使用querySelectorAll

Then to limit the submenu items affected to just the ones under their parent menu item, query from that element as opposed to from the document .然后将受影响的子菜单项限制为仅在其父菜单项下的子菜单项,从该element查询而不是从document查询。 You'll also want to limit querySelectorAll to just choose elements with the navpill class which are direct children of the mainmenu class (done using the > symbol between selectors).您还需要将querySelectorAll限制为仅使用navpill class 选择元素,这些元素是主菜单 class的直接子mainmenu (使用选择器之间的>符号完成)。

let pill = document.querySelectorAll(".mainmenu > .navpill");

pill.forEach ((element) => {
  let sub = element.querySelector(".submenu");
  let mainItem = element.firstChild;
  /* if you want your menu to collapse when clicking a submenu item
   * remove the line above, and on the line below, replace "mainItem"
   * with "element". */
  mainItem.onclick = (e) => {
    if (sub){
      sub.classList.toggle("collapse");
    }
  }
});

Note: Because your submenu items are encompassed in / children of your main menu items (per the selectors originally chosen), clicking on a submenu item will also set off the click event handler for the main menu item above it (the <li> ).注意:因为您的子菜单项包含在主菜单项的 / 子项中(根据最初选择的选择器),所以单击子菜单项还将触发其上方主菜单项的单击事件处理程序( <li> ) . If each submenu item has a link, you'll likely not care - but clicking on a submenu item will also collapse the submenu.如果每个子菜单项都有一个链接,您可能不会在意 - 但单击子菜单项也会折叠子菜单。 The comment in the code above explains how to obtain either behavior, defaulting with the option of leaving the submenu open unless explicitly closed by again clicking on the main menu item.上面代码中的注释解释了如何获得这两种行为,默认情况下,子菜单保持打开状态,除非再次单击主菜单项显式关闭。

As far as the difference between href="#" vs href="" , as others suggested, you can use <a> for your main menu items which are themselves links, and use something else, for example, <span> to hold your main menu items meant to open a submenu.至于href="#"href=""之间的区别,正如其他人所建议的那样,您可以将<a>用于本身就是链接的主菜单项,并使用其他内容,例如<span>来保存您的主菜单项旨在打开子菜单。 That way, you don't send users to the top of your page any time they click a main menu item (using href="#" ).这样,您就不会在用户单击主菜单项(使用href="#" )时将他们带到页面顶部。 You can then change your css for main item entries to the following, so that you get the same cursor behavior for both <a> and <span> :然后,您可以将主要项目条目的 css 更改为以下内容,以便为<a><span>获得相同的 cursor 行为:

.navpill span, .navpill a {
  text-decoration: none;
  color: white;
  cursor: pointer;
}

That's a quite understandable way to handle it.这是一种非常容易理解的处理方式。 In the case, for example, another developer has to one day edit the site, they'd quickly understand your intentions and not get tripped up in e.preventDefault or other relatively obscure code.例如,在这种情况下,另一位开发人员必须有一天编辑该站点,他们会很快理解您的意图,而不会被e.preventDefault或其他相对晦涩的代码绊倒。

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

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