Rails部分使用Javascript侦听器在主页上工作,但没有其他地方

时间:2014-08-05 14:37:29

标签: javascript ruby-on-rails

我解决了这个问题:看到所以我让它工作以解决新问题。以下是参考和上下文的初始问题: 我在app / javascript文件夹中有一个custom.js文件。我有一些代码可以为玩家添加一个监听器:

// Add Listeners 
  document.getElementById('file').addEventListener('change', handleFileSelect, false);
  list.addEventListener("click", function(e)
    {
      audio.src = e.target.dataset.additionalInfo;
    });

音频播放器呈现为部分。 当用户单击列表项时,侦听器将设置音频源的目标。列表项代码(包含在部分中)是:<li data-additional-info= <%=track_url%>><%= sanitize_filename(track.key) %></li>

在主页上渲染部分内容时,一切都很有效,但是当我尝试在不同页面上渲染局部时(除了主页),除了侦听器之外,一切都有效,所以我得到了列表项目但是它们不能被点击以将选定的文件加载到播放器中。

我的application.html.rb有以下代码加载javascript

<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>

所以我让它工作 ..有点儿。这是我的愚蠢错误。我正在使用这个post:

的建议

我回到了帖子并按照说明操作。我将事件监听器从上面改为以下内容:

var list = document.querySelector('.js-interactive-list');

  list.addEventListener("click", function(e)
    {
      audio.src = e.target.dataset.additionalInfo;
    });

对细节不够重视是一个杀手... 但现在如果我在一个页面上播放文件并导航到另一个包含相同部分的页面,我必须做一个浏览器刷新以使其在新页面上播放。

1 个答案:

答案 0 :(得分:2)

我假设您正在使用Rails Turbolinks,因为它是默认功能,我在您的脚本中看到'data-turbolinks-track'包含标记。

以下是turbolinks工作原理的简化版本:

  1. 点击链接
  2. Rails会阻止浏览器加载下一页的默认行为,但rails javascript会通过javascript ajax获取该新页面。
  3. Rails替换了作为中心“视图”的DOM元素,并将html替换为它从ajax请求中获得的html。
  4. 您现在在视图中有全新的(非水合)html,但您的布局和您的javascript环境保持不变。
  5. 此处您的申请中发生了什么:

    1. 您的页面加载
    2. javascript在页面中查询'.js-interactive-list'元素并找到一个
    3. 您的javascript将事件侦听器应用于该DOM元素
    4. 您点击指向下一页的链接,turbolinks会抓取html,并使用全新的html替换视图中元素的所有 - 未添加任何侦听器
    5. 您添加的事件侦听器仅添加到轨道turbolink刚刚丢弃或缓存的元素中。新的新html rails turbolinks加载并替换了你的视图没有添加任何事件监听器。

      因此,您可以收听导入turbolinks的page:load事件,只要它取代视图并重新应用这些事件监听器like this example

      或者您可以将事件侦听器应用于DOM树中更高的元素 - 在视图中不会被替换的元素。 一个例子是(在jQuery中):

      $(document).on('click', '.js-interactive-list', function(e) {
           audio.src = e.target.dataset.additionalInfo;
      });
      

      这有意义吗?