• Jobs
  • Bootcamp
  • About Us
  • For professionals
    • Home
    • Jobs
    • Courses and challenges
    • Questions
    • Teachers
    • Bootcamp
  • For business
    • Home
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

167
Views
Shadowroot : Attaching jquery event handlers to multiple elements under shadowRoot

So I'm using a jQuery plugin under shadowRoot in my app. The HTML is as follows

#shadow-root
<div id="container">
   <div class="display-item">Item 1</div>
   <div class="display-item">Item 2</div>
   <div class="display-item">Item 3</div>
   <div class="display-item">Item 4</div>
</div>

I want to attach event listeners to the divs with class = "display-item" for events like mousedown,mousedown,focus. I tried the following:

let root = document.getElementById(divID).shadowRoot;
$(root).on('mousedown', '#container div.display-item', function(event) {
//function 
});

But this doesn't work. How could I make this work?

EDIT :

I also tried this approach, something like $('#container .display-item'), but it wouldn't work since it's looking for those elements under document I believe and it wouldn't find them since they're under the shadow DOM,so I have to use the root as pivot. Is there an equivalent of jquery 'find' method where I can query like multiple elements with the same class, using the shadow root as pivot? That way, I can attach event listeners to the individual elements explicitly.

9 months ago · Juan Pablo Isaza
1 answers
Answer question

0

In the ideal world Web Components should care about the "outside" world,
and most of all the Outside should not be dependent on Web Components inner world.

  • That means the Component should take care of attaching listeners.

  • Since you are in control what the Component does, there is no need for addEventListener (allowing for multiple same listeners)

customElements.define("my-component", class extends HTMLElement {
  constructor() {
    super().attachShadow({mode: "open"})
      .innerHTML = `<div id="container">
   <div class="display-item">Item 1</div>
   <div class="display-item">Item 2</div>
   <div class="display-item">Item 3</div>
   <div class="display-item">Item 4</div>
</div>`;
  }
  listen() {
    this.shadowRoot.querySelectorAll('.display-item').forEach(div => {
      div.onclick = (evt) => {
        document.body.append(div.innerText);
      }
    });
    this.listen = () => console.warn("ran attach listener once");
  }
})
<my-component id=COMP></my-component>

<script>
  window.onload=()=>{
    document.querySelector("#COMP").listen();
  }
</script>

Note: IE9 was the last browser to implement JS queryselectors... in 2011

If you are only using jQuery for its $(), you have burdened your clients with a not required 80KB+ download for the past 11 years.

If you really want to touch the Inside World

 document.querySelector("#COMP").shadowRoot.querySelectorAll('.display-item').forEach

does the trick, but breaks when there are more shadowRoots in between.

And in my world I don't tell Components what to do,
I make Components listen:

      window.onload=()=>{
        document.dispatchEvent("LISTEN");
      }
9 months ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post job Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2023 PeakU Inc. All Rights Reserved.