2016-01-31 15 views
6

Tôi có nhiều nút (tạo ra bởi php) cho một ứng dụng giỏ hàng:Làm thế nào để gán một hàm javascript bởi classname

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

Tôi muốn cập nhật giỏ hàng của tôi sử dụng một chức năng:

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

Sau đó, tôi muốn tìm id ($ code) được tạo ra bởi nút gọi là nó (không chắc chắn làm thế nào để làm điều đó cũng có, nhưng có lẽ đó là một câu hỏi khác). Và vì vậy tôi đã thử điều này:

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

Nhưng nó không hoạt động. Nó đã được làm việc bằng cách sử dụng onclick, nhưng tôi hiểu rằng cách đúng để làm điều đó bằng cách tạo ra một EventListener. Ngoài ra, tôi không thể sử dụng hàm on() trong jQuery, vì tôi buộc phải sử dụng jQuery Phiên bản 1.6 không có nó.

Tôi đã xem https://stackoverflow.com/a/25387857/989468 và tôi thực sự không thể gán cho cha mẹ là thẻ p, vì tôi rõ ràng không muốn các phần tử khác trong thẻ p được chỉ định chức năng này.

+0

chúng ta có thể thêm id trong nút –

+0

Ý tôi là tên thuộc tính –

+1

IIRC, j Truy vấn 1.6 có '.live', về cơ bản giống với' .on'. – georg

Trả lời

3

Trong khi các câu trả lời đưa ra là đúng, có một cách khác: Event Delegation

Đính kèm người nghe đến một điều duy nhất, trong trường hợp này tài liệu body và sau đó kiểm tra xem những yếu tố được sự nhấp vào:

Cảnh báo: Typed on the fly: chưa được kiểm tra

// 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!"); 
} 
+0

Điều này có vẻ rất hứa hẹn. Nếu tôi chỉ có thể hiểu nó! :-) Ví dụ, tại sao bạn cần thời gian? Và tại sao sẽ không có một mục tiêu cho sự kiện (ref: if (! Target)). Tại sao không sử dụng "này"? – Chiwda

+0

Đọc liên kết tôi đã bao gồm trong bài đăng, nhưng câu trả lời ngắn: Bởi vì 'this' sẽ không trỏ đến phần tử mà bạn đang mong đợi. IIRC, nó trỏ đến phần tử mà bạn thực sự nhấp vào, có thể là * bên trong * phần tử bạn đang thực sự kiểm tra. Tôi không thể kiểm tra nó ngay bây giờ, nhưng bạn có thể thêm 'console.log' và xem giá trị của' this' này là gì. Phái đoàn khó khăn hơn một chút để quấn quanh đầu, tôi sẽ thừa nhận, nhưng nếu bạn đang làm bất kỳ loại cập nhật động nào của nội dung, nó sẽ tốt hơn nhiều so với việc thêm/gỡ bỏ các trình xử lý cụ thể. –

+0

nó đưa ra một lỗi, nếu bạn bấm vào bất cứ nơi nào trên trang – Gavriel

1
<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> 
+0

Điều này không chỉ làm mục đầu tiên? – Chiwda

2

Bạn nên đính kèm click sự kiện để mọi phần tử với lớp addtocart, vì getElementsByClassName() trở lại một mảng của tất cả các đối tượng với tên lớp được, do đó bạn có thể sử dụng for để lặp qua tất cả mọi người trong số họ và liên kết nó với chức năng bạn muốn kích hoạt trên nhấp chuột (trong ví dụ của tôi chức năng này được gọi là my_function), kiểm tra ví dụ dưới đây:

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>

+0

Tôi đã thấy câu trả lời tương tự như vậy, nhưng vấn đề là các id được tạo sau khi thực tế, tức là khi trang được tải. Vì vậy, tôi không thể thực sự liên kết một chức năng với mỗi trước. – Chiwda

+0

Có, tôi thấy, tại sao tôi đang sử dụng tên 'lớp' trong câu trả lời của tôi để liên kết sự kiện nhấp chuột, do đó, không quan trọng nếu các id được tạo tự động nếu tên lớp ở đó. –

+0

Tôi thích giải pháp của bạn, nhưng tôi cảm thấy nó chia sẻ một khi lỗi cơ bản với các câu trả lời khác bên dưới. Tôi thực sự nghĩ rằng đó là mã không hiệu quả để có nó lặp qua tất cả các mục trong mảng mỗi khi ai đó nhấp vào một mục để thêm nó vào giỏ hàng. Hãy tưởng tượng một trường hợp có hàng trăm mặt hàng được hiển thị - đó là rất nhiều chi phí cho mỗi nhấp chuột! Tôi thà quay trở lại cách cũ và được cho là xấu chỉ đến một hàm trong html onclick cho nút. Như trong Chiwda

2

tôi sẽ hiển thị một số lỗi bạn đã có trong mã của bạn, sau đó tôi sẽ chỉ cho bạn cách bạn có thể cải thiện nó để bạn có thể đạt được những gì bạn muốn, và tôi cũng cho thấy rằng nó hoạt động với các nút được thêm động sau này:

Trước tiên, bạn cần chuyển tham chiếu hàm (tên của nó) đến addEventListener! Bạn đã gọi hàm này và truyền lại bất cứ cái gì nó trả về. Thay vì:

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

Nó nên đã:

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

Thứ hai: document.getElementsByClassName("addtocart") trả về một NodeList, bạn không thể hoạt động trên nó, bạn cần phải hoạt động trên các yếu tố của nó: document.getElementsByClassName("addtocart")[0], [1],....

Thứ ba, tôi sẽ đề nghị bạn sử dụng thuộc tính data-... html:

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

Bằng cách này bạn có thể truyền dữ liệu nhiều hơn.Bây giờ bạn có thể nhận được $code như:

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>

+0

'document.getElementsByClassName (" addtocart ")' trả về một cấu trúc giống như mảng được gọi là 'NodeList', không phải là mảng. IIRC nó là một * NodeList * sống * mà thậm chí còn xa lạ. –

+0

Cảm ơn, @JeremyJStarcher, đã sửa NodeList – Gavriel

1

lớp Trên thực tế trong Javascript là cho nhiều lựa chọn bạn nên cung cấp chỉ số như một mảng.

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

Thông số thứ hai của bạn sai không sử dụng dấu ngoặc đơn.

Áp dụng dấu ngoặc đơn nghĩa là nó sẽ tự động gọi hàm khi được tải và sẽ không gọi hàm sau đó.

+0

bằng dấu ngoặc đơn không phải là 'sai'. Nó có nghĩa là hàm sẽ được thực hiện nội tuyến. Bạn cần phải biết khi nào nên sử dụng chúng và khi nào không sử dụng chúng. Có những trường hợp sử dụng mà bạn cần lời gọi nội tuyến. :) – AdityaParab

+0

@AdityaParab Vâng, bạn nói đúng, áp dụng dấu ngoặc đơn là không sai nhưng điều này sai vì tôi nghĩ rằng việc thêm sản phẩm vào giỏ hàng sẽ được thực hiện sau khi nhấp vào thêm vào giỏ hàng không tự động. Mặc dù tôi đã cập nhật ans của tôi và đã thêm thông tin thêm về dấu ngoặc đơn. – C2486

Các vấn đề liên quan