状态改变后保持元素焦点

Posted

技术标签:

【中文标题】状态改变后保持元素焦点【英文标题】:Keep element in focus after state changed 【发布时间】:2016-10-19 14:08:18 【问题描述】:

在我的 AngularJS/Ui-Router 应用程序中,我有一系列这样的输入框:

<input ng-model="vm.filter" ng-keyup="vm.onKeyUp($event)" type="text" class="form-control" id="filter">

然后我有一个控制器,我在其中放置了onKeyUp 函数,如下所示:

var vm = this;
vm.onKeyUp = function (e) 
    var val = e.currentTarget.value;
    $state.go('aState',  'filter': val );

这将触发状态更改(实际上只是更改了状态参数filter),它将在后台调用resolve,在流程结束时,我的数据集被过滤并显示子集。太棒了。

但是有一个小问题:在状态改变时,html 输入失去了焦点,我不知道如何在流程结束时将其设置为焦点。 这是必要的,因为用户开始在输入框中书写,然后当他的焦点“神秘地”丢失时会感到惊讶。糟糕的用户界面体验。

【问题讨论】:

Element.focus();应该在代码末尾将元素重新聚焦... 我认为这可能就足够了,但这不起作用...... 【参考方案1】:

好吧,我能读到什么,您只需在 url (:filter) 上使用不同的参数调用相同的状态,即使状态相同,stateChange 也会强制重新加载视图,因此会丢失的焦点元素。

除非您在$stateChangeStart 上创建event.preventDefault(),否则就是这种行为,但我很确定您的数据不会被更新。

所以可能的解决方案是恕我直言:

    重新考虑您的流程,使其不依赖于状态变化。 (这里不需要编码:P)

    找到一种方法来保存您的活动元素并将其设置为重新加载,例如。

    //sessionStorage to prevent data stored after window is closed;
    $scope.$on('$stateChangeStart', function()
        $window.sessionStorage.setItem('focusedId', '#' + document.activeElement.id);      
    );
    
    $scope.$on('$viewContentLoaded', function() 
        if((var id = $window.sessionStorage.getItem('focusedId'))) 
            $DOM.focus(id);  
            //Use a service for DOM manipulation, you know manipulation in controllers is bad :(
        
    );
    

` 服务可能是这样的:

.factory('$DOM', ['$window', '$timeout', function ($window, $timeout) 
    return 
        __constructor: function (selector, event) 
             $timeout(function () 
                 var element = (typeof selector == 'object') ? 
                               selector :    
                               $window.document.querySelector(selector);

                 (!!element && !!element[event]) ? element[event]() : null;
              );
          ,
          focus: function (selector) 
              this.__constructor(selector, 'focus');
          ,
          blur: function (selector) 
              this.__constructor(selector, 'blur');
          , //and so....
      ;
])

如果您找到更好的方法,请发表评论,也许您可​​以刷新数据以防止刷新视图,我对 ui.router 的理解是错误的:)

【讨论】:

以上是关于状态改变后保持元素焦点的主要内容,如果未能解决你的问题,请参考以下文章

如何让WPF中窗体失去焦点后TextBox中的被选中文本仍然保持高亮状态?

调用 setState 后 ReactJS 元素未更新

Input 控件的Onchange 与onBlur 事件区别?

elementui table表格后端分页 ,改变pagesize或者改变page扔保持复选框状态

MFC怎么实现按钮保持在被选中状态?

更改DOM后刷新浏览器悬停效果