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>
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>
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>
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>
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
Post a Comment