通过javascript

时间:2016-11-18 17:57:39

标签: javascript dom

我正在编写单字段表单,并希望使用Enter键将表单前进到下一个输入字段。由于页面上有另一个表单,我只希望当表单中的一个输入为activeElement时,使用Enter键推进表单。

我已经通过这里看起来非常冗长的if()声明实现了这一点:

document.addEventListener( 'keydown', function( ev ) {
        var keyCode = ev.keyCode || ev.which;
        var ids = [ 'this', 'that', 'there', 'thing', 'other' ];
        if ( document.getElementById( ids[0] ) === document.activeElement || document.getElementById( ids[1] ) === document.activeElement || document.getElementById( ids[2] ) === document.activeElement || document.getElementById( ids[3] ) === document.activeElement || document.getElementById( ids[4] ) === document.activeElement) {
            if( keyCode === 13 ) {
                ev.preventDefault();
                self._nextQuestion();
            }
        }
    } );

每个输入都是同一个类:.questions。我尝试过类似的东西:

document.addEventListener( 'keydown', function( ev ) {
    var keyCode = ev.keyCode || ev.which;
    var ids = [ 'this', 'that', 'there', 'thing', 'other' ];
    if ( document.querySelector('.questions') === document.activeElement) {
        if( keyCode === 13 ) {
            ev.preventDefault();
            self._nextQuestion();
        }
    }
} );

但是,当然,这只会访问页面上.questions的第一个实例。我不想迭代节点,因为它似乎没有比我已经好多了。

我是新手,我正在寻找更简洁的逻辑。

4 个答案:

答案 0 :(得分:5)

只需检查activeElement是否有questions类。

var pattern = /(?:^|\s)questions(?:\s|$)/
if (document.activeElement.className.match(pattern)) {
  ...
}

斜视提供了一个改进的正则表达式,它将在类名中解释更多时髦的情况。

答案 1 :(得分:3)

试试这个:

if ((" "+document.activeElement.className+" ").indexOf(" questions ") > -1) {
    ...
}

答案 2 :(得分:2)

首先,您可以利用classList api来检查给定className存在的元素,例如document.activeElement && document.activeElement.classList.contains('question')

所有提议的方法都非常有用,应该解决问题。另一方面,您可能希望将应用程序的状态保存在一个位置,以便您可以轻松管理它。通过这样做,您可以使应用程序更易于预测并更容易调试。

这是您可能想要采取的方法:

HTML代码:

<input class="question" value="1"/>
<input class="question" value="2"/>
<input class="question" value="3"/>
<input class="question" value="4"/>
<input class="question" value="5"/>

JavaScript代码:

var component = {
  activeQuestion: 0,
  questionSelector: '.question',
  get activeQuestionElement () {
    return component.allQuestionElements[component.activeQuestion];
  },
  get allQuestionElements () {
    return document.querySelectorAll(component.questionSelector);
  },
  next: function () {
    var activeElement = document.activeElement;

    if (activeElement && activeElement === component.activeQuestionElement && component.allQuestionElements[component.activeQuestion+1]) {
      component.activeQuestion++;
      component.highlightQuestion();
    }
  },
  highlightQuestion: function () {
    component.activeQuestionElement.focus();
  },
  install: function () {
    document.addEventListener('keyup', function (event) {
      if (event.which === 13) {
        component.next.call(component);
      }
    });
    document.addEventListener('click', function (event) {
      var className = component.questionSelector.slice(1);

      if (event.target.classList.contains(className)) {
        component.activeQuestion = [].slice.call(document.querySelectorAll(component.questionSelector)).indexOf(event.target);
        component.highlightQuestion();
      }
    })
  }
};

component.install();

正如您在上面所看到的,component是一个单独的对象实例,它包含有用的信息,如activeQuestion索引,问题选择器,一些返回DOM元素的计算属性。 install方法绑定在事件发生时管理状态的事件侦听器。

这是一个演示:

http://jsfiddle.net/maciejsmolinski/xzyvye8z/embedded/result/

当您关注任何字段时单击enter,它会将焦点移至下一个字段。除此之外,单击任何字段也会更改活动问题。您可以通过修改我上面发布的代码轻松地改变行为。它只是一个基本的骨架,可以用来构建自己的功能。

这是一个非常基本的组成部分。你可以在它上面构建任何东西。您可以引入ES6语法(类,箭头函数,const而不是var),但我故意将该部分保持不变,以便更容易理解。

希望它有所帮助!

答案 3 :(得分:0)

你们用document.activeElement.className向我指出了正确的方向,所以我赞成所有提到它的人,但是这里最简洁的解决方案似乎就是这样:

document.addEventListener( 'keydown', function( ev ) {
        var keyCode = ev.keyCode || ev.which;
        // enter
        if ( document.activeElement.className === 'questions') {
            if( keyCode === 13 ) {
                ev.preventDefault();
                self._nextQuestion();
            }
        }
    } );

在我将其标记为答案之前,我会给你们一些时间来批评这个...