触发内部元素上的单击事件

每个第一个单元格包含链接的表格中的一行需要单击并打开一个URL。

 ... 
LT5C260A436C41 more data
LA5C260D436C41 more data

完整的行应该是可点击的,而不是只有链接顶部打开fancybox中的详细信息页面,即在页面本身。

所以我试着这样做:

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

但似乎事件正在冒泡,导致:

未捕获RangeError: 超出最大调用堆栈大小

如何以正确的方式触发完整行而不是仅仅链接的单击以避免堆栈溢出?

更新:我真的很感谢下面的答案,但我的问题是关于触发事件,而不是执行该事件内的行为。 解决方法可能很好,但在这种情况下不是。

这很好用:

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

编辑:

为什么大多数解决方案都不起作用 – 它们会失败,因为当单击链接时,附加的直接处理程序会运行。 然后该事件冒泡以查看处理程序是否附加到表格单元格,行等。

当你建议触发点击时你会导致递归:点击了链接→fancybox→bubbles→aha! 表格行→触发链接点击→链接被点击…

当您建议停止传播时,请注意事件停止冒泡到父元素,因此不会执行附加到bodyclick处理程序。

为什么上面的代码有效 – 我们检查事件是否来自链接。 如果是,我们只需返回并停止进一步传播。


查看更新的小提琴: http : //jsfiddle.net/F5aMb/28/

尝试

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

试试这个:

 $("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'); }); 

我发现了什么问题。

在你的代码中,

 $("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. }); 

更新:

这样做。

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

$(this).find("a").trigger('click'); 实际上并没有触发默认的锚标记行为。 如果单击事件已明确绑定到该元素,它只会尝试触发单击事件。

可能是我误解了你的问题,但这不符合你的需要:

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

对于本练习的有趣目的,这里是一个纯粹的js解决方案,即没有使用jQ lib)。

可在此测试: http : //jsfiddle.net/Sr5Vy/3/

 
LT5C260A436C41 more data
LA5C260D436C41 more data

 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 ) 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  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); } } 

尝试

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

您是否尝试在单击链接时停止立即传播?这样您应该停止递归

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

在这里小提琴: http : //jsfiddle.net/3VMGn/2/

为了补偿冒泡,您需要检测事件的目标,而不是多次单击链接。 此外,jQuery的“触发器”function不适用于普通链接,因此您需要一个专门的点击function。

你可以试试看: 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() } } 

我能够通过为每个链接提供唯一ID然后使用jQuery设置该唯一ID的click事件来将窗口重定向到适当的页面来实现。

这是我的工作示例: http : //jsfiddle.net/MarkKramer/F5aMb/2/

这是代码:

 $('#link1').click(function(){ // do whatever I want here, then redirect window.location.href = "https://stackoverflow.com/questions/7632125/trigger-a-click-event-on-an-inner-element/detail.aspx?CID=67525"; }); $('#link2').click(function(){ // do whatever I want here, then redirect window.location.href = "https://stackoverflow.com/questions/7632125/trigger-a-click-event-on-an-inner-element/detail.aspx?CID=17522"; }); $("table tr").click(function(e) { e.stopImmediatePropagation(); $(this).find("a").trigger('click'); }); 

您可以使用以下代码执行所需操作。 我测试了你jsfilddle似乎工作。

 $("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(); } }); 

让我知道,如果你想要实现别的目的。

我认为.trigger("click") .click().trigger("click")只会激活onclick的事件处理程序。

请参阅此处的示例http://jsfiddle.net/sethi/bEDPp/4/ 。 手动点击链接会显示2个警报,同时通过jQuery触发事件仅显示1个警报。

您还可以参考此链接: 使用jQuery重新触发链接上的click事件

如果你只是想打开一个fancybox试试这个:

 $("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是fancybox与anchor元素绑定的事件。

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

我想我有你想要的东西。 您需要做的是在处理程序中的锚标记上调用click() ,并确保忽略锚本身的事件。 此外,WebKit不支持click() ,因此您必须自己实现它。

请注意下面的小提琴,它正确地跟随链接目标,即打开一个新窗口,或加载到同一窗口。 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(); }); 

我的用例是在单击-element时触发单击。 检查目标元素的类型可以解决递归调用问题。

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