2013-06-08 11 views
7

Ho una funzione, che attribuirà gestore click evento al il mio elemento:Come evitare di collegare il gestore eventi più volte?

function attachClickToElem() { 
    $('.elem').on('click', function() { 
     alert('Hello World'); 
    }); 
} 

Il problema è che ogni volta che io chiamo questa funzione, n click gestore allegare al mio elemento, così quando chiamo due volte , ottengo due alert quando clicco sul mio elemento:

$(function() { 
    attachClickToElem(); 
    attachClickToElem(); 
}); 

Come posso impedirlo? E controlla se il mio elemento ha già il gestore click?

Here is fiddle

+0

Perché non basta sciogliere prima di associare ogni volta .... salva su perdita di memoria quindi. – adrian

risposta

4

Working jsFiddle Demo

Usa .each() metodo per scorrere gli elementi, e controllare un bandiera già da gestori di eventi con .data() metodo, se la bandiera è true, saltare il ciclo attuale. Altrimenti, collega il gestore di eventi all'elemento e imposta il flag come true.

function attachClickToElem() { 
    $('.elem').each(function() { 
     var $elem = $(this); 

     // check if event handler already exists 
     // if exists, skip this item and go to next item 
     if ($elem.data('click-init')) { 
      return true; 
     } 

     // flag item to prevent attaching handler again 
     $elem.data('click-init', true); 

     $elem.on('click', function() { 
      alert('Hello World'); 
     }); 
    }); 
} 

Riferimenti:

  • .each() - jQuery API Documentazione
  • .data() - jQuery API Documentazione
0

qualcosa di simile a questo credo:

function attachClickToElem() { 
    $('.elem:not(.has-click-handler)') 
     .addClass('has-click-handler') 
     .on('click', function() { 
      alert('Hello World'); 
    }); 
} 
11

Prova

function attachClickToElem() { 
    $('.elem').off('click.mytest').on('click.mytest', function() { 
     alert('Hello World'); 
    }); 
} 

$(function() { 
    attachClickToElem(); 
    attachClickToElem(); 
}); 

Demo: Fiddle

Un altro modo

function attachClickToElem() { 
    $('.elem').filter(function(){ 
     return !$(this).data('myclick-handler'); 
    }).on('click.mytest', function() { 
     alert('Hello World'); 
    }).data('myclick-handler', true); 
} 

$(function() { 
    attachClickToElem(); 
    attachClickToElem(); 
}); 

Demo: Fiddle

+0

Mi piace la prima soluzione con uno spazio dei nomi di eventi: semplice e pulita – xtian

+0

Quando consiglieresti l'uso della seconda soluzione con un filtro? Il ciclo off/on è costoso? – xtian

+0

@xtian Raccomanderò il primo, ma per gestire l'elemento dinamico dovresti davvero usare gli eventi delegati –

Problemi correlati