MPK
MPK

Reputation: 247

Both click() and dispatchEvent does not trigger automatic click in reactjs

I have a react component that has an SVG image. I have divided the SVG into multiple react box. I have query selector which selects all the react box and JS click event to auto click that react.

I tried working with both click and dispatch event. But none of them works in my scenario.

Below is the section of the code I am working on.

componentDidMount() {
    var element =  document.querySelectorAll("square");
    for(var i = 0; i<element.length; i++) {
      element[i].dispatchEvent(new Event('click'));
    }
}

render(){
    return (
      <React.Fragment>
        <div className="col-12">
          <svg  viewBox="0 0 100 100">
            <image xlinkHref={imageFile}  height="100%" width="100%" />
            <g><rect className="square" x="10" y="10" width="20" height="10" fillOpacity=".2"  onClick={() =>console.log("clicked")}></rect> </g>         
            <g><rect className="square" x="30" y="10" width="20" height="10" fillOpacity=".4"  onClick={() =>console.log("clicked")}></rect> </g>              
          </svg>
        </div>
      </React.Fragment>
    )
  

}

I also tried using the click() function and did not work for SVG images and also is there a way we could automate a click in each square every 10 seconds?

Upvotes: 1

Views: 1961

Answers (1)

Guerric P
Guerric P

Reputation: 31805

You forgot a . in the query selector so the node list was actually empty.

If you want to automate a click in each square every 10 seconds, this code does the trick:

const elements = document.querySelectorAll(".square");

const intervalsIdentifiers = Array.from(elements).map(x => setInterval(() => x.dispatchEvent(new Event('click')), 10000));

The dispatchEvent method is indeed the only way, because the rect element doesn't have a click method (only HTML elements do, not SVG elements) as demonstrated below:

console.log('click' in SVGRectElement.prototype); // false

console.log(HTMLElement.prototype.hasOwnProperty('click')); // true

console.log(HTMLButtonElement.prototype instanceof HTMLElement); // true (a button has the click method)
console.log(SVGRectElement.prototype instanceof HTMLElement); // false

The full working code (native JavaScript but should work as well with React in the componentDidMount hook):

const elements = document.querySelectorAll(".square");

const intervalsIdentifiers = Array.from(elements).map(x => setInterval(() => x.dispatchEvent(new Event('click')), 10000));
<div className="col-12">
  <svg  viewBox="0 0 100 100">
    <image xlink:Href="https://img-19.ccm2.net/8vUCl8TXZfwTt7zAOkBkuDRHiT8=/1240x/smart/b829396acc244fd484c5ddcdcb2b08f3/ccmcms-commentcamarche/20494859.jpg"  height="100%" width="100%" />
    <g><rect class="square" x="10" y="10" width="20" height="10" fillOpacity=".2"  onclick="console.log('clicked')"></rect> </g>         
    <g><rect class="square" x="30" y="10" width="20" height="10" fillOpacity=".4"  onclick="console.log('clicked')"></rect> </g>              
  </svg>
</div>

Upvotes: 3

Related Questions