触发内部元素的点击事件

发布于 2024-12-07 21:08:01 字数 939 浏览 0 评论 0原文

需要单击表中的一行,其中每个第一个单元格都包含一个链接并打开一个 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>

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

所以我尝试做这样的事情:

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

但事件似乎递归地冒泡,导致:

未捕获范围错误:超出最大调用堆栈大小

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

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

A row in a table where each first cell contains a link needs to be clicked and open a 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>

The complete row should be clickable instead of only the link top open the detail page in a fancybox, ie in the page itself.

So I tried to do something like this:

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

But it seems that the event is bubbling recursivly resulting in a:

Uncaught RangeError: Maximum call stack size exceeded

How can I trigger the click on the full row instead of only the link in a proper way avoiding the stackoverflow?

UPDATE: I really appreciate the answers below, but my question is about triggering the event, NOT executing the behaviour inside that event. Workarounds could be nice, but not in this case.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

唯憾梦倾城 2024-12-14 21:08:01

这很有效:

$("table tr").click(function(e) {
    var $link = $(this).find("a");

    if (e.target === $link[0]) return false;

    $link.trigger('click');
    return false;
});

编辑:

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

当您建议触发单击时,您会导致递归:单击链接→ fancybox → 冒泡→ 啊哈!表行→触发链接点击→链接被点击...

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

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


请参阅更新的小提琴: http://jsfiddle.net/F5aMb/28/

This worked well:

$("table tr").click(function(e) {
    var $link = $(this).find("a");

    if (e.target === $link[0]) return false;

    $link.trigger('click');
    return false;
});

EDIT:

Why most solutions don't work — they fail, because when the link was clicked, the immediate handler attached runs. The event then bubbles to see if a handler was attached to a table cell, row, etc.

When you suggest triggering a click you cause the recursion: the link was clicked → fancybox → bubbles → aha! table row → trigger the link click → the link was clicked…

When you suggest to stop propagation, please note that event stops bubbling to parent elements, so a click handler attached to body will not be executed.

Why the code above works — we check if the event bubbled from a link. If true, we simply return and stop further propagation.


See the updated fiddle: http://jsfiddle.net/F5aMb/28/

脸赞 2024-12-14 21:08:01

尝试

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

try

$('table tr').click(function() {
  var href = $(this).find("a").attr("href");
    if(href) {
       window.location = href;
    }
});
若水微香 2024-12-14 21:08:01

试试这个:

$("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'); 实际上并没有触发默认
锚标记行为。它只是尝试触发点击事件,如果点击事件
已经明确绑定到该元素。

Try this:

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

I found what went wrong.

In your 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.
});

Update:

This will do.

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

$(this).find("a").trigger('click'); is actually not triggering the default
anchor tag behavior. It just tries to trigger a click event if a click event
is already bound to that element explicitly.

海拔太高太耀眼 2024-12-14 21:08:01

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

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

It may be that I misunderstood your question, but doesn't this do what you need:

$("table tr").click(function(e) {
    e.stopImmediatePropagation();
    if (! $(e.target).is('a')) {
        $(this).find("a").trigger('click');
    }
});
仅此而已 2024-12-14 21:08:01

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

可在此处进行测试: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);
        }
    }

For the funny purpose of this exercise, here is a pure js solution, i.e., w/o using jQ lib).

Available here for testing: 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);
        }
    }
偷得浮生 2024-12-14 21:08:01

尝试

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

Try

$(".fancybox").parent('td').parent('tr').bind('click',function(e) {
    e.stopPropagation();
    $(this).find("a").trigger('click');
});
_失温 2024-12-14 21:08:01

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

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

在此处停止递归小提琴: http:// jsfiddle.net/3VMGn/2/

Have you tried stopping immediate propagation when you click the link?This way you should stop the recursion

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

fiddle here: http://jsfiddle.net/3VMGn/2/

花想c 2024-12-14 21:08:01

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

您可以尝试一下: 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()
   }
}

In order to compensate for the bubbling, you need to detect the target of the event and not click on the link more than once.
Also, jQuery's "trigger" function won't work for plain links, so you need a specialized click function.

you can try it out at: 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()
   }
}
錯遇了你 2024-12-14 21:08:01

我可以通过给每个链接一个唯一的 ID,然后使用 jQuery 设置该唯一 ID 的单击事件来将窗口重定向到适当的页面来完成此操作。

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

这是代码:

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

I was able to do it by giving each link a unique ID and then using jQuery to set the click event of that unique ID to redirect the window to the appropriate page.

Here is my working example: http://jsfiddle.net/MarkKramer/F5aMb/2/

And here is the 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');
});
献世佛 2024-12-14 21:08:01

您可以使用以下代码执行您想要的操作。我在你身上测试过,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();
  }
});

如果您还想实现除此之外的其他目标,请告诉我。

You can do what you want with following code. I tested it on you jsfilddle seems working.

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

Let me know, if you want to achieve something else than this.

未蓝澄海的烟 2024-12-14 21:08:01

我认为 .click().trigger("click") 仅触发 onclick 的事件处理程序。

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

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

解决方案

如果您只是想打开 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 与锚元素绑定的事件。

I think .click() or .trigger("click") only fires the event handlers for onclick.

See a sample here http://jsfiddle.net/sethi/bEDPp/4/
. Manually clicking on the link shows 2 alerts while firing the event through jQuery shows only 1 alert.

You can also refer to this link : re-firing a click event on a link with jQuery

Solution

If you are just looking to open a fancybox try this:

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

where click.fb is the event that fancybox binds with the anchor element.

耶耶耶 2024-12-14 21:08:01
$('a.fancybox').click(function(evt){evt.stopPropagation())});

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

$('table tr:has[.fancybox]').click(function(evt){
$(this).find('.fancybox').trigger('click')
})
两个我 2024-12-14 21:08:01

我想我有你要找的东西。您需要做的是在处理程序中的锚标记上调用 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();
});

I think I have what you're looking for. What you need to do is to call click() on the anchor tag in the handler, and make sure you ignore events from the anchor itself. Also, WebKit doesn't support click(), so you have to implement it yourself.

Notice from the fiddle below that it properly follows the link target, that is, opens a new window, or loads into the same window. 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();
});
只有一腔孤勇 2024-12-14 21:08:01

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

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

My usecase was to trigger a click when a -element was clicked. Checking the type of the target element solves the recursive call problem.

$('#table tbody td').click(function(e){
    if ($(e.target).is('td')) {
        $(this).find('input').trigger('click');
    }
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文