简体   繁体   中英

How do you make JS EventListeners work in Rails 6 / webpacker?

I'm trying to build a web app using Ruby 2.7.1 and Rails 6.0.3.2. On a page, I want an html popover to appear when the user clicks a button. I have some vanilla JS code that just removes a is-hidden class from my popover div as the user clicks the button, thus making the popover visible.

app/javascript/packs/project.js:

document.addEventListener('turboLinks:load', function () {
    const createProjectButton = document.getElementById('create-project-button')
    const projectPopover = document.getElementById('create-project-popover')

    if (createProjectButton && projectPopover) {
        createProjectButton.addEventListener('click', function () {
            return projectPopover.classList.contains('is-hidden') ? projectPopover.classList.remove('is-hidden') : null
        }, false)

        const cancelProjectPopover = document.getElementById('cancel-project-popover')
        cancelProjectPopover.addEventListener('click', function () {
            return projectPopover.classList.add('is-hidden')
        }, false)
    }
})

I only want this functionality on one specific page of my application right now, so I've included project.js in the respective html file using a pack tag.

app/views/project/index.html.erb:

<html>
   <body>
      ...
      <%= javascript_pack_tag 'project' %>
   </body>
</html>

However, this code does not work as intended. Clicking the corresponding button does not make my popover appear. I can confirm that the js file is correctly included in my application, as any console.log statement that I place in project.js will appear in the browser console. The js code in project.js is from a tutorial that used Rails 5, so I'm guessing it could have something to do with the recent switch from the asset pipeline to webpack.

Take a look at this line:

document.addEventListener('turboLinks:load', function () {

As you can see, it listens for the 'turboLinks:load' event, which won't happen in an application without TurboLinks.

Remember that javascript will execute immediately if you don't specify triggers (at which time your button will simply be unknown to your browser), so change this line to something like:

window.addEventListener('load', (event) => {

And your code will run as intended. Also note that I'm adding a listener to 'window' and not 'document', pay attention to which objects have which available event triggers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM