使用Rails / jQuery的可单击表行 - 无法使行内的链接正常工作

时间:2014-01-16 02:05:35

标签: javascript jquery html ruby-on-rails ruby-on-rails-4

我正在玩一个Rails 4项目,我成功地完成了它,所以点击表格行中的任何地方都会链接到项目的显示页面(使用jQuery):

$(document).ready(function() {
  // Make table rows clickable
  $(".table tr").click(function() {
    var href = $(this).find("a").first().attr("href");
    if(href) {
      window.location.href = href;
    }
  });
  // Stops links from triggering the tr click???
  $("a").click(function(event) {
    event.stopPropagation();
  });
});

需要包含event.stopPropagation()的第二部分来阻止行内的链接也触发表行单击,因为它们作为子元素存在于其中(如此处所示)(前两个链接只是去项目的显示页面,即行点击使用的内容):http://i.imgur.com/zIA3oci.jpg

问题是,它适用于“编辑”链接(并防止触发前两个链接的额外重定向),但不是“销毁”链接 - 点击它就像我点击其他任何地方一样该行并将我发送到该项目的显示页面。以下是这两个按钮的相关HTML输出:

<tr>
  ...
  <td><a class="btn btn-default btn-xs" href="/foods/2603/edit">Edit</a></td>
  <td><a class="btn btn-danger btn-xs" data-confirm="Are you sure?" data-method="delete" href="/foods/2603" rel="nofollow">Destroy</a></td>
</tr>

现在我知道Rails有自己的Javascript函数来弹出确认框并发送DELETE请求,我想这就是为什么它有data-confirmdata-method属性;我的猜测是,这与我自己的js代码无效的原因有关。有人可以帮帮我吗?

请注意,如果我排除event.stopPropagation(),那么在我重定向之前,确认框会非常短暂地显示,但是因为它没有弹出任何框。

2 个答案:

答案 0 :(得分:4)

经过一番搜索,我最终遇到了this Github issue,这似乎是我遇到的那个。显然,潜在的问题是无法解决的,因为Rails(特别是jquery-ujs)的工作方式,但是提供了一个解决方法,我可以在一些游戏之后适应我的情况:

$(document).ready(function() {
  // Make table rows clickable
  $(".table tr").on('click', function(event) {
    var target = $(event.target);
    if (target.is(":not(a)")) {
      var href = $(this).find("a").first().attr("href");
      if(href) {
        window.location.href = href;
      }
    }
  });
});

基本上现在,如果我点击表格行,它首先会检查被点击的元素是不是a元素(即不是链接),然后才将用户发送到该项目页。如果它是一个链接,Javascript停止,链接有其正常行为。似乎工作正常。

最后一个快速问题是,if (target.is(":not(a)"))是表达这种情况的最佳或最佳方式吗?

答案 1 :(得分:0)

我认为问题在于 $('.table tr').click(function(){...})

我的猜测是表是动态加载的,所以你应该使用;
$('.table tr').on('click', function(){...})
$('.table tr').live('click', function(){...})

或者尝试这个jsfiddle

为了让事情变得有趣,

$('.table tr').on('click', 'a', function(){
    var data = $(this).attr('custom-attr')

    if(data == 'something'){
        //Do something
    }
})