如何从Meteor事件处理程序中聚焦DOM子元素

时间:2013-08-08 01:10:41

标签: dom meteor

我有一个事件处理程序,它设置一个会话变量来改变DOM元素中的内容 - 在本例中是一个表格单元格。

'dblclick td.itemName': function (evt) {
  Session.set("editItemName",true);
  evt.currentTarget.children[0].focus();
},


                <td class="itemName">
                {{#unless editItemName}}
                    {{name}} 
                {{else}}
                    <input class="editItemName" type="text" value="{{name}}" style="width:100px;">
                {{/unless}}
                </td>

非常直接......

然而,evt.currentTarget.children不起作用。一旦输入发生了文本,我想让它自动聚焦...流星文档说这是一个DOM对象,所以奇怪的是儿童功能不起作用......

由于

切特

3 个答案:

答案 0 :(得分:5)

当您双击并且您的函数运行时,您将会话editItemName设置为true,然后您尝试给予输入元素焦点,但模板尚未重新渲染但是,因此还没有创建输入元素(模板将在函数返回后的某个时间重新渲染)。换句话说:evt.currentTarget.children[0]不是对input-element的引用。

可能的解决方案1 ​​

在HTML 5中,有一个名为autofocus的属性,你可以使用它(至少我可以在Chrome中使用)。只需将其添加到input-element:

<input autofocus="autofocus" class="editItemName" type="text" value="{{name}}" style="width:100px;">

可能的解决方案2

否则,在渲染模板并且输入元素存在于其中时,您必须使用JavaScript进行聚焦:

Template.yourTemplate.rendered = function(){

    var input = this.find('.editItemName')

    if(input){
        input.focus()
    }

}

答案 1 :(得分:4)

您正尝试将焦点设置为尚未渲染的DOM元素。

这个问题困扰了我一段时间。我尝试使用autofocus='autofocus' HTML属性:它在Firefox中没有任何效果,而在Chrome中,它似乎只在第一次呈现元素时才起作用。

因此我们需要一个在渲染模板后调用的处理程序,以便使用javascript设置焦点。 Template.templateName.rendered看起来像是要走的路,但有一个问题:

什么对我不起作用:

<template name="itemName">
    <td class="itemName">
    {{#unless editItemName}}
        {{name}} 
    {{else}}
        <input type="text" value="{{name}}">
    {{/unless}}
    </td>
</template>

Template.itemName.rendered = function()
{
    this.$('input').focus() 
}

执行此操作时,Template.yourTemplate.rendered似乎只在您第一次点击该项时触发(您只能正确获得一次焦点)。

对我有用的是什么:

<template name="itemName">
    <td class="itemName">
    {{#unless editItemName}}
        {{name}} 
    {{else}}
        {{> itemNameEdit}}
    {{/unless}}
    </td>
</template>

<template name="itemNameEdit">
    <input type="text" value="{{name}}">
</template>

Template.itemNameEdit.rendered = function()
{
    this.$('input').focus() 
}

流星专家的任何解释?

答案 2 :(得分:1)

作为@Chet pointed out,模板。[name] .rendered在模板更新时不再触发,而是仅在模板首次渲染时才会触发,{{3 }}

可以将回调传递给only once,每次更新模板时都会触发。 即Tracker.afterFlush

Template.myTemplate.events({
  'dblclick td.itemName': function(e, t) {
    Session.set("editItemName",true);

    Tracker.afterFlush(function() {
      this.find('input').focus();
    }.bind(t));
  }
});