简体   繁体   English

Vanilla Javascript:如果单击具有相同切换类的Y元素,则从X元素中删除切换类

[英]Vanilla Javascript: Remove toggle class from X element if I click on Y element with the same toggle class

I'm currently working on a sidebar menu where I toggle the "selected" class on a category, which has the classname "sidebar-category". 我目前正在使用侧边栏菜单,在其中切换类别为“ sidebar-category”的类别中的“ selected”类。

With jQuery I can easily achieve my desired goal: after toggling the "selected" class (if I click on another category) the previous category gets the class removed and is then applied to the currently clicked category: 使用jQuery,我可以轻松实现自己的目标:切换“选定的”类(如果我单击另一个类别),则前一个类别将删除该类,然后将其应用于当前单击的类别:

$('.sidebar-category').click(function() {
  $(".sidebar-category").not(this).removeClass("selected");
  $(this).toggleClass('selected');
});

My problem is that for this project I cannot use jQuery and must use vanilla Javascript. 我的问题是,对于该项目,我无法使用jQuery,而必须使用原始Javascript。

So far I can achieve the toggling easily, but I'm not sure how I can remove the class when clicking on another category using vanilla Javascript. 到目前为止,我可以轻松实现切换,但是我不确定在使用香草Javascript单击另一个类别时如何删除该类。 This is my current code: 这是我当前的代码:

var selectCategory = document.getElementsByClassName('sidebar-category');

for (var i = 0, l = selectCategory.length; i < l; i++) {
  selectCategory[i].onclick = function() {
  this.classList.toggle('selected');
  }
}

The jQuery code that removes the selected class is equivalent to a loop. 删除selected类的jQuery代码等效于循环。 So just write that loop in your event listener. 因此,只需在您的事件监听器中编写该循环即可。

var selectCategory = document.getElementsByClassName('sidebar-category');

for (var i = 0, l = selectCategory.length; i < l; i++) {
  selectCategory[i].onclick = function() {
    for (var j = 0; j < l; j++) {
      if (selectCategory[j] != this) {
        selectCategory[j].classList.remove("selected");
      }
    }
    this.classList.toggle('selected');
  }
}

Assuming your target environment supports ES2015 (or you transpile your code to support such an environment), a declarative approach using Array.from , filter and forEach can be achieved with the following code: 假设您的目标环境支持ES2015(或您将代码转换为支持这种环境),则可以通过以下代码实现使用Array.fromfilterforEach的声明性方法:

 function toggleSelectedClass(event) { Array.from(document.getElementsByClassName('sidebar-category')) .filter(element => element !== event.target) .forEach(element => { element.classList.remove('selected') element.setAttribute('aria-pressed', false); }); event.target.classList.toggle('selected'); const pressed = event.target.getAttribute('aria-pressed') === 'true'; event.target.setAttribute('aria-pressed', String(!pressed)); } 
 .sidebar-category { padding: 5px; } .selected { background: blue; color: white; } 
 <div onclick="toggleSelectedClass(event)"> <button type="button" class="sidebar-category selected" aria-pressed="true">Click</button> <button type="button" class="sidebar-category" aria-pressed="false">Click</button> <button type="button" class="sidebar-category" aria-pressed="false">Click</button> <button type="button" class="sidebar-category" aria-pressed="false">Click</button> </div> 

Note: getElementsByClassName returns an HTMLCollection , not an array, so Array.from is required to use the array methods filter and forEach . 注意: getElementsByClassName返回一个HTMLCollection 而不是一个数组,因此使用数组方法filterforEach需要Array.from

Note 2: Keep accessibility in mind when designing such a menu. 注意2:在设计此类菜单时,请牢记可访问性。 A good reference for this is https://inclusive-components.design/toggle-button/ . https://inclusive-components.design/toggle-button/是一个很好的参考。

This can be achieved with the Events API in JavaScript. 这可以通过JavaScript中的Events API来实现。

Using the onClick="" property of an HTML element we can construct a toggling system. 使用HTML元素的onClick=""属性,我们可以构建一个切换系统。

  1. Create a function to handle the click action of the user and pass in the element that has been clicked as the parameter. 创建一个函数来处理用户的单击动作,并将已单击的元素作为参数传入。 function toggle(element){...}
  2. Inside that element first fire off an event to clear the selected element(s) using the event named clearselected that will iterate through the elements and set the selected property to false. 首先在该元素内部触发一个事件,以使用名为clearselected的事件清除选定的元素,该事件将遍历元素并将selected属性设置为false。 Thus, semantically deselecting the elements. 因此,在语义上取消选择元素。
  3. Change the selected property of the element passed in the onclick handler to true. 将在onclick处理程序中传递的元素的selected属性更改为true。
  4. Update the user interface (UI) using an event called updateui that changed the selected element to its desired appearance, and all non-selected elements to their desired appearance using a for loop that iterates through all elements and looks at the selected property. 使用名为updateui的事件更新用户界面(UI),该事件将选定的元素更改为其所需的外观,并使用for循环遍历所有元素并查看selected属性,将所有未选择的元素更改为其所需的外观。

Down below I have a code snippet that uses vanilla JavaScript to create a toggle system on the UI. 在下面,我有一个使用香草JavaScript在UI上创建切换系统的代码段。 It has a very basic HTML that uses the same class names and adds very little CSS to make the demo easier to understand. 它有一个非常基本的HTML,它使用相同的类名,并添加了很少的CSS,以使演示更易于理解。 I hope this is the thing you were looking for! 我希望这是您想要的东西!

 // Set up the HTML elements in JavaScript var sidebar = document.getElementsByClassName("sidebar")[0]; var sidebarCategories = document.getElementsByClassName("sidebar-category"); // Add an event listener for clearing the selected elements sidebar.addEventListener("clearselected", function(e) { for(var i = 0; i < sidebarCategories.length; i++){ sidebarCategories[i].selected = false; } }, false); // Add an event listener updating the UI to reflect changes sidebar.addEventListener("updateui", function(e) { for(var i = 0; i < sidebarCategories.length; i++){ var current = sidebarCategories[i]; if(current.selected){ current.textContent = "selected"; }else{ current.textContent = ""; } } }, false); // Write a on click handler to handle the toggle function toggle(element){ var event = document.createEvent("Event"); event.initEvent("clearselected", true, true); element.dispatchEvent(event); element.selected = true; var event = document.createEvent("Event"); event.initEvent("updateui", true, true); element.dispatchEvent(event); } 
 .sidebar-category { width: 100px; height: 100px; border: 3px solid black; margin-bottom: 10px; line-height: 100px; text-align: center; } 
 <div class="sidebar"> <p>Click the boxes to see the toggle in action</p> <div class="sidebar-category" onclick="toggle(this)"></div> <div class="sidebar-category" onclick="toggle(this)"></div> <div class="sidebar-category" onclick="toggle(this)"></div> </div> 

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

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