I am trying to integrate this into my LiveView component and the JavaScript does not work as expected. When I click the dropdown, it doesn’t come down.
When I print some elements, they don’t show up where they should (like they do in the codepen).
For example, if I print const dropdownArrow = document.querySelector(".dropdown__arrow"); using Chrome DevTools, I hover over the print statement and it shows the arrow somewhere different than where it is on the DOM.
The LiveView component is pretty standard itself (basically like any one in documentation / tutorials). I’ve been debugging this for a few days; it seems to me that there’s something about JS and LiveView that I’m not aware of.
I guess this is simply executed at start of your normal app.js. It’s not going to work well like that if at all. Liveview is managing the DOM (unless you set it to ignore nodes) of your markup, therefore those dom nodes you’re selecting in your code are not guaranteed to stick around in the face of updates. They might be removed or updated at any time. This means you cannot plainly attach event listeners to nodes or store references to dom nodes in variables. You’ll need to use liveview hooks to attach this stuff to dom nodes and depending on your needs implement update logic/restarts on update – or if no updates are needed consider making liveview ignore those parts of the dom. To summarize: This javascript is not ready to deal with DOM nodes changing beneath it’s functionality.
// Used to register listener in liveview
hook: {
mounted() {
registerListener(this.el)
}
},
// Used to register listener when dom is loaded normally
init: function () {
getElements().forEach(registerListener)
}
}