2012-04-02 21 views
18

Nếu tôi gán một trình xử lý cho sự kiện OnClick của một phần tử hai lần, thì trình xử lý sẽ được thực thi hai lần. Nhưng tôi muốn thay đổi điều này vì vậy ngay cả khi tôi gán nó hai lần, thì trình xử lý sẽ chỉ thực hiện một lần.Chỉ thêm một trình xử lý OnClick với jQuery một lần - ngay cả khi được gọi lại

dụ vô nghĩa để chứng minh vấn đề:

$('.button').click(
    function(){ 
     alert('here'); 
}); 
$('.button').click(
    function(){ 
     alert('here'); 
}); 

Vì vậy, tôi đã thêm xử lý hai lần. Bây giờ khi tôi nhấp vào một phần tử với lớp đó, tôi sẽ nhận được hai hộp cảnh báo.

Câu hỏi đặt ra là, làm cách nào để hạn chế nó để tôi chỉ nhận được một hộp cảnh báo?

+1

Tại sao bạn cần phải thêm sự kiện hai lần? – root

+1

Có một chức năng được thực hiện trên trang này mỗi khi có một postback, để thêm trình xử lý vào các phần tử được tạo động. Tuy nhiên, bất kỳ phần tử nào đã tồn tại trước đây đều có trình xử lý hai lần ... – msigman

+2

Tôi nghĩ bạn cần suy nghĩ lại cách tiếp cận để tránh bị ràng buộc hai lần, nhưng nếu bạn đang ở trong một cuộc khủng hoảng, tôi cho rằng bạn có thể sử dụng '$ ('. Button') .off ('click'). on ('click', function() {...}); 'như ở đây: http://jsfiddle.net/SsRxv/ – hyperslug

Trả lời

24

Thực tế là những gì bạn đang làm sau (xóa trình xử lý sự kiện sau khi nó được kích hoạt một lần) thì tôi tin đó là câu trả lời đúng. Nếu không, bạn có thể hủy liên kết sự kiện trước khi ràng buộc sự kiện:

var myEventHandler = function() {alert('hello')}; 
$('a').unbind('click', myEventHandler); 
$('a').bind('click', myEventHandler); 

Nên hoạt động.

Chỉnh sửa: vì câu trả lời này tiếp tục nhận được phiếu bầu, tôi sẽ thêm một giải pháp khác (tốt hơn trong hầu hết các trường hợp) sẽ hoạt động ít nhất trong trường hợp của OP. Khi xử lý nội dung được thêm động, chỉ cần sử dụng jQuery on() trên phần tử cha thay vì áp dụng trình xử lý sự kiện trực tiếp trên phần tử.

http://api.jquery.com/on/

4

Sử dụng một thẻ. http://api.jquery.com/one/

$(".button").one('click', function(){ 
    alert('....') 
}); 
+8

Lưu ý điều này sẽ gây ra' alert() 'cho chỉ hiển thị một lần nhấp và bỏ qua các nhấp chuột tiếp theo. Vấn đề của OP là 'alert()' hiển thị nhiều lần cho mỗi nhấp chuột. – leepowers

+0

powerbuoy có câu trả lời sau đó. –

-1

Tôi nghĩ không có điểm để thêm hàm hai lần. Tuy nhiên, nếu bạn có thì bạn có thể thêm return false vào một trong các chức năng.

$('.button').click(
    function(){ 
     return false; 
     alert('here'); 
}); 
$('.button').click(
    function(){ 
     alert('here'); 
});​ 
5

Để các sự kiện chỉ được kích hoạt một lần, hãy liên kết chúng một lần. Khi động thêm các yếu tố, ràng buộc xử lý sự kiện cho các yếu tố phụ huynh sử dụng on():

Xem jsfiddle này:

<div id="container"> 
<p>Paragraph #1</p> 
</div> 

<div> 
<button id="add">Add Elements</button> 
</div> 

<script type="text/javascript"> 
var n = 1; 
$('#add').click(function() { 
    $('#container').append('<p>Paragraph #' + ++n + '</p>'); 
}); 
$('#container').on('click', 'P', function() { 
    alert($(this).text()); 
}); 
</script> 

Lưu ý cách thức xử lý sự kiện được đăng ký với on() chỉ một lần. Mã tự động thêm phần tử không đăng ký trình xử lý sự kiện.

5

một mẹo nhỏ có thể giúp:

jQuery(".button:not(.clickadded)").click(function(){ 

    alert('here'); 

).addClass("clickadded"); 
0

Dưới đây là một phương pháp Tôi đang sử dụng, tương tự như phương pháp Miquel trong một số cách khác nhau.

$.prototype.once = function() { 
    var ret = this.not(function() { 
     return this.once; 
    }); 
    this.each(function(id, el) { 
     el.once = true; 
    }); 
    return ret; 
}; 

Sử dụng nó như thế này,

$('#footer') 
    .once() 
    .click(function(){ 
     console.log('click the footer'); 
    }); 

Khi còn hỗ trợ một tham số để bạn có thể có các loại khác nhau

1

Bạn cũng có thể loại bỏ bất kỳ sự kiện nhấp chuột hiện trong hàm có chức năng tắt (' nhấp vào '):

$('.button').off('click').click(function() { 
    ... 
}); 
1

Tôi đã giải quyết nó bằng cờ, tôi biết nó không phải là tốt nhất chỉ bằng ý tưởng

if (!alreadyBound) { 
    $('.button').bind('click', submitEvtHandler); 
    alreadyBound = true; 
} 
Các vấn đề liên quan