简体   繁体   English

如何通过classname分配javascript函数

[英]How to assign a javascript function by classname

I have multiple buttons (generated by php) for a shopping cart application: 我有一个购物车应用程序的多个按钮(由PHP生成):

<button class="addtocart" id="<?php echo $code; ?>"> 
    <span id="addtocartbutton">Add to cart</span>
</button>

I want to update my cart using a function: 我想使用功能更新我的购物车:

function AddtoCart() {
    alert("Added!");
}

Later, I want to find the id ($code) created by the button which called it (not sure how to do that also, but maybe that's another question). 后来,我想找到由调用它的按钮创建的id($ code)(不知道该怎么做,但也许这是另一个问题)。 And so I tried this: 所以我尝试了这个:

document.getElementsByClassName("addtocart").addEventListener("click", AddtoCart());

But it doesn't work. 但它不起作用。 It was working using an onclick, but I understand that the right way to do it by creating an EventListener. 它使用onclick工作,但我理解通过创建EventListener来实现它的正确方法。 Also, I cannot use the on() function in jQuery, because I am forced to use jQuery Version 1.6 which does not have it. 另外,我不能在jQuery中使用on()函数,因为我被迫使用没有它的jQuery Version 1.6。

I have looked at https://stackoverflow.com/a/25387857/989468 and I can't really assign it to the parent which is ap tag, because I obviously don't want the other elements in the p tag to be assigned this function. 我查看了https://stackoverflow.com/a/25387857/989468 ,我无法将其分配给ap标签的父级,因为我显然不希望分配p标签中的其他元素这个功能。

While the answers given are correct, there is another way: Event Delegation 虽然给出的答案是正确的,但还有另一种方式: 事件委派

Attach the listener to a SINGLE thing, in this case the document body and then check to see what element was actually clicked on: 将侦听器附加到SINGLE事物,在这种情况下是文档body ,然后检查以查看实际单击的元素:

Warning: Typed on the fly: Untested 警告:即时输入:未经测试

// Only needed *once* and items may be added or removed on the fly without
// having to add/remove event listeners.
document.body.addEventListener("click", addtoCart);

function addtoCart(event) {
    var target = event.target;

    while(target) {
      if (target.classList.contains('addtocart')) {
        break;
      }
      // Note: May want parentElement here instead.
      target = target.parentNode;
    }

    if (!target) {
       return;
    }

    var id = target.dataset.id;
    alert(id + " added!");
}

You should attach click event to every element with class addtocart , since getElementsByClassName() return an array of all objects with given class name so you could use for to loop through everyone of them and associate it with function you want to trigger on click (in my example this function called my_function ), check example bellow : 您应该将click事件附加到具有类addtocart每个元素,因为getElementsByClassName()返回具有给定类名的所有对象的数组,因此您可以使用for循环遍历其中的每个元素并将其与您想要在单击时触发的函数相关联(在我的例子这个函数名为my_function ),检查示例如下:

var class_names= document.getElementsByClassName("addtocart");

for (var i = 0; i < class_names.length; i++) {
    class_names[i].addEventListener('click', my_function, false);
}

Hope this helps. 希望这可以帮助。


 function my_function() { alert(this.id); }; var class_names= document.getElementsByClassName("addtocart"); for (var i = 0; i < class_names.length; i++) { class_names[i].addEventListener('click', my_function, false); } 
 <button class="addtocart" id="id_1">button 1</button> <button class="addtocart" id="id_2">button 2</button> <button class="addtocart" id="id_3">button 3</button> <button class="addtocart" id="id_3">button 4</button> 

I'll show some of the errors you had in your code, then I'll show you how can you improve it so that you can achieve what you want, and I also show that it works with buttons dynamically added later: 我将展示你在代码中遇到的一些错误,然后我会向你展示如何改进它以便你可以实现你想要的东西,并且我还展示它适用于以后动态添加的按钮:

First and foremost, you need to pass the function reference (it's name) to the addEventListener ! 首先,您需要将函数引用(它的名称)传递给addEventListener You have called the function, and passed whatever it returned. 你已经调用了函数,并传递了它返回的任何内容。 Instead of: 代替:

document.getElementsByClassName("addtocart").addEventListener("click", AddtoCart());

It should've been: 应该是:

document.getElementsByClassName("addtocart").addEventListener("click", AddtoCart);

Second: document.getElementsByClassName("addtocart") returns a NodeList, you can't operate on it, you need to operate on it's elements: document.getElementsByClassName("addtocart")[0], [1],... . 第二: document.getElementsByClassName("addtocart")返回一个NodeList,你无法操作它,你需要操作它的元素: document.getElementsByClassName("addtocart")[0], [1],...

Third, I would suggest you to use the data-... html attribute: 第三,我建议你使用data-... html属性:

<button class="addtocart" id="addtocart" data-foo="<? echo $code; ?>">

This way you can pass even more data. 这样您就可以传递更多数据。 Now you can get the $code as: 现在你可以得到$code

document.getElementById('addtocart').dataset.foo

 // el: the button element function AddtoCart(el) { // this is the id: var id = el.id; // and this is an example data attribute. You can have as many as you wish: var foo = el.dataset.foo; alert(id + " (" + foo + ") added!"); } // Try add a div or something around the area where all the buttons // will be placed. Even those that will be added dynamically. // This optimizes it a lib, as every click inside that div will trigger // onButtonClick() document.getElementById("buttons").addEventListener("click", onButtonClick); // this shows that even works when you dynamically add a button later document.getElementById('add').onclick = addButton; function addButton() { var s = document.createElement("span"); s.text = "Add to cart"; var b = document.createElement("button"); b.innerHTML = 'Third <span class="addtocartbutton">Add to cart</span>'; b.className = "addtocart"; b.id="third"; b.dataset.foo="trio"; // note the new button has the same html structure, class // and it's added under #buttons div! document.getElementById("buttons").appendChild(b); } // this will gett triggered on every click on #buttons function onButtonClick(event) { var el = event.target; if (el && el.parentNode && el.parentNode.classList.contains('addtocart')) { // call your original handler and pass the button that has the // id and the other datasets AddtoCart(el.parentNode); } } 
 <div id="buttons"> <button class="addtocart" id="first" data-foo="uno">First <span class="addtocartbutton">Add to cart</span></button> <button class="addtocart" id="second" data-foo="duo">Second <span class="addtocartbutton">Add to cart</span></button> </div> <button id="add">Add new button</button> 

<html>
<head>
<script>
window.onload=function{
    var btn = document.getElementsByName("addtocartbtn")[0];
    btn.addEventListener("click", AddtoCart());
}

function AddtoCart() {
    alert("Added!");
}
</script>
</head>
<body >
<button class="addtocart" name ="addtocartbtn" id="<?php echo $code; ?>" > <span id="addtocartbutton">Add to cart</span></button>

</body>
</html>

Actually class in Javascript is for multiple selection you should provide index like an array. 实际上Javascript中的类是用于多选的,你应该像数组一样提供索引。

 <button class="addtocart"> <span id="addtocartbutton">Add to cart</span></button>
        <script type="text/javascript">
        document.getElementsByClassName("addtocart")[0].addEventListener("click", AddtoCart);        
        function AddtoCart() {
            alert("Added!");
        }
        </script>

Also your second parameter was wrong don't use parentheses. 另外你的第二个参数是错误的,不要使用括号。

Applying parentheses means it will call the function automatically when loaded, and will not call the function after that. 应用括号表示它会在加载时自动调用该函数,之后不会调用该函数。

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

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