# Re-attach DOM event listeners in the body of a turbo-frame

**URL:** https://discuss.hotwired.dev/t/re-attach-dom-event-listeners-in-the-body-of-a-turbo-frame/2377
**Category:** General
**Created:** [February 24, 2021, 3:46pm UTC](https://discuss.hotwired.dev/t/re-attach-dom-event-listeners-in-the-body-of-a-turbo-frame/2377 "2021-02-24T15:46:22Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![dpaola2](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/dpaola2/32/96_2.png) [@dpaola2](https://discuss.hotwired.dev/u/dpaola2)
#### Post date: [February 24, 2021, 3:46pm UTC](https://discuss.hotwired.dev/t/re-attach-dom-event-listeners-in-the-body-of-a-turbo-frame/2377/1 "2021-02-24T15:46:22Z")

</div>

I have some buttons with click handlers that seem to only work on the very first page load. After the turbo-frame they’re a part of is replaced, the click handlers are no longer registered and I have inferred that I need to re-attach them.

I’ve tried to re-attach event listeners after `turbo:load`, `turbo:render`, and even `turbo:submit-end` all to no avail. It seems like the DOM element is indeed found but for some reason none of the event listeners attach. This is the case only after the turbo-frame has been replaced. And it only seems to happen when the visit is triggered by a form submission and redirect - normal links don’t seem to have this problem. Very strange! TIA for any help or advice.

EDIT: I have also noticed that the `data-turbo="false"` tag seems to be ignored entirely. I actually can’t get Turbo to ignore the form submission - no UJS is present, `local: false`, and I even added the `<meta name="turbo-visit-control" content="reload">` tag and Turbo insists on ignoring all of these. Feels related.

---

<div class="post-metadata">

### Author: ![walterdavis](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/walterdavis/32/737_2.png) [@walterdavis](https://discuss.hotwired.dev/u/walterdavis)
#### Post date: [February 24, 2021, 3:59pm UTC](https://discuss.hotwired.dev/t/re-attach-dom-event-listeners-in-the-body-of-a-turbo-frame/2377/2 "2021-02-24T15:59:30Z")

</div>

You should definitely consider re-writing those handlers to respond to deferred events. In jQuery, this would take the form of:

```auto
$(document).on('click', '.some.selector#here', function(evt){
  // do something here
});

```

You can also write this sort of thing in “vanilla” JS, it just takes a few more lines of code. The idea is that the click bubbles up to the document, which then re-attaches it on the fly to the `evt.target.closest('.some.selector#here');`.

Walter

---

<div class="post-metadata">

### Author: ![dpaola2](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/dpaola2/32/96_2.png) [@dpaola2](https://discuss.hotwired.dev/u/dpaola2)
#### Post date: [February 24, 2021, 4:13pm UTC](https://discuss.hotwired.dev/t/re-attach-dom-event-listeners-in-the-body-of-a-turbo-frame/2377/3 "2021-02-24T16:13:37Z")

</div>

You have single handedly saved me hours of work. Thank you so much.

---

<div class="post-metadata">

### Author: ![dpaola2](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/dpaola2/32/96_2.png) [@dpaola2](https://discuss.hotwired.dev/u/dpaola2)
#### Post date: [February 25, 2021, 6:57pm UTC](https://discuss.hotwired.dev/t/re-attach-dom-event-listeners-in-the-body-of-a-turbo-frame/2377/4 "2021-02-25T18:57:34Z")

</div>

Hey @walterdavis do you happen to have a link handy on how to convert that code sample into vanilla JS? I can’t seem to find a good example in the `addEventListener` documentation.

---

<div class="post-metadata">

### Author: ![walterdavis](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/walterdavis/32/737_2.png) [@walterdavis](https://discuss.hotwired.dev/u/walterdavis)
#### Post date: [February 25, 2021, 7:43pm UTC](https://discuss.hotwired.dev/t/re-attach-dom-event-listeners-in-the-body-of-a-turbo-frame/2377/5 "2021-02-25T19:43:13Z")

</div>

Sure. This is ripped from a “use the entire table row as if it was a form label” where I clicked on a radio button if the click landed anywhere on the same row.

```auto
// polyfill for some browsers that don't do this natively
var matches;
(function(doc) {
  matches = 
  doc.matchesSelector ||
  doc.webkitMatchesSelector ||
  doc.mozMatchesSelector ||
  doc.oMatchesSelector ||
  doc.msMatchesSelector;
})(document.documentElement);

// set a delegated handler on a click, only respond if it's on a particular kind of tr
document.addEventListener('click', function(evt) {
  // ignore highlight swipes
  if ( window.getSelection().toString().length > 0 ) return true
  if ( matches.call( evt.target, '.row-as-label td' ) ) {
    const tgt = evt.target.closest('tr').querySelector('td input');
    if(evt.target != tgt) tgt.click();
  }
}, false);

```

Let me know if this helps.

Walter

---

<div class="post-metadata">

### Author: ![dpaola2](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/dpaola2/32/96_2.png) [@dpaola2](https://discuss.hotwired.dev/u/dpaola2)
#### Post date: [February 25, 2021, 7:54pm UTC](https://discuss.hotwired.dev/t/re-attach-dom-event-listeners-in-the-body-of-a-turbo-frame/2377/6 "2021-02-25T19:54:09Z")

</div>

Thanks so much. Owe you.

---

<div class="post-metadata">

### Author: ![existentialmutt](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/existentialmutt/32/166_2.png) [@existentialmutt](https://discuss.hotwired.dev/u/existentialmutt)
#### Post date: [March 3, 2021, 3:40pm UTC](https://discuss.hotwired.dev/t/re-attach-dom-event-listeners-in-the-body-of-a-turbo-frame/2377/7 "2021-03-03T15:40:41Z")

</div>

Glad you found a solution. StimulusJS controllers are also great at managing event handlers on elements that are updated after the initial page load. It’s literally what Stimulus was made for!
