admin管理员组

文章数量:1023782

I have a custom React app built that is not easy for me to modify and repile. There is a div dom element that has some React mouse click events bound to it. I want to know if there is a way I can insert some javascript to intercept a click on this element and redirect the page to a different url. I tried calling removeEventListener on the object but I think React has a firm hold on this so to speak.

document.getElementsByClassName('close-builder')[0].addEventListener("click", function(){
    alert("test");
});

My event fires first (I think) but so do the ones I am trying to get rid of.

I have a custom React app built that is not easy for me to modify and repile. There is a div dom element that has some React mouse click events bound to it. I want to know if there is a way I can insert some javascript to intercept a click on this element and redirect the page to a different url. I tried calling removeEventListener on the object but I think React has a firm hold on this so to speak.

document.getElementsByClassName('close-builder')[0].addEventListener("click", function(){
    alert("test");
});

My event fires first (I think) but so do the ones I am trying to get rid of.

Share Improve this question edited Jun 8, 2018 at 14:43 Derek 朕會功夫 94.5k45 gold badges198 silver badges253 bronze badges asked Jun 7, 2018 at 22:34 Jason GordonJason Gordon 511 silver badge3 bronze badges 2
  • it's better when you add code of what you have at the moment to give you a good response and help you – xploshioOn Commented Jun 7, 2018 at 23:55
  • Yes, it's quite easy to do. What events do you want to intercept? Are they bound with onClick, etc? – dfsq Commented Jun 8, 2018 at 14:24
Add a ment  | 

1 Answer 1

Reset to default 4

Yes, this is quite easy to do. However you can't do it the way you tried. The reason is because React uses synthetic events system, with real DOM events delegated to the document root. It means that when you use something like <button onClick={this.handleClick}>Button</button> React attaches this event to document and uses event bubbling to handle it there.

If you understand how bubbling happens it's very easy to intercept such event. Just bind another handler before delegate target and stop propagation of event, so it never reaches target node, and hence never handled.

Basically, event will propagate to document node where it will be handled. You want to intercept event propagation at say root of your React application (for example, it might have id="root"):

document
   ↑
  HTML
   ↑
  BODY
   ↑
  DIV#root ← catch event at this level
   ↑
 BUTTON[class="my-button" onClick={...}]

So it could look like this:

// root is the root of your React application
const root = document.querySelector('#root') // or const root = document.body

root.addEventListener('click', (e) => {
  if (e.target.tagName === 'BUTTON' && e.target.className === 'my-button') {
    e.stopPropagation()
    location.href = 'http://stackoverflow.'
  }
})

Important part here is that you need to be able to identify even source, so that you catch events only from necessary nodes. In the example above I used some class which I know my button has, but it's up to you.

I have a custom React app built that is not easy for me to modify and repile. There is a div dom element that has some React mouse click events bound to it. I want to know if there is a way I can insert some javascript to intercept a click on this element and redirect the page to a different url. I tried calling removeEventListener on the object but I think React has a firm hold on this so to speak.

document.getElementsByClassName('close-builder')[0].addEventListener("click", function(){
    alert("test");
});

My event fires first (I think) but so do the ones I am trying to get rid of.

I have a custom React app built that is not easy for me to modify and repile. There is a div dom element that has some React mouse click events bound to it. I want to know if there is a way I can insert some javascript to intercept a click on this element and redirect the page to a different url. I tried calling removeEventListener on the object but I think React has a firm hold on this so to speak.

document.getElementsByClassName('close-builder')[0].addEventListener("click", function(){
    alert("test");
});

My event fires first (I think) but so do the ones I am trying to get rid of.

Share Improve this question edited Jun 8, 2018 at 14:43 Derek 朕會功夫 94.5k45 gold badges198 silver badges253 bronze badges asked Jun 7, 2018 at 22:34 Jason GordonJason Gordon 511 silver badge3 bronze badges 2
  • it's better when you add code of what you have at the moment to give you a good response and help you – xploshioOn Commented Jun 7, 2018 at 23:55
  • Yes, it's quite easy to do. What events do you want to intercept? Are they bound with onClick, etc? – dfsq Commented Jun 8, 2018 at 14:24
Add a ment  | 

1 Answer 1

Reset to default 4

Yes, this is quite easy to do. However you can't do it the way you tried. The reason is because React uses synthetic events system, with real DOM events delegated to the document root. It means that when you use something like <button onClick={this.handleClick}>Button</button> React attaches this event to document and uses event bubbling to handle it there.

If you understand how bubbling happens it's very easy to intercept such event. Just bind another handler before delegate target and stop propagation of event, so it never reaches target node, and hence never handled.

Basically, event will propagate to document node where it will be handled. You want to intercept event propagation at say root of your React application (for example, it might have id="root"):

document
   ↑
  HTML
   ↑
  BODY
   ↑
  DIV#root ← catch event at this level
   ↑
 BUTTON[class="my-button" onClick={...}]

So it could look like this:

// root is the root of your React application
const root = document.querySelector('#root') // or const root = document.body

root.addEventListener('click', (e) => {
  if (e.target.tagName === 'BUTTON' && e.target.className === 'my-button') {
    e.stopPropagation()
    location.href = 'http://stackoverflow.'
  }
})

Important part here is that you need to be able to identify even source, so that you catch events only from necessary nodes. In the example above I used some class which I know my button has, but it's up to you.

本文标签: javascriptIntercepting React Click EventsStack Overflow