简体   繁体   English

在一个 div 中定位多个类并计算它们被点击的次数 Vanilla JS

[英]Target multiple classes in a div and count number of times they have been clicked Vanilla JS

The purpose of this is to be able to track the number of times a button with class testButton or incButton has been clicked and if either has been clicked twice to show a overlay.这样做的目的是能够跟踪带有 class testButton 或 incButton 的按钮被单击的次数,以及是否已单击两次以显示覆盖。

There are 2 main issues: 1: I'm not sure how to select 2 different classes of buttons 2: Once there are more than 1 button with the same class name the existing JS code does only works on the first button with the testButton class.有 2 个主要问题: 1:我不知道如何 select 2 个不同类别的按钮 2:一旦有多个按钮具有相同的 class 名称,现有的 JS 代码仅适用于带有 testButton6142F2ED4F8EB402 的第一个按钮.

The code I have is:我的代码是:

<style>
    #winOverlay {
        position: fixed;
        z-index: 200;
        width: 100%;
        height: 100%;
        background-color: red;
        top: 0;
        left: 0;
    }
</style>

<div id="winOverlay" style="display:none"></div>

<div id="buttonContainer">
    <button class="testButton">1</button>
    <button class="incButton">2</button>
    <button class="testButton">3</button>
    <button class="incButton">4</button>
    <button class="testButton">5</button>
</div>


<script>
    var count = 0;
    var btn = document.getElementById("buttonContainer").querySelector(".testButton");

    btn.onclick = function () {
        count++;
        if (count == 2) {
            document.getElementById('winOverlay').style.display = "block";
        }
    }
</script>

Any help would be greatly appreciated.任何帮助将不胜感激。

You need to select all buttons with querySelectorAll add listener to all of them.您需要 select 所有带有 querySelectorAll 的按钮添加侦听器。

 var count = 0; const buttons = document.querySelectorAll("#buttonContainer > button"); for (let index = 0; index < buttons.length; index++) { const e = buttons[index]; e.onclick = function() { count++; if (count == 2) { document.getElementById('winOverlay').style.display = "block"; } } }
 #winOverlay { position: fixed; z-index: 200; width: 100%; height: 100%; background-color: red; top: 0; left: 0; }
 <div id="winOverlay" style="display:none"></div> <div id="buttonContainer"> <button class="testButton">1</button> <button class="incButon">2</button> <button class="testButton">3</button> <button class="incButon">4</button> <button class="testButton">5</button> </div>

To select 2 class you should do as in css:对于 select 2 class 你应该像 css 那样做:

querySelector(class1 class2)

But don't work because you can't use querySelector for two or more classes.但是不要工作,因为您不能将 querySelector 用于两个或更多类。 This code say only select class1 or class2 and take the first Element.这段代码只说 select class1 或 class2 并取第一个元素。

Use querySelectorAll() to have all of them使用querySelectorAll()拥有所有这些

You can make use of event Delegation where you add event listener on the common parent container with class buttonContainer and you can check if the button clicked with id only testButton and incButon您可以使用event Delegation ,在公共父容器上添加事件侦听器,使用 class buttonContainer并且您可以检查按钮是否单击了只有 id 的testButtonincButon

1) This code will work if you have to calculate of count of irrespective of which button is clicked. 1) This code will work if you have to calculate of count of irrespective of which button is clicked.

 var count = 0; var btn = document.getElementById("buttonContainer"); const winOverlay = document.getElementById('winOverlay'); btn.addEventListener("click", e => { const classes = e.target.classList; if (classes.contains("testButton") || classes.contains("incButon")) { count++; if (count === 2) winOverlay.style.display = "block"; } })
 #winOverlay { position: fixed; z-index: 200; width: 100%; height: 100%; background-color: red; top: 0; left: 0; }
 <div id="winOverlay" style="display:none"></div> <div id="buttonContainer"> <button class="testButton">1</button> <button class="incButon">2</button> <button class="testButton">3</button> <button class="incButon">4</button> <button class="testButton">5</button> </div>

2) This code will work if you have to calculate the count of specif key on which you clicked and show overlay if it's count is 2 2) This code will work if you have to calculate the count of specif key on which you clicked and show overlay if it's count is 2

 var btn = document.getElementById("buttonContainer"); const winOverlay = document.getElementById("winOverlay"); const dict = {}; btn.addEventListener("click", (e) => { const classes = e.target.classList; const addOverlay = () => (winOverlay.style.display = "block"); if (classes.contains("testButton") || classes.contains("incButon")) { const key = e.target.dataset.key; dict[key] = (dict[key] || 0) + 1; if (dict[key] === 2) addOverlay(); } });
 #winOverlay { position: fixed; z-index: 200; width: 100%; height: 100%; background-color: red; top: 0; left: 0; } button { color: white; border: none; padding: 1rem; cursor: pointer; } button.testButton { background-color: teal; } button.incButon { background-color: orange; }
 <div id="winOverlay" style="display: none;"></div> <div id="buttonContainer"> <button class="testButton" data-key="testButton">1</button> <button class="incButon" data-key="incButon">2</button> <button class="testButton" data-key="testButton">3</button> <button class="incButon" data-key="incButon">4</button> <button class="testButton" data-key="testButton">5</button> </div>

As the others have suggested querySelectorAll provides support for multiple selectors.正如其他人所建议的那样, querySelectorAll提供了对多个选择器的支持。 It will return an array-like nodelist which you can then iterate over.它将返回一个类似数组的节点列表,然后您可以对其进行迭代。

document.querySelectorAll('testButton', 'incButton');

I'm going to offer an alternative approach using event delegation which allows you to attach one listener to a parent element that captures events as they bubble up the DOM.我将提供一种使用事件委托的替代方法,它允许您将一个侦听器附加到父元素,当事件在 DOM 中冒泡时捕获事件。

This example also uses a closure (basically a function that's returned from another function but that can carry any variables set outside it in the local lexical environment with it when it's returned. This is a useful pattern if you want to avoid global variables. In this case we create an object to hold the totals of the two types of buttons.这个例子还使用了一个闭包(基本上是一个 function,它是从另一个 function 返回的,但是当它返回时,它可以携带在它之外设置在本地词法环境中的任何变量。如果你想避免全局变量,这是一个有用的模式。在这个在这种情况下,我们创建一个 object 来保存两种类型按钮的总数。

 // Cache your container and overlay elements const container = document.querySelector('.buttonContainer'); const overlay = document.querySelector('.overlay'); // Add one listener to the container which calls `handleClick`. // `handleClick` sets up the object and returns a new function // (the closure) that carries the object with it. container.addEventListener('click', handleClick(), false); function handleClick() { // An object that holds the button totals const cases = { testButton: 0, incButton: 0 }; // The function that will be added to the listener // It has the event argument return function (e) { // Destructure the nodeName/className from the // element that was clicked const { nodeName, className } = e.target; // Check to see if the element was a button if (nodeName === 'BUTTON') { // Increase the value in the object where // the key matches the className ++cases[className]; console.log(JSON.stringify(cases)); // If that value is 2 show the overlay if (cases[className] === 2) { overlay.classList.add('show'); } } } }
 .overlay { display: none; margin: 1em; background-color: #acaccc; black: white; padding: 2em; }.show { display: block; } button { padding: 0.7em; } button:hover { cursor: pointer; background-color: #acacac; }
 <div class="buttonContainer"> <button class="testButton">1</button> <button class="incButton">2</button> <button class="testButton">3</button> <button class="incButton">4</button> <button class="testButton">5</button> </div> <div class="overlay">Overlay</div>

Additional documentation附加文件

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

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