Déclenchez un événement de clic sur un élément intérieur

Une ligne dans une table où chaque première cellule contient un lien doit être cliquée et ouvrir une url.

<table> <tr> <td><a class="fancybox" href="detail.aspx?CID=67525">LT5C260A436C41</a></td> <td>more data</td> </tr> <tr> <td><a class="fancybox" href="detail.aspx?CID=17522">LA5C260D436C41</a></td> <td>more data</td> </tr> ... </table> 

La ligne complète doit être cliquable au lieu de seulement le lien supérieur d'ouvrir la page de détail dans une fancybox , c'est-à-dire dans la page elle-même.

J'ai donc essayé de faire quelque chose comme ça:

 $("table tr").bind('click',function(e) { e.stopPropagation(); $(this).find("a").trigger('click'); }); 

Mais il semble que l'événement bouillonne de manière récursive en résultant: a)

RangeError non détecté: taille maximale de la pile d'appels dépassée

Comment puis-je déclencher le clic sur la ligne complète au lieu de seulement le lien de manière appropriée, en évitant le stackoverflow?

MISE À JOUR: J'apprécie vraiment les réponses ci-dessous, mais ma question concerne le déclenchement de l'événement, sans exécuter le comportement à l'intérieur de cet événement. Les solutions de contournement pourraient être agréables, mais pas dans ce cas.

Cela a bien fonctionné:

 $("table tr").click(function(e) { var $link = $(this).find("a"); if (e.target === $link[0]) return false; $link.trigger('click'); return false; }); 

MODIFIER:

Pourquoi la plupart des solutions ne fonctionnent pas – elles échouent, car lorsque le lien a été cliqué, le gestionnaire immédiat est connecté. L'événement éclate alors pour voir si un gestionnaire était attaché à une cellule de table, une ligne, etc.

Lorsque vous suggérez un déclic, vous avez provoqué la récurrence: le lien a été cliqué → fancybox → bubbles → aha! Table row → trigger the link click → le lien a été cliqué …

Lorsque vous suggérez d'arrêter la propagation, notez que l'événement cesse de bouillonner aux éléments parents, de sorte qu'un gestionnaire de click attaché au body ne sera pas exécuté.

Pourquoi le code ci-dessus fonctionne – nous vérifions si l'événement a été analysé à partir d'un lien. Si c'est vrai, nous revenons tout simplement et arrêtons la propagation.


Voir le violon mis à jour: http://jsfiddle.net/F5aMb/28/

essayer

 $('table tr').click(function() { var href = $(this).find("a").attr("href"); if(href) { window.location = href; } }); 

Essaye ça:

 $("table tr a").bind('click', function(e) { e.preventDefault(); window.open($(this).attr('href')); return false; }); $("table tr").bind('click', function(e) { $(this).find("a").trigger('click'); }); 

J'ai trouvé ce qui ne va pas.

