web-dev-qa-db-fra.com

jQuery bind cliquez sur * N'IMPORTE QUOI * mais * ELEMENT *

Supposons qu'il y ait des éléments flottants et que j'essaie d'en faire quand je clique sur N'importe quoi (divs, body, etc.) mais celui spécifié (par exemple div # special).

Je me demande s'il existe un meilleur moyen d'y parvenir en plus de la méthode suivante à laquelle je peux penser ...

$(document).bind('click', function(e) {
    get mouse position x, y
    get the element (div#special in this case) position x, y
    get the element width and height
    determine if the mouse is inside the element
    if(inside)
        do nothing
    else
        do something
});
66
railOne

Pour gérer l'élément "faire ceci sauf quand this est" cliqué " En général, l’approche consiste à ajouter un gestionnaire d’événements à document, qui gère le cas "do this", puis à ajouter un autre gestionnaire d’événements à l’élément "except this", ce qui empêche simplement document;

$('#special').on('click', function(e) {
    e.stopPropagation();
});

$(document).on('click', function (e) {
 // Do whatever you want; the event that'd fire if the "special" element has been clicked on has been cancelled.
});

Voir la documentation event.stopPropagation() . Pour ceux d'entre vous qui utilisent des versions antérieures à jQuery 1.7 (comme c'était le cas lorsque cette question a été posée), vous ne pourrez pas utiliser on(); remplacez simplement les 2 utilisations de on() par bind() ; la signature dans ce cas est la même.

Démo ici; http://jsfiddle.net/HBbVC/

113
Matt

Tu pourrais aussi faire

$(document).bind('click', function(e) {
  if(!$(e.target).is('#special')) {
    // do something
  }
});

ou si div # special a des éléments enfants que vous pourriez faire

$(document).bind('click', function(e) {
  if($(e.target).closest('#special').length === 0) {
    // do something
  }
});
43
bmavity

Je l'ai fait comme ça dans le passé:

jQuery("body").bind("click", function(e)
{
    var obj = (e.target ? e.target : e.srcElement);
    if (obj.tagName != 'div' && obj.id != 'special')
    {
        // Perform your click action. 
        return false;
    }
});

Cela ne s’exécutera que si vous n’avez pas cliqué sur div # special. Honnêtement, il y a peut-être de meilleures façons de le faire, mais cela a fonctionné pour moi.

5
Dan Smith

vous devez faire différentes liaisons, il n'est pas nécessaire de traiter tous ces clics dans une seule fonction

$('body').bind('click', function(e){
  bodyClickEvent();
});
$('div.floating').bind('click',function(e){
  elementClickEvent(this);
  e.stopPropagation(); //prevents bodyClickEvent
});
  $('div#special').bind('click', function(){
  e.stopPropagation(); //prevents bodyClickEvent
});
1
El'

J'ai écrit ceci aujourd'hui pour un problème que je rencontrais car je n'aime pas avoir des événements de clic liés au document tout le temps, donc pour mon scénario cela fonctionne, en utilisant des rappels à partir de fonctions.

$('#button').click(function(){
        //when the notification icon is clicked open the menu
        $('#menu').slideToggle('slow', function(){
            //then bind the close event to html so it closes when you mouse off it.
            $('html').bind('click', function(e){
                $('#menu').slideToggle('slow', function(){
                    //once html has been clicked and the menu has closed, unbind the html click so nothing else has to lag up
                    $('html').unbind('click');
                });
            });
            $('#menu').bind('click', function(e){
                //as when we click inside the menu it bubbles up and closes the menu when it hits html we have to stop the propagation while its open
                e.stopPropagation();
                //once propagation has been successful! and not letting the menu open/close we can unbind this as we dont need it!
                $('#menu').unbind('click');
            });
        });
    });
1
Owen