javascript - Polymer focus() 必须包含在 setTimeout() 中才能工作?

标签 javascript polymer polymer-1.0

当试图将焦点放在一个 polymer 元素上时,我总是必须将它包装在一个 setTimout 中,在本例中它是一个 polymer paper-input 元素。像这样:

setTimeout(function() {
   paperInput.focus(); 
}, 10);

我阅读了关于主题 focus() polymer 元素的不同 Stackoverflow 帖子,我发现其中一些帖子有同样的问题。 我真的无法接受这样一个事实,即它在我包裹它时才起作用我想知道为什么当我不包裹它时它不起作用。

所以我的问题是,为什么?为什么我必须将它包装在 setTimeout 中?

目前使用 Polymer 1.4。但我注意到旧版本中存在相同的行为。

谢谢!

更新

我已尝试重现该问题,但这确实有效。所以我敢打赌问题出在我自己的环境中:jsbin

如果我找到问题的解决方案,我会及时更新这篇文章。 感谢您的帮助。

最佳答案

在简单的情况下,页面上除了 <paper-input> 之外没有其他元素。 ,focus()似乎没有问题.

<head>
  <base href="https://polygit.org/polymer+1.4.0/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link rel="import" href="paper-input/paper-input.html">
</head>
<body>
  <paper-input></paper-input>
  <paper-input></paper-input>
  <paper-input id="my-input"></paper-input>
  <paper-input></paper-input>

  <script>
    HTMLImports.whenReady(function() {
      document.getElementById('my-input').focus();
    });
  </script>
</body>

jsbin

但我可以在稍微复杂一点的情况下重现该问题,其中 <paper-input>在里面<iron-pages> .在以下示例中,第三个 <paper-input>第 2 页上的内容应该是重点。

<head>
  <base href="https://polygit.org/polymer+1.4.0/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link rel="import" href="paper-input/paper-input.html">
  <link rel="import" href="paper-tabs/paper-tabs.html">
  <link rel="import" href="paper-tabs/paper-tab.html">
  <link rel="import" href="iron-pages/iron-pages.html">
</head>
<body>
  <x-foo></x-foo>

  <dom-module id="x-foo">
    <template>
      <paper-tabs selected={{selected}}>
        <paper-tab>PAGE 1</paper-tab>
        <paper-tab>PAGE 2</paper-tab>
        <paper-tab>PAGE 3</paper-tab>
      </paper-tabs>
      <iron-pages selected=[[selected]]>
        <section>
          <h3>empty page 1</h3>
        </section>
        <section>
          <h3>page 2 inputs</h3>
          <paper-input></paper-input>
          <paper-input></paper-input>
          <paper-input id="my-input"></paper-input>
          <paper-input></paper-input>
        </section>
        <section>
          <h3>empty page 3</h3>
        </section>
      </iron-pages>
    </template>
    <script>
      Polymer({
        is: 'x-foo',
        properties: {
          selected: {
            type: Number,
            value: function() { return 1; }
          }
        },
        ready: function() {
          this.$['my-input'].focus();
        }
      });
    </script>
  </dom-module>
</body>

jsbin

如果我使用您包装 focus() 的解决方法用 setTimeout() 打电话(这有效地将工作推迟到执行队列的末尾),焦点正确出现:

setTimeout(function() {
  this.$['my-input'].focus();
}.bind(this), 0);

<head>
  <base href="https://polygit.org/polymer+1.4.0/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link rel="import" href="paper-input/paper-input.html">
  <link rel="import" href="paper-tabs/paper-tabs.html">
  <link rel="import" href="paper-tabs/paper-tab.html">
  <link rel="import" href="iron-pages/iron-pages.html">
</head>
<body>
  <x-foo></x-foo>

  <dom-module id="x-foo">
    <template>
      <paper-tabs selected={{selected}}>
        <paper-tab>PAGE 1</paper-tab>
        <paper-tab>PAGE 2</paper-tab>
        <paper-tab>PAGE 3</paper-tab>
      </paper-tabs>
      <iron-pages selected=[[selected]]>
        <section>
          <h3>empty page 1</h3>
        </section>
        <section>
          <h3>page 2 inputs</h3>
          <paper-input></paper-input>
          <paper-input></paper-input>
          <paper-input id="my-input"></paper-input>
          <paper-input></paper-input>
        </section>
        <section>
          <h3>empty page 3</h3>
        </section>
      </iron-pages>
    </template>
    <script>
      Polymer({
        is: 'x-foo',
        properties: {
          selected: {
            type: Number,
            value: function() { return 1; }
          }
        },
        ready: function() {
          setTimeout(function() {
            this.$['my-input'].focus();
          }.bind(this), 0);
        }
      });
    </script>
  </dom-module>
</body>

jsbin

这对我来说意味着 <paper-input>当我们尝试聚焦它时实际上并没有准备好(尽管在这个自定义元素的 ready 回调中),我不确定这是否是一个错误。要解决此问题,我们可以为 WebComponentsReady 设置一个事件处理程序。当系统中的所有组件都完全初始化时将被调用:

document.addEventListener('WebComponentsReady', function() {
   this.$['my-input'].focus();
}.bind(this));

<head>
  <base href="https://polygit.org/polymer+1.4.0/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link rel="import" href="paper-input/paper-input.html">
  <link rel="import" href="paper-tabs/paper-tabs.html">
  <link rel="import" href="paper-tabs/paper-tab.html">
  <link rel="import" href="iron-pages/iron-pages.html">
</head>
<body>
  <x-foo></x-foo>

  <dom-module id="x-foo">
    <template>
      <paper-tabs selected={{selected}}>
        <paper-tab>PAGE 1</paper-tab>
        <paper-tab>PAGE 2</paper-tab>
        <paper-tab>PAGE 3</paper-tab>
      </paper-tabs>
      <iron-pages selected=[[selected]]>
        <section>
          <h3>empty page 1</h3>
        </section>
        <section>
          <h3>page 2 inputs</h3>
          <paper-input></paper-input>
          <paper-input></paper-input>
          <paper-input id="my-input"></paper-input>
          <paper-input></paper-input>
        </section>
        <section>
          <h3>empty page 3</h3>
        </section>
      </iron-pages>
    </template>
    <script>
      Polymer({
        is: 'x-foo',
        properties: {
          selected: {
            type: Number,
            value: function() { return 1; }
          }
        },
        ready: function() {
          document.addEventListener('WebComponentsReady', function() {
            this.$['my-input'].focus();
          }.bind(this));
        }
      });
    </script>
  </dom-module>
</body>

jsbin

我认为 WebComponentsReady事件处理程序优于 setTimeout因为我认为假设 WebComponentsReady 是不安全的总是出现在这个执行队列的末尾。 setTimeout可能只是偶然起作用。

关于javascript - Polymer focus() 必须包含在 setTimeout() 中才能工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37433985/

相关文章:

javascript - jQuery、javascript 卸载

css - Polymer Layout——在卡片和响应之间放置空间

html - polymer 数据变化不反射(reflect)

css - polymer 元素不显示使用自定义 CSS 属性传递的背景图像

javascript - Polymer 1.0 - 更改 Dom 重复中未更新的属性值

javascript - jQuery - 仅当满足某些 HTML 属性时才在鼠标光标旁边显示图像

javascript - 如何使用 JS 数组元素来定义对使用参数的函数的调用

javascript - 使用 .innerHTML 向 JS 函数发送参数

javascript - 核心滚动标题面板 + jQuery 滚动

styles - 是否可以扩展Polymer元素并重用其样式?