通过javascript检查活动元素是否有特定的类

Check if active element has particular class via javascript

本文关键字:是否 javascript 检查 活动 元素 通过      更新时间:2023-09-26

我正在编写一个单字段表单,并希望按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的第一个实例。我不想在节点上迭代,因为它看起来并不比我已经有的好多少。

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

检查activeElement是否具有questions类。

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

squint提供了一个改进的正则表达式,它将在类名中考虑更多奇怪的情况。

试试这个:

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

首先,您可以使用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),但我故意没有触及这部分,使其更容易理解。

希望有帮助!

你们用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();
            }
        }
    } );

在我把它标记为答案之前,我会给你们一些时间来评论一下…