2011-04-15 6 views
0

J'ai préparé une démoHEREélément cliqué ID Être

Mon problème: Je suis en train d'obtenir l'ID de l'élément cliqué. Il retourne toujours l'ID de l'élément qui contient d'autres éléments: l'ID parent 'externe' DIV.

est intéressant, que l'ajout alert(...) (uncomment dans la démo), il en résulte avec deux alertes! Comment? Pourquoi?
La première indiquant l'ID de la DIV superposée et la deuxième alerte: l'ID 'container'. Comment obtenir l'ID de l'élément cliqué exact?

$(document).ready(function(){ 

    $('div').each(function(){ 
     $(this).click(function(){ 
     $('#clicked_info').html($(this).attr('id')); 
     //alert($(this).attr('id')); // try THIS! wow! 
     }); 
    }); 

    }); 

Est-il également possible de saisir tous les éléments ID soumis à la souris (clic) comme alert fait, mais sans alert?

Répondre

0

Le .each() n'est pas nécessaire lorsque le sélecteur de clic requis est déjà utilisé $('div'), en faisant référence à tout élément 'div' dans le DOM.


L'événement click se propage dans l'arborescence DOM par défaut,
retour sur chaque événement Bubble l'ID en cours d'élément.

Alert interrompt l'exécution de la bulle, alertant l'ID d'élément courant faisant la phase de propagation clairement visible quand un résultat positif this.id est satisfaite.
Sans utiliser alert ou console.log (dans l'exemple de l'écriture du résultat sur la page), tous les ID détectés précédemment seront écrasés sur le vol par le plus récent enregistré, résultant en seulement le dernier ID enregistré.

Disons que nous avons cette simple annonce structure HTML nous Cliquez sur l'élément paragraphe:

<div id="container"> 
    Container element 
    <div id="box"> 
     Box element 
     <p>Paragraph</p> 
    </div> 
</div> 

Maintenant, nous allons empêcher l'événement se propage utilisant event.stopPropagation()

$(function() { 

    $('div').click(function(ev) { 
    ev.stopPropagation(); 
    console.log( this.id ); // "box" 
    }); 

}); 

Dans l'exemple ci-dessus, (! même si nous avons cliqué sur l'élément p) l'élément Selector lié à l'événement click était $('div'); propagation supplémentaire a été empêché - renvoyant le résultat souhaité: "box".

En utilisant le code ci-dessus de façon similaire, mais au lieu d'écouter pour event.target nous pourrions avoir une fin mauvais résultat:

$(function(){ 

    $('div').click(function(ev){ 
    console.log( ev.target.id ); // "" 
            // "" 
    }); 

}); 

cause de l'élément enregistré réelle event.target était le HTML Paragraphe élément. La présence de deux éléments emboîtés div (#box et #container) le résultat console.log extrémités ayant un événement à bulles auge nos deux DIV sélecteurs connectant le même (vide) event.target valeur deux fois (// "" // "").

Pour voir exactement l'élément courant event.currentTarget le bouillonnement est actuellement - nous pouvons faire:

console.log(ev.currentTarget.id+' '+ev.currentTarget.tagName); // "box DIV" 
                   // "container DIV" 

résultant toujours dans le dernier élément DIV.

Après avoir exploré tous les résultats ci-dessus, la réponse est d'arrêter/annuler l'événement à bulle l'arbre DOM en utilisant event.stopPropagation() et obtenir le event.currentTarget.id ou simplement this.id notre sélecteur jQuery faire est déjà souhaité $('div') Element.


Maintenant, sachant que la bulle des événements le DOM et
pour obtenir une liste de tous les ID éléments
nous venons de permettre l'événement de se propager, et recueillez l'ID dans un tableau comme dans cet exemple:

$(function(){ 

    var allIDs = []; // Empty Array 

    $('div').on('mousedown', function(ev){ // 
    allIDs.push(this.id); // Push all bubbling DIVs ID into array!! 
    console.log("All IDs: " + allIDs); 
    console.log("Ev. bubbled Selector ID: " + this.id); // First Parent 
    console.log("Target ID: " + ev.target.id); // The targeted one 
    }).on('mouseup', function(){ 
    allIDs = []; // Reset array for further clicks inspections 
    }); 

}); 

jsBin demo

1

Vous assignez gestionnaire de clic à tous les éléments div et depuis le conteneur div # est parent de tous les divs id de cet élément est retourné.

