高度/内容跳跃时不会触发click事件

时间:2016-12-06 11:59:01

标签: javascript html angularjs onclick

我的表单下面有一个显示验证错误的表单。它显示blur事件的验证错误。问题是,如果在单击链接时显示错误消息,则此表单下方的链接不可单击。问题与以下事实有关:在dom中注入错误消息并且点击事件的位置不再在链接上之后实际链接正在下降

  <form name="myForm" ng-model-options="{updateOn: 'blur'}">
    <input type="text" name="firstName" ng-model="firstName" required>
    <div style="color:red; margin-top: 20px" ng-if="myForm.firstName.$touched && myForm.firstName.$invalid">
      Required field
    </div>
  </form>
  <a href="https://www.google.com" target="_blank">Static link</a>
  <a href="" ng-click="linkClick()">Click Me</a>

angular.module('formExample', [])
  .controller('ExampleController', ['$scope', function($scope) {
    $scope.firstName = 'test';
    $scope.linkClick = function(){
      alert('link click');
    }
  }]);

Example Plunker

要重现问题,请删除输入文本并单击链接(以触发模糊事件)。它不会显示警报。如果你点击第二次 - 它会。

如何使其以通用方式(每个页面使用表单)工作,每次单击链接(或其他任何内容)时,无论内容是否跳跃,此点击事件都会触发

1 个答案:

答案 0 :(得分:0)

这是因为模糊发生在点击事件之前。事件的顺序是:

  • 鼠标按下
  • 模糊
  • 鼠标松开
  • 点击

如果您使键盘事件生效(即某些选项卡远离输入字段),这会变得更加有趣

Tab键事件的键盘顺序为:

  • KEYDOWN
  • 模糊
  • KEYUP

(除了标签之外,您还有其他键的按键事件)

因此,您有两个解决方案:

  1. 将click事件更改为mousedown和keydown事件。
  2. 在填充错误消息之前,在blur事件上添加1000毫秒的延迟。
  3. 我更喜欢#2,因为如果我仍然可以使用点击,我不必担心单独的keydown事件。

    以下是您可以使用的一些代码(所有香草JS):

    var testForm = document.getElementById('testForm'),
        testInput = document.getElementById('testInput'),
        testButton = document.getElementById('testButton'),
        testError = document.createElement("DIV"),
        errorText = document.createTextNode("Error Message");
    
    testInput.addEventListener('blur', function (evt) {
      console.log('blur');
      /*
      if (testInput.value === '') {
        console.log('add div');
        testError.appendChild(errorText);
        testForm.appendChild(testError);
      }
      */
      setTimeout(function() {
        console.log('timeout ended');
        if (testInput.value === '') {
          console.log('add div');
          testError.appendChild(errorText);
          testForm.appendChild(testError);
        }
      }, 1000);
    });
    
    testButton.addEventListener('mousedown', function (evt) {
      console.log('mousedown');
    });
    
    testButton.addEventListener('mouseup', function (evt) {
      console.log('mouseup');
    });
    
    testButton.addEventListener('click', function (evt) {
      console.log('click');
      alert('you clicked me');
    });
    
    document.addEventListener('keydown', function (evt) {
      console.log('keydown');
    });
    
    document.addEventListener('keyup', function (evt) {
      console.log('keyup');
    });
    
    document.addEventListener('keypress', function (evt) {
      console.log('keypress');
    });
    <form action="" id="testForm">
      <input type="text" value="test" id="testInput" />
    </form>
    <button id="testButton">TEST BUTTON</button>