Saya memiliki kode berikut:
function someMethod()
{
$(obj).click(function {});
}
someMethod dipanggil dua kali dan dengan demikian peristiwa klik diikat dua kali. Bagaimana saya bisa membuatnya mengikat hanya sekali?
Saya memiliki kode berikut:
function someMethod()
{
$(obj).click(function {});
}
someMethod dipanggil dua kali dan dengan demikian peristiwa klik diikat dua kali. Bagaimana saya bisa membuatnya mengikat hanya sekali?
Jawaban:
Jika Anda dapat menerapkannya, mungkin ingin melihat event.preventDefault dan event.stopPropagation OR unbind and bind setiap kali, dalam metode Anda seperti
function someMethod()
{
$(obj).off('click').on('click', function(e) {
// put your logic in here
});
}
function someMethod() { $(obj).off('click.namespace').on('click.namespace', function {}); }
Selain jawaban pna, Anda mungkin ingin memikirkan tentang namespacing acara Anda sehingga Anda tidak terus-menerus melepaskan semua peristiwa klik secara tidak sengaja.
function someMethod () {
$ (obj) .unbind ('click.namespace'). bind ('click.namespace', function () {});
}
$(obj).off()dan $(obj).on()masing - masing. Jika tidak, namespacing membantu dan ini berhasil. Terima kasih!
Tidak ada metode bawaan untuk menentukan apakah Anda telah mengikat fungsi khusus ini. Anda dapat mengikat beberapa fungsi klik ke sebuah objek. Sebagai contoh:
$('#id').bind('click', function(){
alert('hello');
});
$('#id').bind('click', function(){
alert('goodbuy');
});
jika Anda melakukan hal di atas saat objek diklik itu akan memberi tahu halo lalu selamat tinggal. Untuk memastikan hanya satu fungsi yang terikat ke peristiwa klik lepaskan penangan peristiwa klik lalu ikat fungsi yang diinginkan seperti ini:
$(obj).unbind('click').bind('click', function(){... });
Solusi yang jelas adalah tidak menelepon someMethod()dua kali. Jika Anda tidak dapat memperbaikinya, maka Anda dapat menyimpan variabel status sehingga hanya akan mengikat sekali seperti ini:
function someMethod()
{
if (!someMethod.bound) {
$(obj).click(function() {});
someMethod.bound = true;
}
}
Catatan: ini menggunakan properti dari fungsi itu sendiri daripada memperkenalkan variabel global untuk melacak apakah itu terikat. Anda juga bisa menggunakan properti pada objek itu sendiri.
Anda dapat melihatnya bekerja di sini: http://jsfiddle.net/jfriend00/VHkxu/ .
Atau gunakan fungsi one () jQuery yang mirip dengan on () tetapi hanya mengaktifkan peristiwa sekali, bahkan jika Anda mengikatnya beberapa kali.
jQuery memungkinkan pemanggilan beberapa fungsi hanya sekali cukup mudah:
function someMethod()
{
$(obj).click(function() {});
this.someMethod = $.noop;
}
jQuery.noophanya satu karakter lebih pendek dari function(){}, jadi agak konyol mengatakan itu "membantu" di sini, hanya menyediakan fungsi kosong. Berikut adalah contoh non-metode non-jQuery dari solusi umum ini:var fn = function(){ fn = function(){}; do stuff; };
$sebagai gantinya
Ini saran karena saya tidak tahu logika Anda. Mungkin berhasil atau tidak untuk Anda.
Coba gabungkan fungsi jquery live () dan one () akan memberi Anda hasil yang lebih baik daripada event rebinds.
Kasus khusus berfungsi ketika Anda memiliki 2 elemen DOM (induk & anak). Live () di node induk memastikan acara akan dipanggil, dan kemudian memanggil satu () untuk mendaftarkan acara secara dinamis yang akan dijalankan hanya sekali. (ini menyediakan fungsionalitas serupa seperti rebind).
One()fungsi berfungsi chrometetapi tidak berfungsi safaridi Mac.
Anda dapat menambahkan kelas css ke elemen terikat dan kemudian memfilternya:
function someMethod()
{
$(obj).not('.click-binded')
.click(function {})
.addClass('click-binded');
}
Metode ini dapat digunakan juga untuk plugin:
$(obj).not('.datetimepicker-applied')
.datetimepicker()
.addClass('datetimepicker-applied');
var bound = false;
function someMethod()
{
if(!bound)
{
$(obj).click(function {});
bound = true;
}
}
tapi saya mungkin akan melihat mengapa itu; dipanggil dua kali sebelum membuat beberapa jenis solusi.
bounddilampirkan someMethod()alih-alih mencemari ruang nama global.
Anda dapat menggunakan fungsi ekstensi jQuery ini.
$.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);
}
};
Daripada melakukan ini
$("button").on("click", function(){
alert("You Clicked On A Button");
});
Ya lakukan ini
$("button").once("click", function(){
alert("You Clicked On A Button");
}, "btnHandler");
Sekarang ketika saya memiliki fungsi di sekitarnya
function addBtnHandler() {
$("button").once("click", function() {
alert("You Clicked On A Button");
}, "btnHandler");
}
Dan saya menyebutnya beberapa kali
addBtnHandler();
addBtnHandler();
addBtnHandler();
Itu hanya melakukannya sekali.
Perhatikan bahwa ekstensi bekerja dengan memeriksa uid dan type. Ini berarti Anda dapat mengikat berbagai jenis penangan dengan uid yang sama, Anda mungkin menginginkan ini atau tidak. Untuk mengubahnya, edit.
var dataStr = type+"-handler-"+uid;
Dengan sesuatu seperti
var dataStr = "handler-"+uid;
Saya juga mencoba menggunakan metode off and on jquery untuk mengikat event hanya sekali dengan elemen dom yang belum ada atau elemen dom belum dibuat.
$('.select').off('event').on('event', 'selector', function(e){ // });
Kode ini tidak berfungsi dengan benar
Saya menemukan metode yang sangat menguntungkan yaitu metode 'satu'. Ini sangat berguna jika Anda ingin mengikat acara hanya sekali.
Anda dapat menemukan dokumennya di sini http://api.jquery.com/one/
Ini sama dengan metode 'on' tetapi berbeda dengan perilakunya dengan tidak melekat pada acara untuk banyak pemilih.
$('body').one('click', 'selector', function(){ // do your stuff here });
Anda dapat mencapai ini dengan JS murni, menggunakan metode addEventListener dan opsi sekali
target.addEventListener('click', handler, {once: true});