Javascript 主干:渲染后恢复焦点

Javascript 主干:渲染后恢复焦点,javascript,backbone.js,focus,Javascript,Backbone.js,Focus,我这里有个小问题: 在我的Backbone.js应用程序中,我将更改保存在可在blur上编辑的内容中。这意味着,当按下tab键时,整个视图将被重新渲染,而我将失去对下一个元素的焦点。我怎样才能恢复这个 我对每个输入使用专用的ViewModel和View。它有一个特殊的readValue/writeValue方法,用于更新元素而不是重新创建它。看起来是这样的: var TextInput = Backbone.Model.extend({ // abstract defaults: {

我这里有个小问题:


在我的Backbone.js应用程序中,我将更改保存在可在blur上编辑的内容中。这意味着,当按下tab键时,整个视图将被重新渲染,而我将失去对下一个元素的焦点。我怎样才能恢复这个

我对每个输入使用专用的ViewModel和View。它有一个特殊的readValue/writeValue方法,用于更新元素而不是重新创建它。看起来是这样的:

var TextInput = Backbone.Model.extend({ // abstract
    defaults: {
        value: '', // text
        visible: true, // determines if input element is visible
        readonly: false, // determines if input element is read only 
        enabled: true, // determines if input element is enabled
        delay: 750 // view/model sync latency
    }
});

var TextInputView = Backbone.View.extend({
    template: _.template($('#text-input').html()),
    initialize: function (options) {
        this.model.bind('change:visible', this.render, this);
        this.model.bind('change:readonly', this.render, this);
        this.model.bind('change:enabled', this.render, this);
        this.model.bind('change:value', this.readValue, this);
    },
    events: {
        'change input': 'writeValue',
        'keyup input': 'writeValue'
    },
    render: function () {
        $(this.el).html(this.template(this.model))
            .find('input')
                .prop({
                    readonly: this.model.get('readonly'),
                    disabled: !this.model.get('enabled')
                })
                .toggleClass('hidden', !this.model.get('visible'));

        this.readValue();
        return this;
    },
    changeTimer: null,
    writeValue: function () {
        if (this.changeTimer)
            clearTimeout(this.changeTimer);

        var that = this;
        this.changeTimer = setTimeout(function () {
            that.model.set({ value: that.$('input').val() });
        }, this.model.get('delay'));
    },
    readValue: function () {
        if (this.$('input').val() != this.model.get('value'))
            this.$('input').val(this.model.get('value'));
    }
});

我为每个输入使用专用的ViewModel和View。它有一个特殊的readValue/writeValue方法,用于更新元素而不是重新创建它。看起来是这样的:

var TextInput = Backbone.Model.extend({ // abstract
    defaults: {
        value: '', // text
        visible: true, // determines if input element is visible
        readonly: false, // determines if input element is read only 
        enabled: true, // determines if input element is enabled
        delay: 750 // view/model sync latency
    }
});

var TextInputView = Backbone.View.extend({
    template: _.template($('#text-input').html()),
    initialize: function (options) {
        this.model.bind('change:visible', this.render, this);
        this.model.bind('change:readonly', this.render, this);
        this.model.bind('change:enabled', this.render, this);
        this.model.bind('change:value', this.readValue, this);
    },
    events: {
        'change input': 'writeValue',
        'keyup input': 'writeValue'
    },
    render: function () {
        $(this.el).html(this.template(this.model))
            .find('input')
                .prop({
                    readonly: this.model.get('readonly'),
                    disabled: !this.model.get('enabled')
                })
                .toggleClass('hidden', !this.model.get('visible'));

        this.readValue();
        return this;
    },
    changeTimer: null,
    writeValue: function () {
        if (this.changeTimer)
            clearTimeout(this.changeTimer);

        var that = this;
        this.changeTimer = setTimeout(function () {
            that.model.set({ value: that.$('input').val() });
        }, this.model.get('delay'));
    },
    readValue: function () {
        if (this.$('input').val() != this.model.get('value'))
            this.$('input').val(this.model.get('value'));
    }
});

可以在视图(作为普通属性,如下面的示例所示)或模型中维护属性,以存储当前关注的元素。每当焦点改变时,更新属性

重新渲染内容后,手动将焦点设置为元素

下面是一个最低限度的代码:

var myView = Backbone.View.extend({
    el: $('#formElement'),

    initialize: function() {
        _.bindAll(this);
    }

    events: {
        'focus input': "updateFocus"
    },

    updateFocus: function(event) {
        this.focusedElem = $(event.target);
    },

    render: function() {
        // After rendering is complete
        this.focusedElem.focus();
    }
});

可以在视图(作为普通属性,如下面的示例所示)或模型中维护属性,以存储当前关注的元素。每当焦点改变时,更新属性

重新渲染内容后,手动将焦点设置为元素

下面是一个最低限度的代码:

var myView = Backbone.View.extend({
    el: $('#formElement'),

    initialize: function() {
        _.bindAll(this);
    }

    events: {
        'focus input': "updateFocus"
    },

    updateFocus: function(event) {
        this.focusedElem = $(event.target);
    },

    render: function() {
        // After rendering is complete
        this.focusedElem.focus();
    }
});

我发现我希望它在渲染后转到“下一个”元素。此外,您不记得JQuery中从DOM中删除的元素。所以我记录输入的名称,而不是输入本身。结合前面的答案,你可以做类似下面的事情。记住,我有一些假设,比如输入上的名称,以及我在字段集中搜索的名称

    getNextInputForName = function(desiredName) {
      var desiredElement = false;
        var foundElement;
        $("fieldset input").each(function(index) {
          if (desiredElement) {
              foundElement = $(this);
                return false;
            }
            if ($(this).attr("name") === desiredName) {
                desiredElement = true;
            }
        });
        return foundElement;
    }

    var myView = Backbone.View.extend({
      el: $('#formElement'),

      initialize: function() {
        _.bindAll(this);
      }

      events: {
        'focus input': "updateFocus"
      },

      updateFocus: function(event) {
        this.focusedElem = $(event.target).attr("name");
      },

      render: function() {
        // After rendering is complete
        if( this.focusedElem ) {
          getNextInputForName(this.focusedElem).focus();
        }
      }
    });

我发现我希望它在渲染后转到“下一个”元素。此外,您不记得JQuery中从DOM中删除的元素。所以我记录输入的名称,而不是输入本身。结合前面的答案,你可以做类似下面的事情。记住,我有一些假设,比如输入上的名称,以及我在字段集中搜索的名称

    getNextInputForName = function(desiredName) {
      var desiredElement = false;
        var foundElement;
        $("fieldset input").each(function(index) {
          if (desiredElement) {
              foundElement = $(this);
                return false;
            }
            if ($(this).attr("name") === desiredName) {
                desiredElement = true;
            }
        });
        return foundElement;
    }

    var myView = Backbone.View.extend({
      el: $('#formElement'),

      initialize: function() {
        _.bindAll(this);
      }

      events: {
        'focus input': "updateFocus"
      },

      updateFocus: function(event) {
        this.focusedElem = $(event.target).attr("name");
      },

      render: function() {
        // After rendering is complete
        if( this.focusedElem ) {
          getNextInputForName(this.focusedElem).focus();
        }
      }
    });

考虑在模糊考虑时禁用重渲染,在模糊时禁用重新渲染。