Tôi có mã sau:
function someMethod()
{
$(obj).click(function {});
}
someMethod được gọi hai lần và do đó sự kiện nhấp chuột được liên kết hai lần. Làm thế nào tôi có thể làm cho nó ràng buộc chỉ một lần?
Tôi có mã sau:
function someMethod()
{
$(obj).click(function {});
}
someMethod được gọi hai lần và do đó sự kiện nhấp chuột được liên kết hai lần. Làm thế nào tôi có thể làm cho nó ràng buộc chỉ một lần?
Câu trả lời:
Nếu bạn có thể áp dụng nó, có thể bạn muốn xem qua event.preventDefault và event.stopPropagation HOẶC bỏ liên kết và ràng buộc mỗi lần, trong phương pháp của bạn như
function someMethod()
{
$(obj).off('click').on('click', function(e) {
// put your logic in here
});
}
function someMethod() { $(obj).off('click.namespace').on('click.namespace', function {}); }
Ngoài câu trả lời của pna, bạn có thể muốn suy nghĩ về việc đặt tên cho sự kiện của mình để bạn không vô tình bỏ liên kết tất cả các sự kiện nhấp chuột.
function someMethod () { $ (obj) .unbind ('click.namespace'). bind ('click.namespace', function () {}); }
$(obj).off()
và $(obj).on()
tương ứng. Nếu không, không gian tên đã giúp và điều này đã hoạt động. Cảm ơn bạn!
Không có phương pháp cài sẵn nào để xác định xem bạn đã ràng buộc hàm cụ thể này chưa. Bạn có thể liên kết nhiều hàm bấm vào một đối tượng. Ví dụ:
$('#id').bind('click', function(){
alert('hello');
});
$('#id').bind('click', function(){
alert('goodbuy');
});
nếu bạn làm như trên khi đối tượng được nhấp vào nó sẽ cảnh báo xin chào rồi tạm biệt. Để đảm bảo chỉ một hàm được liên kết với sự kiện nhấp chuột, hãy bỏ liên kết trình xử lý sự kiện nhấp, sau đó ràng buộc chức năng mong muốn như sau:
$(obj).unbind('click').bind('click', function(){... });
Giải pháp rõ ràng là không gọi someMethod()
hai lần. Nếu bạn không thể khắc phục điều đó, thì bạn có thể giữ một biến trạng thái để nó chỉ liên kết một lần như thế này:
function someMethod()
{
if (!someMethod.bound) {
$(obj).click(function() {});
someMethod.bound = true;
}
}
Lưu ý: điều này sử dụng một thuộc tính của chính hàm thay vì giới thiệu một biến toàn cục để theo dõi xem nó có bị ràng buộc hay không. Bạn cũng có thể sử dụng một thuộc tính trên chính đối tượng.
Bạn có thể thấy nó hoạt động tại đây: http://jsfiddle.net/jfriend00/VHkxu/ .
Hoặc sử dụng hàm one () của jQuery tương tự như on () nhưng chỉ kích hoạt sự kiện một lần, ngay cả khi bạn liên kết sự kiện nhiều lần.
jQuery làm cho việc gọi một số hàm có thể chỉ một lần khá dễ dàng:
function someMethod()
{
$(obj).click(function() {});
this.someMethod = $.noop;
}
jQuery.noop
chỉ ngắn hơn một ký tự function(){}
, vì vậy thật ngớ ngẩn khi nói rằng nó đang "giúp đỡ" ở đây, chỉ cung cấp một hàm trống. Đây là một ví dụ không phải phương thức jQuery về giải pháp chung này:var fn = function(){ fn = function(){}; do stuff; };
$
thay thế
Đây là một gợi ý vì tôi không biết logic của bạn. Có thể có hoặc có thể không phù hợp với bạn.
Hãy thử kết hợp hàm jquery live () và một () sẽ cho bạn kết quả tốt hơn so với sự kiện rebinds.
Các trường hợp đặc biệt hoạt động khi bạn có 2 phần tử DOM (cha và con). Live () tại nút cha đảm bảo rằng sự kiện sẽ được gọi và sau đó gọi một () để đăng ký động sự kiện sẽ chỉ được thực thi một lần. (điều này cung cấp chức năng tương tự như rebinds).
One()
chức năng hoạt động trong chrome
nhưng không hoạt động safari
trong Mac
.
Bạn có thể thêm lớp css vào các phần tử được liên kết và sau đó lọc chúng ra:
function someMethod()
{
$(obj).not('.click-binded')
.click(function {})
.addClass('click-binded');
}
Phương pháp này cũng có thể được sử dụng cho các plugin:
$(obj).not('.datetimepicker-applied')
.datetimepicker()
.addClass('datetimepicker-applied');
var bound = false;
function someMethod()
{
if(!bound)
{
$(obj).click(function {});
bound = true;
}
}
nhưng tôi có lẽ sẽ xem xét tại sao nó được gọi hai lần trước khi thực hiện một số loại giải pháp.
bound
để gắn vào someMethod()
thay vì gây ô nhiễm không gian tên toàn cầu.
Bạn có thể sử dụng chức năng mở rộng jQuery này.
$.fn.once = function (type, fn, uid) {
if(uid == undefined) {
console.error("Called $.once without uid\n", this, "\n", fn);
}
var dataStr = type+"-handler-"+uid;
if(!this.data(dataStr)) {
this.data(dataStr, true);
this.on(type, fn);
}
};
Thay vì làm điều này
$("button").on("click", function(){
alert("You Clicked On A Button");
});
Ya làm điều này
$("button").once("click", function(){
alert("You Clicked On A Button");
}, "btnHandler");
Bây giờ khi tôi có một chức năng xung quanh nó
function addBtnHandler() {
$("button").once("click", function() {
alert("You Clicked On A Button");
}, "btnHandler");
}
Và tôi gọi nó nhiều lần
addBtnHandler();
addBtnHandler();
addBtnHandler();
Nó chỉ làm điều đó một lần.
Lưu ý rằng tiện ích mở rộng hoạt động bằng cách kiểm tra cả uid và type. Điều này có nghĩa là bạn có thể liên kết các loại trình xử lý khác nhau với cùng một uid, bạn có thể muốn hoặc không. Để thay đổi nó, hãy chỉnh sửa.
var dataStr = type+"-handler-"+uid;
Với một cái gì đó như
var dataStr = "handler-"+uid;
Tôi cũng đang cố gắng sử dụng tắt và bật phương thức jquery cho sự kiện ràng buộc chỉ một lần với phần tử dom chưa tồn tại hoặc phần tử dom chưa được tạo.
$('.select').off('event').on('event', 'selector', function(e){ // });
Mã này không hoạt động bình thường
Tôi đã bắt gặp một phương pháp rất sinh lợi đó là phương pháp 'một'. Nó rất hữu ích khi bạn chỉ muốn ràng buộc một sự kiện một lần.
Bạn có thể tìm thấy tài liệu tại đây http://api.jquery.com/one/
Phương thức này giống với phương thức 'on' nhưng khác với hành vi của nó là không gắn với sự kiện cho nhiều bộ chọn.
$('body').one('click', 'selector', function(){ // do your stuff here });
Bạn có thể đạt được điều này với JS thuần túy, sử dụng phương thức addEventListener và tùy chọn một lần của anh ấy
target.addEventListener('click', handler, {once: true});