【问题标题】:Polymer 2.0 getElementById in different ShadowDomPolymer 2.0 getElementById 在不同的 ShadowDom
【发布时间】:2017-08-03 18:54:51
【问题描述】:

我正在尝试学习 Polymer 2.0,但遇到从不同 Shadow Dom 获取元素的问题。这在 Polymer 1 中有效,但在 Polymer 2.0 中不再有效。写这个的正确方法是什么?它只是告诉我targetText = Null

感谢您的帮助!

这是一个 MWE: 聚合物 WC 1:

<dom-module id="sc-navdrawer">
<template>
<style is="custom-style">
p {
  font-weight: bold;
}
.changed {
  color: red;
}
</style>
<p>Some text in normal p tag</p>
<div id="test" class="htmltextcontent" inner-h-t-m-l="{{inputText}}"></div>
</template>

<script>
    Polymer({
        is: 'sc-navdrawer',
        properties: {
          inputText: {
            type: String,
            value: "<p>Some innerhtml text in p tags</p>"
          }
        }
    });

</script>
</dom-module>

聚合物 WC 2:

<dom-module id="sc-testpage">
<template>

<button onclick="{{changeColor}}">Click here to change color</button>
</template>

<script>
    Polymer({
        is: 'sc-testpage',
        changeColor: function() {
          var targetText = document.getElementById("test");
          console.log(targetText);
          targetText.classList.add("changed");
        }
    });

</script>
</dom-module>

【问题讨论】:

  • 这两个元素是否相互关联?这意味着他们有一个孩子父母关系?

标签: javascript polymer-2.x


【解决方案1】:

我看到的第一件事是你使用document.getElementById("test");,如果你说这有效,你就使用了Shady Dom。
Polymer 2 强制您使用 Shadow Dom,因此该命令应替换为 Polymer.dom(this.root).querySelector("#test")。因为 Shadow Dom 封装了您的组件,所以您无法使用 document 对象访问其内容
但这不应该解决您的问题。这种封装意味着您无法访问 WebComponent 的内容,因此您无法从另一个组件访问具有 id:xyz 的元素。看看这些链接,他们将向您解释 shadowDom 的工作原理:
1.https://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/
2.https://developer.mozilla.org/en-US/docs/Web/Web_Components/Shadow_DOM
3.https://glazkov.com/2011/01/14/what-the-heck-is-shadow-dom/

【讨论】:

  • 谢谢。是的,这确实是问题所在。感谢您的链接;我会通读它们。我还注意到我也无法从同一个 WC 中访问该元素。
  • 谢谢。你让我走上正轨。我仍然必须习惯这一点,但我得到了它的工作!
  • Awesome Polymer 一开始很奇怪,但一旦你完全理解它就会变得非常强大;-)
【解决方案2】:

尝试使用纸张输入并设置它的值:

&lt;paper-input id="test" label="input" value="{{inputText}}"&gt;&lt;/paper-input&gt;

然后你可以像这样访问变量:

var targetText = this.$.inputText;

(这应该适用于纸张输入以外的其他元素)

【讨论】:

    【解决方案3】:
    1. 您应该使用Automatic node finding 而不是使用getElementById@ 如果您的两个元素彼此具有子父关系,则此方法有效。
    2. 我还认为,在 WC 2 中,您不应使用 onclick 按钮,而应使用 on-tap。这是 Polymer 文档中推荐的方式。

    3. 此外,我真的不明白您为什么在 onclick 属性上使用双向数据绑定。我可能遗漏了一些东西,但您的代码在正常的函数调用中应该可以正常工作。

      <dom-module id="sc-testpage">
         <template>
           <button on-tap="changeColor">Click here to change color</button>
         </template>
      
         <script>
           Polymer({
             is: 'sc-testpage',
      
             changeColor: function() {
               var targetText = this.$.sc-navdrawer.$.test;
               console.log(targetText);
               targetText.classList.add("changed");
             }
           });
      
          </script>
      </dom-module>
      

    【讨论】:

    • 感谢您的回答。确实,2路绑定不是必需的,也不是onclick,但我做了一个非常快速的MWE来显示问题。我尝试了你的建议,但没有奏效:不是两个元素都具有相同的父级,也不是 sc-navdrawer 是 sc-testpage 的父级,反之亦然。此外,我认为在您的代码中,它必须改为 this.$.scNavdrawer.$.test 吗?在任何情况下,它总是将 targetText 返回为 Null。我认为这在 Polymer 2 中发生了变化。
    • 实际上第 1 点是错误的,至少关于孩子父母的事情是错误的。这仅适用于 Polymer 1 和 shady dom。
    猜你喜欢
    • 2014-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-28
    • 2018-11-09
    相关资源
    最近更新 更多