【问题标题】:Can I access the shadow DOM using jQuery?我可以使用 jQuery 访问影子 DOM 吗?
【发布时间】:2014-02-08 17:29:49
【问题描述】:

我用这样的聚合物定义了一个组件:

<polymer-element name="my-component">
  <template>
    <div id='test'>CONTENT</div>
  </template>
</polymer-element>

现在我要访问shadow dom,例如:获取div id='test'的内容

var x = $("div#test").html();

给定的代码不起作用。 我可以用 jquery 访问 shadow dom 吗?

【问题讨论】:

    标签: javascript jquery dom polymer shadow-dom


    【解决方案1】:

    因为它最终是我使用的,所以值得将它放入答案列表中。

    // following line assumes shadow content has only one <body> tag... 
    // ...otherwise filter by whatever makes sense for your code
    
    var $shadowBody = $($("#shadow-root-elem")[0].shadowRoot.childNodes).filter("body");
    
    // get the elem in the shadow content that I need/want
    
    var $elemInShadowBody = $shadowBody.find(".selector.for.elem.in.shadow.body")
    

    【讨论】:

      【解决方案2】:

      这对我有用

      $(element)[0].shadowRoot

      【讨论】:

        【解决方案3】:

        你可以这样做:

        $("#example", this.shadowRoot).DataTable();
        

        【讨论】:

          【解决方案4】:

          这是我在 shadow-root 中更改验证码的简单功能

          const get_captcha = (CustomElement)=>{
          	var src = `./app/create_captcha/${chance.natural()}`;
          	var rootElement = $(CustomElement)[0].shadowRoot;
          	var captchaElement = $(rootElement).find('#img_captcha');
          	$(captchaElement).attr('src',src);
          };

          【讨论】:

            【解决方案5】:

            使用这样的东西:

            jQuery.fn.extend({
              shadowRoot: function() {
                 return $(this.get(0).shadowRoot);
              },
            });
            

            然后调用:

            $("my-element").shadowRoot());
            

            【讨论】:

              【解决方案6】:

              我可以像这样访问 Chrome 中的 shadowRoot 元素:

              $("#idOfElementInShadowRoot", $("#idOfShadowRootElement").shadowRoot)
              

              Jquery: How to select only within a selection?得到这个想法

              【讨论】:

              • $("#idOfShadowRootElement") 之后需要一个[0],因为.shadowRoot 在DOM 对象上而不是在jQuery 对象上。所以像这样:$("#idOfElementInShadowRoot", $("#idOfShadowRootElement")[0].shadowRoot)
              • 必须使用attachShadow 的“打开”模式才能正常工作。 “封闭”模式会给你null。否则一个很好的答案,谢谢!
              【解决方案7】:

              您可以使用$('body /deep/ your-selector') 模式穿透shadow DOM 并让Jquery 在其中工作。

              更新:到目前为止,我只设法在桌面版 chrome 上完成这项工作。我相信,其他浏览器不支持 /deep/ 组合器。

              更新 2/deep/ 组合器已弃用,不应再使用。它计划从 Chrome 中删除。

              【讨论】:

              【解决方案8】:

              我在 TypeScript 中写了一个简单的助手来解决这个问题:

              class DomUtils {
              
                  public static getShadowElementById(id: string):any {
              
                      try {
                          // Try to get it by simple id in case of browser doesn't support shadow DOM
                          var element = $("#" + id);
              
                          if (element.length <= 0) {
                              // Support Chrome browser
                              element = $("body /deep/ #" + id);
                          }
              
                          return element;
              
                      } catch (error) {
                          console.log("Error: " + error + ", while trying to get shadow element with id: " + id);
                          return null;
                      }
                  }
              } 
              

              用法:

              var element = DomUtils.getShadowElementById('mainContainer');
              

              在桌面 Chrome、Internet Explorer、Firefox 上测试

              【讨论】:

                【解决方案9】:

                我认为这对我有用...

                $('polymer-element::shadow #test')
                

                虽然只在 chrome 上测试过

                【讨论】:

                【解决方案10】:

                不,不在 Polymer 元素之外。

                阅读 Polymer 后,您似乎只能在 Polymer 元素内的脚本中访问 Polymer 元素的 shadow-DOM。 Automatic node finding 上的 Polymer 文档说:

                组件的影子 DOM 中每个带有 id 属性标记的节点都会自动在组件的 this.$ 哈希中引用。

                这意味着您可以添加一个&lt;script&gt; 标记作为&lt;template&gt; 的同级标记,其中this.$.test 将是您想要的元素。

                <polymer-element name="my-component">
                  <template>
                    <div id='test'>CONTENT</div>
                  </template>
                  <script>
                    Polymer('my-component', {
                        logNameValue: function () {
                            console.log('polymer element', this.$.test);
                            console.log('jQuery wrapper of polymer element', $(this.$.test));
                        }
                    });
                  </script>
                </polymer-element>
                

                【讨论】:

                • 0.5 的答案很好,但我不确定这是否仍然是 1.0 中的做法。
                • 我的问题与聚合物无关,但我发现这个答案很有帮助。 stackoverflow.com/a/58417950/897326
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2014-01-08
                • 2011-12-15
                • 2013-02-02
                • 1970-01-01
                • 2010-12-02
                • 1970-01-01
                • 2021-06-15
                相关资源
                最近更新 更多