简体   繁体   中英

How to assign a javascript function by classname

I have multiple buttons (generated by php) for a shopping cart application:

<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). 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. Also, I cannot use the on() function in jQuery, because I am forced to use jQuery Version 1.6 which does not have it.

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.

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:

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 :

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 ! 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],... .

Third, I would suggest you to use the data-... html attribute:

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

This way you can pass even more data. Now you can get the $code as:

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.

 <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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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