ShadowDOM v1 - Input text changed in lightdom











up vote
2
down vote

favorite
1












I am trying to listen for text changes in a custom component



<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript" src="component.js"></script>
</head>
<body>
<fancy-p>
<p>Bar</p>
<!-- the input should be listened to -->
<input id="foo" type="text" name="text" placeholder="Hello"></input>
</fancy-p>
</body>
</html>


component.js



customElements.define('fancy-p', class extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'});
}
get foo() {
return "foo"
}
connectedCallback() {
this.shadowRoot.innerHTML = `
<style>
p {
color: red;
}
:host {
background-color: blue;
}
</style>
<div data-foo="bar">
<slot></slot>
</div>
`;

let input = this.querySelector("input");
console.log("input is:" + input);
}
});


I tried to listen for text changes and use a querySelector in connectedCallback but in Chrome 70.xx the selector returns null.



It seems like when I set a breakpoint that the lightDOM is not filled (i.e. the slot) but then I don't know how to add a event listener to the input.



How can I do that???










share|improve this question


























    up vote
    2
    down vote

    favorite
    1












    I am trying to listen for text changes in a custom component



    <!DOCTYPE html>
    <html lang="en" dir="ltr">
    <head>
    <meta charset="utf-8">
    <title></title>
    <script type="text/javascript" src="component.js"></script>
    </head>
    <body>
    <fancy-p>
    <p>Bar</p>
    <!-- the input should be listened to -->
    <input id="foo" type="text" name="text" placeholder="Hello"></input>
    </fancy-p>
    </body>
    </html>


    component.js



    customElements.define('fancy-p', class extends HTMLElement {
    constructor() {
    super();
    this.attachShadow({mode: 'open'});
    }
    get foo() {
    return "foo"
    }
    connectedCallback() {
    this.shadowRoot.innerHTML = `
    <style>
    p {
    color: red;
    }
    :host {
    background-color: blue;
    }
    </style>
    <div data-foo="bar">
    <slot></slot>
    </div>
    `;

    let input = this.querySelector("input");
    console.log("input is:" + input);
    }
    });


    I tried to listen for text changes and use a querySelector in connectedCallback but in Chrome 70.xx the selector returns null.



    It seems like when I set a breakpoint that the lightDOM is not filled (i.e. the slot) but then I don't know how to add a event listener to the input.



    How can I do that???










    share|improve this question
























      up vote
      2
      down vote

      favorite
      1









      up vote
      2
      down vote

      favorite
      1






      1





      I am trying to listen for text changes in a custom component



      <!DOCTYPE html>
      <html lang="en" dir="ltr">
      <head>
      <meta charset="utf-8">
      <title></title>
      <script type="text/javascript" src="component.js"></script>
      </head>
      <body>
      <fancy-p>
      <p>Bar</p>
      <!-- the input should be listened to -->
      <input id="foo" type="text" name="text" placeholder="Hello"></input>
      </fancy-p>
      </body>
      </html>


      component.js



      customElements.define('fancy-p', class extends HTMLElement {
      constructor() {
      super();
      this.attachShadow({mode: 'open'});
      }
      get foo() {
      return "foo"
      }
      connectedCallback() {
      this.shadowRoot.innerHTML = `
      <style>
      p {
      color: red;
      }
      :host {
      background-color: blue;
      }
      </style>
      <div data-foo="bar">
      <slot></slot>
      </div>
      `;

      let input = this.querySelector("input");
      console.log("input is:" + input);
      }
      });


      I tried to listen for text changes and use a querySelector in connectedCallback but in Chrome 70.xx the selector returns null.



      It seems like when I set a breakpoint that the lightDOM is not filled (i.e. the slot) but then I don't know how to add a event listener to the input.



      How can I do that???










      share|improve this question













      I am trying to listen for text changes in a custom component



      <!DOCTYPE html>
      <html lang="en" dir="ltr">
      <head>
      <meta charset="utf-8">
      <title></title>
      <script type="text/javascript" src="component.js"></script>
      </head>
      <body>
      <fancy-p>
      <p>Bar</p>
      <!-- the input should be listened to -->
      <input id="foo" type="text" name="text" placeholder="Hello"></input>
      </fancy-p>
      </body>
      </html>


      component.js



      customElements.define('fancy-p', class extends HTMLElement {
      constructor() {
      super();
      this.attachShadow({mode: 'open'});
      }
      get foo() {
      return "foo"
      }
      connectedCallback() {
      this.shadowRoot.innerHTML = `
      <style>
      p {
      color: red;
      }
      :host {
      background-color: blue;
      }
      </style>
      <div data-foo="bar">
      <slot></slot>
      </div>
      `;

      let input = this.querySelector("input");
      console.log("input is:" + input);
      }
      });


      I tried to listen for text changes and use a querySelector in connectedCallback but in Chrome 70.xx the selector returns null.



      It seems like when I set a breakpoint that the lightDOM is not filled (i.e. the slot) but then I don't know how to add a event listener to the input.



      How can I do that???







      javascript html shadow-dom






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 19 at 20:42









      bnassler

      159211




      159211
























          2 Answers
          2






          active

          oldest

          votes

















          up vote
          1
          down vote



          accepted










          When the connectedCallback() method is called, the <input> element is not appended to the light DOM yet. So you cannot get it with this.querySelector('input') at that time.



          It's not really a problem: you can listen to the {input} event on the Custom Element itself, because the event will bubble to the parent element.



          this.addEventListener( 'input', ev => console.log( ev.target, ev.target.value ) )  


          See the running example:






          customElements.define('fancy-p', class extends HTMLElement {
          constructor() {
          super()
          this.attachShadow({mode: 'open'})
          .innerHTML = `
          <style>
          ::slotted(p) { color: red; }
          :host { display:inline-block; background-color: blue; }
          </style>
          <div data-foo="bar">
          <slot></slot>
          </div>`
          this.addEventListener('input', ev => console.log( '%s value is %s', ev.target, ev.target.value))
          }
          })

          <fancy-p>
          <p>Bar</p>
          <input id="foo" type="text" name="text" placeholder="Hello">
          </fancy-p>








          share|improve this answer





















          • That was what I was looking for thanks!
            – bnassler
            Nov 20 at 19:01


















          up vote
          2
          down vote













          In your example the <input> is placed into a <slot> which means that the code outside of the custom element owns the <input> tag.



          In the code below you see that I am using document.querySelector outside of the custom element to get the <input> element and not using this.querySelector or this.shadowRoot.querySelector inside of the custom element code.






          customElements.define('fancy-p', class extends HTMLElement {
          constructor() {
          super();
          this.attachShadow({mode: 'open'});
          }
          get foo() {
          return "foo"
          }
          connectedCallback() {
          this.shadowRoot.innerHTML = `
          <style>
          p {
          color: red;
          }
          :host {
          background-color: blue;
          }
          </style>
          <div data-foo="bar">
          <slot></slot>
          </div>
          `;
          let input = this.shadowRoot.querySelector("input");
          console.log('inside input=',input); // input will be null
          }
          });


          //Since the `<input>` tag is *owned* by the outside DOM you need to get the events from the outside:


          let input = document.querySelector("input");
          console.log('outside input=', input);
          input.addEventListener('input', () => {
          console.log("input is:" + input.value);
          });

          <fancy-p>
          <p>Bar</p>
          <input id="foo" type="text" name="text" placeholder="Hello"/></fancy-p>





          If you want to access it through the shadowDOM then you need to define it in the shadowDOM:






          customElements.define('fancy-p', class extends HTMLElement {
          constructor() {
          super();
          this.attachShadow({mode: 'open'});
          }
          get foo() {
          return "foo"
          }
          connectedCallback() {
          this.shadowRoot.innerHTML = `
          <style>
          p {
          color: red;
          }
          :host {
          background-color: blue;
          }
          </style>
          <div data-foo="bar">
          <slot></slot>
          <input id="foo" type="text" name="text" placeholder="Hello">
          </div>
          `;

          let input = this.shadowRoot.querySelector("input");
          console.log('inside input=',input);
          input.addEventListener('input', () => {
          console.log("input is:" + input.value);
          });
          }
          });

          <fancy-p>
          <p>Bar</p>
          </fancy-p>








          share|improve this answer























          • Thanks for the explanation! In my case I want to insert the input in the Light DOM so I cannot move it to the Shadow DOM
            – bnassler
            Nov 20 at 19:01











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53382342%2fshadowdom-v1-input-text-changed-in-lightdom%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          1
          down vote



          accepted










          When the connectedCallback() method is called, the <input> element is not appended to the light DOM yet. So you cannot get it with this.querySelector('input') at that time.



          It's not really a problem: you can listen to the {input} event on the Custom Element itself, because the event will bubble to the parent element.



          this.addEventListener( 'input', ev => console.log( ev.target, ev.target.value ) )  


          See the running example:






          customElements.define('fancy-p', class extends HTMLElement {
          constructor() {
          super()
          this.attachShadow({mode: 'open'})
          .innerHTML = `
          <style>
          ::slotted(p) { color: red; }
          :host { display:inline-block; background-color: blue; }
          </style>
          <div data-foo="bar">
          <slot></slot>
          </div>`
          this.addEventListener('input', ev => console.log( '%s value is %s', ev.target, ev.target.value))
          }
          })

          <fancy-p>
          <p>Bar</p>
          <input id="foo" type="text" name="text" placeholder="Hello">
          </fancy-p>








          share|improve this answer





















          • That was what I was looking for thanks!
            – bnassler
            Nov 20 at 19:01















          up vote
          1
          down vote



          accepted










          When the connectedCallback() method is called, the <input> element is not appended to the light DOM yet. So you cannot get it with this.querySelector('input') at that time.



          It's not really a problem: you can listen to the {input} event on the Custom Element itself, because the event will bubble to the parent element.



          this.addEventListener( 'input', ev => console.log( ev.target, ev.target.value ) )  


          See the running example:






          customElements.define('fancy-p', class extends HTMLElement {
          constructor() {
          super()
          this.attachShadow({mode: 'open'})
          .innerHTML = `
          <style>
          ::slotted(p) { color: red; }
          :host { display:inline-block; background-color: blue; }
          </style>
          <div data-foo="bar">
          <slot></slot>
          </div>`
          this.addEventListener('input', ev => console.log( '%s value is %s', ev.target, ev.target.value))
          }
          })

          <fancy-p>
          <p>Bar</p>
          <input id="foo" type="text" name="text" placeholder="Hello">
          </fancy-p>








          share|improve this answer





















          • That was what I was looking for thanks!
            – bnassler
            Nov 20 at 19:01













          up vote
          1
          down vote



          accepted







          up vote
          1
          down vote



          accepted






          When the connectedCallback() method is called, the <input> element is not appended to the light DOM yet. So you cannot get it with this.querySelector('input') at that time.



          It's not really a problem: you can listen to the {input} event on the Custom Element itself, because the event will bubble to the parent element.



          this.addEventListener( 'input', ev => console.log( ev.target, ev.target.value ) )  


          See the running example:






          customElements.define('fancy-p', class extends HTMLElement {
          constructor() {
          super()
          this.attachShadow({mode: 'open'})
          .innerHTML = `
          <style>
          ::slotted(p) { color: red; }
          :host { display:inline-block; background-color: blue; }
          </style>
          <div data-foo="bar">
          <slot></slot>
          </div>`
          this.addEventListener('input', ev => console.log( '%s value is %s', ev.target, ev.target.value))
          }
          })

          <fancy-p>
          <p>Bar</p>
          <input id="foo" type="text" name="text" placeholder="Hello">
          </fancy-p>








          share|improve this answer












          When the connectedCallback() method is called, the <input> element is not appended to the light DOM yet. So you cannot get it with this.querySelector('input') at that time.



          It's not really a problem: you can listen to the {input} event on the Custom Element itself, because the event will bubble to the parent element.



          this.addEventListener( 'input', ev => console.log( ev.target, ev.target.value ) )  


          See the running example:






          customElements.define('fancy-p', class extends HTMLElement {
          constructor() {
          super()
          this.attachShadow({mode: 'open'})
          .innerHTML = `
          <style>
          ::slotted(p) { color: red; }
          :host { display:inline-block; background-color: blue; }
          </style>
          <div data-foo="bar">
          <slot></slot>
          </div>`
          this.addEventListener('input', ev => console.log( '%s value is %s', ev.target, ev.target.value))
          }
          })

          <fancy-p>
          <p>Bar</p>
          <input id="foo" type="text" name="text" placeholder="Hello">
          </fancy-p>








          customElements.define('fancy-p', class extends HTMLElement {
          constructor() {
          super()
          this.attachShadow({mode: 'open'})
          .innerHTML = `
          <style>
          ::slotted(p) { color: red; }
          :host { display:inline-block; background-color: blue; }
          </style>
          <div data-foo="bar">
          <slot></slot>
          </div>`
          this.addEventListener('input', ev => console.log( '%s value is %s', ev.target, ev.target.value))
          }
          })

          <fancy-p>
          <p>Bar</p>
          <input id="foo" type="text" name="text" placeholder="Hello">
          </fancy-p>





          customElements.define('fancy-p', class extends HTMLElement {
          constructor() {
          super()
          this.attachShadow({mode: 'open'})
          .innerHTML = `
          <style>
          ::slotted(p) { color: red; }
          :host { display:inline-block; background-color: blue; }
          </style>
          <div data-foo="bar">
          <slot></slot>
          </div>`
          this.addEventListener('input', ev => console.log( '%s value is %s', ev.target, ev.target.value))
          }
          })

          <fancy-p>
          <p>Bar</p>
          <input id="foo" type="text" name="text" placeholder="Hello">
          </fancy-p>






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 20 at 10:30









          Supersharp

          12.7k22868




          12.7k22868












          • That was what I was looking for thanks!
            – bnassler
            Nov 20 at 19:01


















          • That was what I was looking for thanks!
            – bnassler
            Nov 20 at 19:01
















          That was what I was looking for thanks!
          – bnassler
          Nov 20 at 19:01




          That was what I was looking for thanks!
          – bnassler
          Nov 20 at 19:01












          up vote
          2
          down vote













          In your example the <input> is placed into a <slot> which means that the code outside of the custom element owns the <input> tag.



          In the code below you see that I am using document.querySelector outside of the custom element to get the <input> element and not using this.querySelector or this.shadowRoot.querySelector inside of the custom element code.






          customElements.define('fancy-p', class extends HTMLElement {
          constructor() {
          super();
          this.attachShadow({mode: 'open'});
          }
          get foo() {
          return "foo"
          }
          connectedCallback() {
          this.shadowRoot.innerHTML = `
          <style>
          p {
          color: red;
          }
          :host {
          background-color: blue;
          }
          </style>
          <div data-foo="bar">
          <slot></slot>
          </div>
          `;
          let input = this.shadowRoot.querySelector("input");
          console.log('inside input=',input); // input will be null
          }
          });


          //Since the `<input>` tag is *owned* by the outside DOM you need to get the events from the outside:


          let input = document.querySelector("input");
          console.log('outside input=', input);
          input.addEventListener('input', () => {
          console.log("input is:" + input.value);
          });

          <fancy-p>
          <p>Bar</p>
          <input id="foo" type="text" name="text" placeholder="Hello"/></fancy-p>





          If you want to access it through the shadowDOM then you need to define it in the shadowDOM:






          customElements.define('fancy-p', class extends HTMLElement {
          constructor() {
          super();
          this.attachShadow({mode: 'open'});
          }
          get foo() {
          return "foo"
          }
          connectedCallback() {
          this.shadowRoot.innerHTML = `
          <style>
          p {
          color: red;
          }
          :host {
          background-color: blue;
          }
          </style>
          <div data-foo="bar">
          <slot></slot>
          <input id="foo" type="text" name="text" placeholder="Hello">
          </div>
          `;

          let input = this.shadowRoot.querySelector("input");
          console.log('inside input=',input);
          input.addEventListener('input', () => {
          console.log("input is:" + input.value);
          });
          }
          });

          <fancy-p>
          <p>Bar</p>
          </fancy-p>








          share|improve this answer























          • Thanks for the explanation! In my case I want to insert the input in the Light DOM so I cannot move it to the Shadow DOM
            – bnassler
            Nov 20 at 19:01















          up vote
          2
          down vote













          In your example the <input> is placed into a <slot> which means that the code outside of the custom element owns the <input> tag.



          In the code below you see that I am using document.querySelector outside of the custom element to get the <input> element and not using this.querySelector or this.shadowRoot.querySelector inside of the custom element code.






          customElements.define('fancy-p', class extends HTMLElement {
          constructor() {
          super();
          this.attachShadow({mode: 'open'});
          }
          get foo() {
          return "foo"
          }
          connectedCallback() {
          this.shadowRoot.innerHTML = `
          <style>
          p {
          color: red;
          }
          :host {
          background-color: blue;
          }
          </style>
          <div data-foo="bar">
          <slot></slot>
          </div>
          `;
          let input = this.shadowRoot.querySelector("input");
          console.log('inside input=',input); // input will be null
          }
          });


          //Since the `<input>` tag is *owned* by the outside DOM you need to get the events from the outside:


          let input = document.querySelector("input");
          console.log('outside input=', input);
          input.addEventListener('input', () => {
          console.log("input is:" + input.value);
          });

          <fancy-p>
          <p>Bar</p>
          <input id="foo" type="text" name="text" placeholder="Hello"/></fancy-p>





          If you want to access it through the shadowDOM then you need to define it in the shadowDOM:






          customElements.define('fancy-p', class extends HTMLElement {
          constructor() {
          super();
          this.attachShadow({mode: 'open'});
          }
          get foo() {
          return "foo"
          }
          connectedCallback() {
          this.shadowRoot.innerHTML = `
          <style>
          p {
          color: red;
          }
          :host {
          background-color: blue;
          }
          </style>
          <div data-foo="bar">
          <slot></slot>
          <input id="foo" type="text" name="text" placeholder="Hello">
          </div>
          `;

          let input = this.shadowRoot.querySelector("input");
          console.log('inside input=',input);
          input.addEventListener('input', () => {
          console.log("input is:" + input.value);
          });
          }
          });

          <fancy-p>
          <p>Bar</p>
          </fancy-p>








          share|improve this answer























          • Thanks for the explanation! In my case I want to insert the input in the Light DOM so I cannot move it to the Shadow DOM
            – bnassler
            Nov 20 at 19:01













          up vote
          2
          down vote










          up vote
          2
          down vote









          In your example the <input> is placed into a <slot> which means that the code outside of the custom element owns the <input> tag.



          In the code below you see that I am using document.querySelector outside of the custom element to get the <input> element and not using this.querySelector or this.shadowRoot.querySelector inside of the custom element code.






          customElements.define('fancy-p', class extends HTMLElement {
          constructor() {
          super();
          this.attachShadow({mode: 'open'});
          }
          get foo() {
          return "foo"
          }
          connectedCallback() {
          this.shadowRoot.innerHTML = `
          <style>
          p {
          color: red;
          }
          :host {
          background-color: blue;
          }
          </style>
          <div data-foo="bar">
          <slot></slot>
          </div>
          `;
          let input = this.shadowRoot.querySelector("input");
          console.log('inside input=',input); // input will be null
          }
          });


          //Since the `<input>` tag is *owned* by the outside DOM you need to get the events from the outside:


          let input = document.querySelector("input");
          console.log('outside input=', input);
          input.addEventListener('input', () => {
          console.log("input is:" + input.value);
          });

          <fancy-p>
          <p>Bar</p>
          <input id="foo" type="text" name="text" placeholder="Hello"/></fancy-p>





          If you want to access it through the shadowDOM then you need to define it in the shadowDOM:






          customElements.define('fancy-p', class extends HTMLElement {
          constructor() {
          super();
          this.attachShadow({mode: 'open'});
          }
          get foo() {
          return "foo"
          }
          connectedCallback() {
          this.shadowRoot.innerHTML = `
          <style>
          p {
          color: red;
          }
          :host {
          background-color: blue;
          }
          </style>
          <div data-foo="bar">
          <slot></slot>
          <input id="foo" type="text" name="text" placeholder="Hello">
          </div>
          `;

          let input = this.shadowRoot.querySelector("input");
          console.log('inside input=',input);
          input.addEventListener('input', () => {
          console.log("input is:" + input.value);
          });
          }
          });

          <fancy-p>
          <p>Bar</p>
          </fancy-p>








          share|improve this answer














          In your example the <input> is placed into a <slot> which means that the code outside of the custom element owns the <input> tag.



          In the code below you see that I am using document.querySelector outside of the custom element to get the <input> element and not using this.querySelector or this.shadowRoot.querySelector inside of the custom element code.






          customElements.define('fancy-p', class extends HTMLElement {
          constructor() {
          super();
          this.attachShadow({mode: 'open'});
          }
          get foo() {
          return "foo"
          }
          connectedCallback() {
          this.shadowRoot.innerHTML = `
          <style>
          p {
          color: red;
          }
          :host {
          background-color: blue;
          }
          </style>
          <div data-foo="bar">
          <slot></slot>
          </div>
          `;
          let input = this.shadowRoot.querySelector("input");
          console.log('inside input=',input); // input will be null
          }
          });


          //Since the `<input>` tag is *owned* by the outside DOM you need to get the events from the outside:


          let input = document.querySelector("input");
          console.log('outside input=', input);
          input.addEventListener('input', () => {
          console.log("input is:" + input.value);
          });

          <fancy-p>
          <p>Bar</p>
          <input id="foo" type="text" name="text" placeholder="Hello"/></fancy-p>





          If you want to access it through the shadowDOM then you need to define it in the shadowDOM:






          customElements.define('fancy-p', class extends HTMLElement {
          constructor() {
          super();
          this.attachShadow({mode: 'open'});
          }
          get foo() {
          return "foo"
          }
          connectedCallback() {
          this.shadowRoot.innerHTML = `
          <style>
          p {
          color: red;
          }
          :host {
          background-color: blue;
          }
          </style>
          <div data-foo="bar">
          <slot></slot>
          <input id="foo" type="text" name="text" placeholder="Hello">
          </div>
          `;

          let input = this.shadowRoot.querySelector("input");
          console.log('inside input=',input);
          input.addEventListener('input', () => {
          console.log("input is:" + input.value);
          });
          }
          });

          <fancy-p>
          <p>Bar</p>
          </fancy-p>








          customElements.define('fancy-p', class extends HTMLElement {
          constructor() {
          super();
          this.attachShadow({mode: 'open'});
          }
          get foo() {
          return "foo"
          }
          connectedCallback() {
          this.shadowRoot.innerHTML = `
          <style>
          p {
          color: red;
          }
          :host {
          background-color: blue;
          }
          </style>
          <div data-foo="bar">
          <slot></slot>
          </div>
          `;
          let input = this.shadowRoot.querySelector("input");
          console.log('inside input=',input); // input will be null
          }
          });


          //Since the `<input>` tag is *owned* by the outside DOM you need to get the events from the outside:


          let input = document.querySelector("input");
          console.log('outside input=', input);
          input.addEventListener('input', () => {
          console.log("input is:" + input.value);
          });

          <fancy-p>
          <p>Bar</p>
          <input id="foo" type="text" name="text" placeholder="Hello"/></fancy-p>





          customElements.define('fancy-p', class extends HTMLElement {
          constructor() {
          super();
          this.attachShadow({mode: 'open'});
          }
          get foo() {
          return "foo"
          }
          connectedCallback() {
          this.shadowRoot.innerHTML = `
          <style>
          p {
          color: red;
          }
          :host {
          background-color: blue;
          }
          </style>
          <div data-foo="bar">
          <slot></slot>
          </div>
          `;
          let input = this.shadowRoot.querySelector("input");
          console.log('inside input=',input); // input will be null
          }
          });


          //Since the `<input>` tag is *owned* by the outside DOM you need to get the events from the outside:


          let input = document.querySelector("input");
          console.log('outside input=', input);
          input.addEventListener('input', () => {
          console.log("input is:" + input.value);
          });

          <fancy-p>
          <p>Bar</p>
          <input id="foo" type="text" name="text" placeholder="Hello"/></fancy-p>





          customElements.define('fancy-p', class extends HTMLElement {
          constructor() {
          super();
          this.attachShadow({mode: 'open'});
          }
          get foo() {
          return "foo"
          }
          connectedCallback() {
          this.shadowRoot.innerHTML = `
          <style>
          p {
          color: red;
          }
          :host {
          background-color: blue;
          }
          </style>
          <div data-foo="bar">
          <slot></slot>
          <input id="foo" type="text" name="text" placeholder="Hello">
          </div>
          `;

          let input = this.shadowRoot.querySelector("input");
          console.log('inside input=',input);
          input.addEventListener('input', () => {
          console.log("input is:" + input.value);
          });
          }
          });

          <fancy-p>
          <p>Bar</p>
          </fancy-p>





          customElements.define('fancy-p', class extends HTMLElement {
          constructor() {
          super();
          this.attachShadow({mode: 'open'});
          }
          get foo() {
          return "foo"
          }
          connectedCallback() {
          this.shadowRoot.innerHTML = `
          <style>
          p {
          color: red;
          }
          :host {
          background-color: blue;
          }
          </style>
          <div data-foo="bar">
          <slot></slot>
          <input id="foo" type="text" name="text" placeholder="Hello">
          </div>
          `;

          let input = this.shadowRoot.querySelector("input");
          console.log('inside input=',input);
          input.addEventListener('input', () => {
          console.log("input is:" + input.value);
          });
          }
          });

          <fancy-p>
          <p>Bar</p>
          </fancy-p>






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 20 at 0:02

























          answered Nov 19 at 23:56









          Intervalia

          3,97211031




          3,97211031












          • Thanks for the explanation! In my case I want to insert the input in the Light DOM so I cannot move it to the Shadow DOM
            – bnassler
            Nov 20 at 19:01


















          • Thanks for the explanation! In my case I want to insert the input in the Light DOM so I cannot move it to the Shadow DOM
            – bnassler
            Nov 20 at 19:01
















          Thanks for the explanation! In my case I want to insert the input in the Light DOM so I cannot move it to the Shadow DOM
          – bnassler
          Nov 20 at 19:01




          Thanks for the explanation! In my case I want to insert the input in the Light DOM so I cannot move it to the Shadow DOM
          – bnassler
          Nov 20 at 19:01


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53382342%2fshadowdom-v1-input-text-changed-in-lightdom%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          If I really need a card on my start hand, how many mulligans make sense? [duplicate]

          Alcedinidae

          Can an atomic nucleus contain both particles and antiparticles? [duplicate]