keydown 事件中的 preventDefault(),onchange 事件不触发

preventDefault() in a keydown event, onchange event not trigger

在以编程方式更改值的 keydown 或 keypress 事件中调用的 preventDefault() 不考虑更改,也不会在输入文本退出时触发 onchange 事件。

示例代码:

$('#textbox1').on('change', function() {
    alert('onchange called');
});

$('#textbox1').on('keydown', function(event) {
    if(event.key=='a') {

      $(this).val('A');
      //event.target.value = 'A';
      event.preventDefault();
    }
});

在 onchange 调用(保留输入文本)后仅显示字符 'a' 并再次保留输入。

Fiddle代码:http://jsfiddle.net/gxx5744s/1/

什么使用 onchange 事件来检查值是否已更改?一对旧/新值变量?布尔值? 可以和它互动吗?

Keydown 事件默认值可能也会这样做。

来自 the docs:

Depending on the kind of form element being changed and the way the user interacts with the element, the change event fires at a different moment:

  • 当元素在其值更改后失去焦点时,但不是 已提交(例如,在编辑 <textarea><input type="text"> 的值后)。

你的例子就是这种情况。

尝试更改值并取消聚焦,您会看到警报。

onchange 事件通常会在您更改文本输入的值后触发,然后它会失去焦点,因为这里也是这种情况...但是当带有 preventDefault 的函数是调用,这不是预期的行为!!!

preventDefault 应该阻止调用它的 keydown 事件的默认行为,而不是 onchange 事件的默认行为,实际上不能取消...

我想问题有点不同:

该值的默认设置似乎与 JQuery 与

的方式不同

$(this).val('A');

可能是因为只是提交的值发生了变化,而不是 DOM 元素...如果将此行更改为

$(this).attr('Value','A');

它的行为符合预期!

有趣的是,默认行为既不设置属性值,也不会改变显示,但一定有区别!

编辑:对我来说,@Kaddath 的解决方案似乎最合适:

var change = false;

$('#textbox1').on('change', function() {
  alert('onchange called');
});

$('#textbox1').on('blur', function() {
  if (change) {
    alert('"onchange" called too');
    change = false;
  }
});

$('#textbox1').on('keydown', function(event) {
  if (event.key == 'a') {
    $(this).val('A');
    change = true;
    event.preventDefault();
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="textbox1" />

采用@Kaddath 的想法修改解决方案 "dirty" 但可能可行。 我不太喜欢,但目前我没有发现它更好。

$('#textbox1').on('change', function() {
 alert('onchange called');
});
    
$('#textbox1').on('keydown', function(event) {    
  var oldValue = event.target.value;
  
  if (event.keyCode == 46) { //DELETE
   event.target.value = ""
    } else
  event.target.value = event.key + event.target.value;
    
  event.preventDefault();

  if (event.target.valueOnFocus === undefined) {
    // set a new property on the input element
    event.target.valueOnFocus = oldValue;
    
    $(event.target).on('focus', function(event) {
      // From the second time that enter on the input element,
      // update the new property
      event.target.valueOnFocus = event.target.value;
    });
    
   $(event.target).on('blur', function(event) {
      if (event.target.value !== event.target.valueOnFocus)
        $(event.target).trigger('change');
   });
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="textbox1" />

在 fiddle 上:http://jsfiddle.net/gxx5744s/3/