【问题标题】:Rails render partial seems to make the #element not responsive to $('#element').click(function() anymoreRails 渲染部分似乎使#element 不再响应 $('#element').click(function()
【发布时间】:2021-11-09 05:18:46
【问题描述】:

我有一些 javascript (1) 监控导航 #element 上的点击,它工作得非常好。这是一个基本的 $('#element').click(function())。

但是,我有一些 other javascript (2) 可以“呈现”导航元素中的内容,本质上是刷新它。据我所见,输出的 HTML 与初始的 HTML 足够相同,即我没有从根本上破坏。

一旦这个 javascript (2) 执行并再次呈现导航,我原来的 javascript (1) 就不再工作了。

$(document).ready() 中是否有我需要了解的内容?当 render 发生时,它是否附加到那些不相同的对象上?我需要使用 $(document).ready() 以外的东西,还是我也需要重新加载 javascript?

我在这里误会了什么?


作为参考,这是我的基本代码,application.html 呈现 _nav 模板:

application.html.erb

<%= content_tag "nav", id: "stages-nav", data: {progress_overall: @progress_overall} do %>
  <%= render 'home/nav', current_progress: @progress_overall %>
<% end %>

_nav.html.erb

<ul class="navbar-nav me-auto mb-2 mb-lg-0">
  <li class="nav_item" id="business_costs_nav_item"><a href="javascript:void(0);"><span class="small">step 2: </span>Business Costs</a></li>
  <li class="nav_item" id="wedding_costs_nav_items"><a href="javascript:void(0);"><span class="small">step 3: </span>Wedding Costs</a></li>
  ...etc
</ul>

application.js

$(document).ready(function() {
  // BUSINESS COSTS
  $('#business_costs_nav_item').click(function() {
    slide_current_to_new('business_costs')
  })
});

以上所有都可以正常工作。

但是,在我的应用程序的其他地方,这里是呈现 #stages-nav 的 js:

show_updated_view.js.erb

// updates the stages-nav to give me my current progress
$('#stages-nav').html("<%= escape_javascript(render('home/nav', current_progress: progress )) %>");

上面运行后,我已经仔细检查了 HTML 的输出,它看起来与运行之前相同,所以可以肯定我的页面没有格式错误。如果我没有正确完成此渲染,我很想知道,但对我来说看起来不错。

我猜它必须是 $(document).ready 的东西,但希望得到一些帮助!

【问题讨论】:

    标签: javascript jquery ruby-on-rails ajax


    【解决方案1】:

    一旦文档准备好进行操作,您的代码就会将事件处理程序直接附加到元素。由于您的 js.erb 文件中的元素稍后会通过 AJAX 调用添加到 DOM,因此它们没有附加的事件处理程序。

    这不是特定于 Rails 的,它适用于您向 DOM 动态添加元素的任何时候。解决方法是使用event delegation:

    $(document).on('click', '#business_costs_nav_item', function() {
      slide_current_to_new('business_costs');
    });
    

    这将捕获点击事件,因为它会冒泡到 DOM 顶部并与动态插入的元素一起使用。此代码不需要包装在 jQuery.ready 处理程序中,因为它不会将事件处理程序直接附加到元素。

    原版 JS 中的等价物是:

    document.addEventListener('click', (event) => {
      if (!event.target.matches('#business_costs_nav_item')){
        return;
      } 
      slide_current_to_new('business_costs');
    });
    

    【讨论】:

    • 谢谢@max,回想起来这似乎很简单,但它对我来说是一个改变游戏规则的人,理解这个 .on 函数。这解决了它。太棒了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-07
    • 1970-01-01
    • 1970-01-01
    • 2022-12-04
    • 2011-12-17
    • 1970-01-01
    • 2021-12-10
    相关资源
    最近更新 更多