Changer votre code d'événement prêt comme ci-dessous:

$(document).ready(function(){ 

     $(".cssInner").click(function(){ 
     $('#clicked_info').html($(this).attr('id')); 
     //alert($(this).attr('id')); // try THIS! wow! 
     }); 

    }); 

Exemple de travail: http://jsbin.com/udeha4/15/edit

+0

rapide comme toujours! Merci de votre intérêt! J'apprécie toutes vos réponses! - Je sais que je peux assigner un évènement click à une classe de divs, ce n'est pas mon problème, j'ai besoin de retourner un ID même pour le container (c'est pourquoi j'ai ajouté de la marge aux DIVs plus petites) –

+0

@roXon: Dans ce cas La réponse de @Matt Bridges répond à vos besoins. – Chandu

+1

Je viens d'essayer sa réponse! Droite! merci Cyber, j'espère vous voir bientôt;) –

1

Je pense que c'est parce que l'événement click bouillonne des divs internes au contenant div. La fonction de gestionnaire de clics pour cette div sera appelée en dernier et remplacera la valeur de votre élément #clicked_info.

Si vous ne souhaitez que le gestionnaire pour les divs internes à appeler, alors vous devez les sélectionner spécifiquement lors de la fixation du gestionnaire de clic:

$(document).ready(function(){ 
    $('div#container > div').each(function(){ 
     $(this).click(function(){ 
     $('#clicked_info').html($(this).attr('id')); 
     }); 
    }); 
    }); 

Edit: Ou, encore plus facile, il suffit de revenir false de votre fonction de gestionnaire. Cela arrêtera la propagation d'événement aux éléments contenant.

2

Puisque votre gestionnaire de clic est appliqué à toutes les divs, il y a un gestionnaire de clic sur les divs internes et le conteneur. Lorsque vous cliquez une fois, les gestionnaires des deux sont exécutés. Si vous voulez seulement montrer la div intérieure, vous pouvez empêcher l'événement « bouillonne » en faisant ceci:

$('div').each(function(){ 
    $(this).click(function(e){ 
    e.stopPropagation(); 
    $('#clicked_info').html($(this).attr('id')); 
    }); 
}); 
0

Je pense que c'est ce que vous vouliez dire:

$(document).ready(function(){ 
    $('div .cssInner').click(function(){ 
    $('#clicked_info').html($(this).attr('id')); 
    //alert($(this).attr('id')); // try THIS! wow! 
    }); 
}); 

Dans ce cas, vous définissez la cliquez sur événement pour arriver sur les éléments internes seulement!

+0

> Merci, mais regardez la réponse que j'ai donné à Cybernate –

+0

d'accord avec lui, Matt Bridges l'a eu! –

+0

Mais regardez la réponse 'lonesomeday'! ... pourquoi je ne peux pas marquer 'Plus de bonnes réponses?' :(...;) –

2

La raison est quelque chose appelé bouillonnement d'événement. Lorsqu'un événement est déclenché sur un élément, ses éléments ancêtres sont informés de l'événement. Si des gestionnaires d'événements sont liés à cet événement, ils seront également déclenchés.

Dans ce cas, un clic sur #div3 déclenche le gestionnaire sur cet élément (d'où l'alerte div3), puis l'événement bulles jusqu'à l'élément container, et déclenche le gestionnaire sur cet élément (puisque vous lié le gestionnaire à tous div éléments). Puisque le gestionnaire container a été déclenché en second, c'est le résultat mis en #clicked_info.(div3 est mis là par le premier gestionnaire, mais immédiatement remplacé.)

Pour contourner cela, il existe plusieurs solutions. Ma solution préférée est d'appliquer l'identifiant de la fonction d'origine, qui est la propriété de l'objet targetevent:

$(this).click(function(event){ 
    $('#clicked_info').html(event.target.id); 
}); 

Modified example. Notez que j'ai également simplifié votre code: l'appel each est inutile car click se lie à chaque élément de la sélection.

Je pense que cette solution est meilleure que d'arrêter la propagation car elle n'arrête pas la propagation! La propagation est souvent utile (c'est pourquoi elle existe, après tout) et un autre aspect de votre code peut en dépendre.

+1

copier-coller votre code avec un message d'alerte pour montrer l'id fait apparaître la boîte d'alerte deux fois –