javascript - Polymer focus() has to be wrapped in setTimeout() to work? -


when trying give focus polymer element i've have wrap in settimout, in case it's polymer paper-input element. this:

settimeout(function() {    paperinput.focus();  }, 10); 

i've read different stackoverflow posts on subject focus() polymer elements , i've seen of them have same problem. can't accept fact works when wrap want know why dose not work when don't wrap it.

so question is, why? why have wrap in settimeout?

using polymer 1.4 @ moment. i've noticed same behaviour in older versions.

thanks!

update

i've tried reproduce problem, works. i'll bet problem in own environment: jsbin

i keep post updated if find solution problem. help.

in simple case, no other elements on page except <paper-input>, there seems no problem 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

but can reproduce problem in more complex case <paper-input> inside <iron-pages>. in following example, third <paper-input> on page 2 should have been focused.

<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

if use workaround of wrapping focus() call settimeout() (which defers work until end of execution queue), focus correctly occurs:

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

this implies me <paper-input> not ready when try focus (despite being inside custom element's ready callback), , i'm not sure whether that's bug. workaround issue, set event handler webcomponentsready called when components in system have initialized:

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

i think webcomponentsready event handler better settimeout because don't think it's safe assume webcomponentsready occurs @ end of execution queue. settimeout works chance.


Comments

Popular posts from this blog

PySide and Qt Properties: Connecting signals from Python to QML -

c# - DevExpress.Wpf.Grid.InfiniteGridSizeException was unhandled -

scala - 'wrong top statement declaration' when using slick in IntelliJ -