Properly adding Turbolinks 5 event handling
Here's what I understand:
- Turbolinks preserves the
documentfrom request to request
- As a result, I should add click/change listeners to the window/document once when the js is first loaded so that it can execute when the relevant element click happens (the element may not be loaded on the page yet)
This is possible because of "event delegation," or when you click on a specific child element of the document, you're effectively clicking on the entire body and it will sequentially trigger that event up the DOM tree all the way to the document root.
This is why the TL readme says:
When possible, avoid using the turbolinks:load event to add event listeners directly to elements on the page body. Instead, consider using event delegation to register event listeners once on document or window.
Where I'm stuck is, how do I add an event listener to window to listen for specific elements that may not exist yet? I'd prefer to do this with css selectors and not with if statements checking them, but at this point I'm not even sure if thats an option.
I'd like the
$.on style of setting things up, but it seems like I'll have to check the element the event was triggered on before deciding what to do.
here's some example code of a place where I'd like to do that. This displays different filter options based on what other filter options are selected:
document.addEventListener "turbolinks:load", -> $('#school_type').on 'change', -> selection = this.options[this.selectedIndex].value if selection == "HighSchool" $("[data-behavior='college-division-select']").css(display:'none') $("[data-behavior='high-school-enrollment-select']").css(display:'block') else $("[data-behavior='high-school-enrollment-select']").css(display:'none') $("[data-behavior='college-division-select']").css(display:'block') .trigger('change')
It works, but how could I catch the change event happening on the
#school_type element on the window?
Lastly, but also firstly, is this something even worth worrying about?