2011-01-28 224 views
5

Qual è il modo più semplice per fare un clickout in jquery Dove si nasconde una casella div se viene fatto clic ovunque al di fuori di esso.Clickout in jquery

risposta

11

Non mi piacciono le soluzioni che utilizzano stopPropagation perché spesso sto usando bubbling degli eventi per gestire i vari collegamenti. Non voglio preoccuparmi che possano smettere di funzionare se la scatola esiste. La mia scelta sarebbe simile a questa:

var $box = $('#box'); 
$(document.body).click(function(){ 
    if (!$box.has(this).length) { // if the click was not within $box 
     $box.hide(); 
    } 
}); 

La funzione has i filtri di selezione e restituisce gli elementi solo se contengono l'elemento passato come parametro (è anche possibile utilizzare una stringa di selezione, ma che non è rilevante qui). Se il clic era all'esterno della casella, length sarà 0, quindi il condizionale passerà e la casella verrà nascosta.

Questo dovrebbe essere ottimizzato impostando un valore booleano per indicare se la casella è attualmente visibile e solo effettuando la chiamata se è attualmente visibile.

+0

pulito e semplice – Hussein

+4

Questo non ha funzionato per me, ma dopo aver esaminato la risposta di Caspar ho potuto farlo cambiando 'this' to' e.target' e aggiungendo 'e' come argomento al callback. – meustrus

3
$('body').click(function() { 
    $('#box').fadeOut(); 
}); 

$('#box').click(function(e) { 
    e.stopPropagation(); 
}); 

Questo funziona perché #box riceverà prima l'evento click se si fa clic all'interno. Poiché la propagazione viene interrotta, il gestore collegato al corpo non lo riceverà, quindi la casella non verrà chiusa se non si fa clic all'esterno della casella.

se si vuole che per nascondere immediatamente, utilizzare .hide()

Ho la stopPropagation() trucco da How do I detect a click outside an element?

+0

Questo lo nasconderebbe se si fa clic all'interno del div, non all'esterno. –

+0

Ah .. ho letto male la domanda. – ThiefMaster

1

So che jQuery ha l'evento "focusout" per gli elementi di forma, non è sicuro se potesse forse essere utilizzato per un

4

come questo:

$("#thediv").show(0, function() { 
    var that = $(this); 
    $(document).bind("click", function(e) { 
     if($(e.target).attr("id") != that.attr("id")) { 
      that.hide(); 
      $(this).unbind("click"); 
     } 
    }); 
}); 

violino qui: http://jsfiddle.net/XYbmE/3/

+0

Ben fatto, tuttavia @lonesomeday è più pulito. – Hussein

0

associare una funzione di clic al documento stesso:

$(document).click(function(){ 
    alert('doc'); 
}); 

quindi associare una funzione per lo stesso evento sul div stesso e return false modo che l'evento non sarà bolla fino al documento .

$('#mydiv').click(function(e){ 
    alert('mydiv click'); 
    return false; 
} 
+0

Meglio usare 'e.stopPropagation()' invece di 'return false;'. – ThiefMaster

0

Heres la mia soluzione

var ClickOut = {}; 

    ClickOut.list = []; 

    ClickOut.Add = function(jqel, callback) { 
     var i = ClickOut.list.push({jqel:jqel, callback:callback}); 
     return (i-1); 
    } 

    ClickOut.Remove = function(i) { 
     ClickOut.list.splice(i, 1); 
    } 

    ClickOut.Init = function() { 
     $('body').click(function(e) { 
      for(var x = 0; x < ClickOut.list.length; x++) { 
       if (!ClickOut.list[x].jqel.has(e.target).length) { 
        ClickOut.list[x].callback(); 
       } 
      } 
     }); 
    }