Dans votre code,

 $("table tr").bind('click',function(e) { e.stopPropagation(); $(this).find("a").trigger('click');//This line again triggers a click event binded on the tr ELEMENT which contains the 'a' ELEMENT. So it goes into a infinite loop. }); 

Mettre à jour:

Cela fera.

 $("table tr").bind('click', function(e) { window.location.href = $(this).find("a.fancybox").attr('href'); }); 

$(this).find("a").trigger('click'); Ne déclenche actuellement pas le comportement d'étiquette d'ancrage par défaut. Il tente simplement de déclencher un événement de clic si un événement de clic est déjà lié à cet élément explicitement.

C'est peut-être que j'ai mal compris votre question, mais cela ne fait pas ce dont vous avez besoin:

 $("table tr").click(function(e) { e.stopImmediatePropagation(); if (! $(e.target).is('a')) { $(this).find("a").trigger('click'); } }); 

Pour le but drôle de cet exercice, voici une solution js pure, c'est-à-dire sans utiliser jQ lib).

Disponible ici pour tester: http://jsfiddle.net/Sr5Vy/3/

 <table> <tr id="node_1"> <td><a class="fancybox" href="detail.aspx?CID=67525">LT5C260A436C41</a></td> <td>more data</td> </tr> <tr id="node_2"> <td><a class="fancybox" href="detail.aspx?CID=17522">LA5C260D436C41</a></td> <td>more data</td> </tr> </table> 

 function AddEvent(id, evt_type, ma_fonction, phase) { var oElt = document.getElementById(id); if( oElt.addEventListener ) { oElt.addEventListener(evt_type, ma_fonction, phase); } else if( oElt.attachEvent ) { oElt.attachEvent('on'+evt_type, ma_fonction); } // Debug // alert('a \'' + evt_type + '\' event has been attached on ' + id ); return false; } function getElementsByRegExpOnId(search_reg, search_element, search_tagName) { search_element = (search_element === undefined) ? document : search_element; search_tagName= (search_tagName === undefined) ? '*' : search_tagName; var id_return = new Array; for(var i = 0, i_length = search_element.getElementsByTagName(search_tagName).length; i < i_length; i++) { if (search_element.getElementsByTagName(search_tagName).item(i).id && search_element.getElementsByTagName(search_tagName).item(i).id.match(search_reg)) { id_return.push(search_element.getElementsByTagName(search_tagName).item(i).id) ; } } return id_return; // array } function FollowSpecialLinks(event) { // Debug // alert('event was successfully attached'); // Prevent propagation event.preventDefault(); // Identify targetted node (eg one of the children of <tr>) var targetted_elt = ShowEventSource(event); //alert('Event\'s target : ' + targetted_elt); // Extract the targetted url if (targetted_elt == "A") { var current_link = GetEventSource(event).href; } else { var current_tr = GetEventSource(event).parentNode; var child_links = current_tr.getElementsByTagName('a'); var current_link = child_links[0].href; } // Now open the link if(current_link) { // Debug alert('will now open href : ' + current_link); window.location = current_link; } } function GetEventSource(event) { var e = event || window.event; var myelt = e.target || e.srcElement; return myelt; } function ShowEventSource(event) { var elmt; var event = event || window.event; // W3C ou MS var la_cible = event.target || event.srcElement; if (la_cible.nodeType == 3) // Vs bug Safari elmt = la_cible.parentNode; else elmt = la_cible.tagName; return elmt; } // Get all document <tr> id's and attach the "click" events to them my_rows = new Array(); my_rows = getElementsByRegExpOnId(/^node_.+/, document , 'tr') ; if (my_rows) { for (i=0; i< my_rows.length; i++ ) { var every_row = document.getElementById( my_rows[i] ) ; AddEvent(every_row.id, 'click', FollowSpecialLinks, false); } } 

essayer

 $(".fancybox").parent('td').parent('tr').bind('click',function(e) { e.stopPropagation(); $(this).find("a").trigger('click'); }); 

Avez-vous essayé d'arrêter la propagation immédiate lorsque vous cliquez sur le lien? De cette façon, vous devez arrêter la récurrence

 $('a').click(function(e){ e.stopImmediatePropagation(); alert('hi'); }); 

Cliquez ici: http://jsfiddle.net/3VMGn/2/

Afin de compenser les bouffées, vous devez détecter la cible de l'événement et ne pas cliquer sur le lien plus d'une fois. En outre, la fonction "déclencheur" de jQuery ne fonctionnera pas pour les liens simples, vous avez donc besoin d'une fonction de clic spécialisée.

Vous pouvez l'essayer à l' adresse suivante : http://jsfiddle.net/F5aMb/27/

 $("table tr").each(function(i, tr){ $(tr).bind('click',function(e) { var target = $(e.target); if( !target.is("a") ) { clickLink($(this).find("a")[0]); } }) }); function clickLink(element) { if (document.createEvent) { // dispatch for firefox + others var evt = document.createEvent("MouseEvents"); evt.initEvent("click", true, true ); // event type,bubbling,cancelable return !element.dispatchEvent(evt); } else { //IE element.click() } } 

J'ai pu le faire en donnant à chaque lien une ID unique, puis en utilisant jQuery pour définir l'événement de clic de cette ID unique pour rediriger la fenêtre vers la page appropriée.

Voici mon exemple de travail: http://jsfiddle.net/MarkKramer/F5aMb/2/

Et voici le code:

 $('#link1').click(function(){ // do whatever I want here, then redirect window.location.href = "detail.aspx?CID=67525"; }); $('#link2').click(function(){ // do whatever I want here, then redirect window.location.href = "detail.aspx?CID=17522"; }); $("table tr").click(function(e) { e.stopImmediatePropagation(); $(this).find("a").trigger('click'); }); 

Vous pouvez faire ce que vous voulez avec le code suivant. Je l'ai testé sur vous jsfilddle semble fonctionner.

 $("table tr").click(function(e) { // check if click event is on link or not. // if it's link, don't stop further propagation // so, link href will be followed. if($(e.target).attr('class')=='fancybox'){ alert('you clicked link, so what next ?.'); // else if click is happened somewhere else than link, // stop the propagation, so that it won't go in recursion. }else{ alert('no link clicked, :( '); alert('now clicking link prgrammatically'); $(this).find('a').click(); e.preventDefault(); } }); 

Faites-moi savoir, si vous voulez réaliser quelque chose d'autre que cela.

Je pense que .click() ou .trigger("click") déclenche uniquement les gestionnaires d'événements pour onclick .

Voir un exemple ici http://jsfiddle.net/sethi/bEDPp/4/ . En cliquant manuellement sur le lien, vous voyez 2 alertes en déclenchant l'événement via jQuery ne montre qu'une seule alerte.

Vous pouvez également vous référer à ce lien: ré-déclencher un événement de clic sur un lien avec jQuery

Solution

Si vous cherchez simplement à ouvrir une fancybox, essayez ceci:

 $("table tr").bind('click',function(e) { var elem = $(e.target); if(elem.is('a')){ return; } e.stopImmediatePropagation(); var parent= elem.is('tr') ? elem:elem.parents("tr").eq(0); parent.find("a").trigger('click.fb'); }); 

click.fb est l'événement auquel fancybox se lie avec l'élément d'ancrage.

 $('a.fancybox').click(function(evt){evt.stopPropagation())}); $('table tr:has[.fancybox]').click(function(evt){ $(this).find('.fancybox').trigger('click') }) 

Je pense que j'ai ce que vous cherchez. Ce qu'il faut faire, c'est appeler le click() sur la balise d'ancrage dans le gestionnaire, et assurez-vous d'ignorer les événements de l'ancrage lui-même. En outre, WebKit ne prend pas en charge le click() , donc vous devez l'implémenter vous-même.

Notez de la violon ci-dessous qu'il suit correctement la cible du lien, c'est-à-dire ouvre une nouvelle fenêtre ou charge dans la même fenêtre. http://jsfiddle.net/mendesjuan/5pv5A/3/

 // Some browsers (WebKit) don't support the click method on links if (!HTMLAnchorElement.prototype.click) { HTMLAnchorElement.prototype.click = function() { var target = this.getAttribute('target'); var href = this.getAttribute('href'); if (!target) { window.location = href; } else { window.open(href, target); } } } $("table tr").bind('click',function(e) { // This prevents the stack overflow if (e.target.tagName == 'A') { return; } // This triggers the default behavior of the anchor // unlike calling jQuery trigger('click') $(this).find("a").get(0).click(); }); 

Mon utilisation était de déclencher un clic lorsqu'un élément a été cliqué. La vérification du type de l'élément cible résout le problème de l'appel récursif.

 $('#table tbody td').click(function(e){ if ($(e.target).is('td')) { $(this).find('input').trigger('click'); } });