1

I solved this part: see So I got it to work below for new problem. Following is the initial problem for reference and context: I have a custom.js file in app/javascript folder. I have a bit of code that adds a listener for a player:

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

The audio player is rendered as a partial. The target for the audio source is set by the listener when the user clicks the list item. The list item code (included in the partial) is: <li data-additional-info= <%=track_url%>><%= sanitize_filename(track.key) %></li>

Everything works beautifully for rendering the partial on the home page, but when I try to render the partial on a different page (in addition to the home page), everything works except the listener, so I get the list items as I should but they are not clickable to load a selected file into the player.

my application.html.rb has the following code loading javascript

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

So I got it to work..sort of. Here's my silly error. I was using advice from this post:

I went back to the post and followed the instructions. Ichanged the event listener from above to the following:

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

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

Not paying enough attention to detail is a killer...but now if i play the file on one page and navigate to the other page that holds the same partial, I have to do a browser refresh to get it to play on the new page.

rrivermcd
  • 45
  • 2
  • 8

1 Answers1

3

I'm going to assume you're using Rails Turbolinks since it's a default feature and I see 'data-turbolinks-track' in your script include tag.

Here's a pared-down version of how turbolinks works:

  1. you click a link
  2. Rails prevents the default behavior of your browser loading the next page, but rails javascript will fetch that new page via javascript ajax.
  3. Rails replaces the DOM element that is your central "view" and replaces the html with the html it just got from the ajax request.
  4. you now have brand new (non-hydrated) html in your view, but your layout and your javascript environment have remained the same.

Here what's happening in your application:

  1. Your page loads
  2. the javascript queries the page for a '.js-interactive-list' element and finds one
  3. your javascript applies an event listener to that DOM element
  4. you click a link to the next page, turbolinks fetches the html and replaces all of the elements in your view with fresh new html—with no listeners added

The event listener you added was only added to the element which rails turbolinks just threw away or cached. The fresh new html rails turbolinks loaded and replaced your view with doesn't have any event listeners added.

So you can either listen to the page:load event that rails turbolinks fires whenever it replaces the view and re-apply those event listeners like this example

Or you can apply your event listener to an element higher up in the DOM tree—an element that doesn't get replaced within the view. An example of this would be (in jQuery):

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

Does that make sense?

jbielick
  • 2,800
  • 17
  • 28
  • I've got the javascript wrapped in `document.addEventListener("DOMContentLoaded", function() {listener code from above});` Is this wrong? I wrapped everything in this listener to get the other listeners to load at the right time (and work in the first place). – rrivermcd Aug 05 '14 at 19:08
  • 1
    DOMContentLoaded will occur when the original document resource is loaded and ready. When rails turbolinks replaces your view's HTML with new HTML, there is no additional DOMContentLoaded event. That's why Rails gives you a page:load event [explained here](http://stackoverflow.com/a/18770589/3543371) – jbielick Aug 05 '14 at 19:15