当输入值通过JavaScript发生变化时,如何监听/检测输入值的变化?

0yg35tkg  于 2023-11-15  发布在  Java
关注(0)|答案(4)|浏览(130)

我有一个input与谷歌自动完成连接。
当用户在seachResults中上下移动时,输入的值会通过JavaScript动态更改。
我想在任何给定时间捕获输入中的值。
我已经尝试了onChangeonInput,但由于没有触发事件,DOM节点的value也没有设置-没有更新。

如何检测通过JavaScript动态更新的input更改

ryevplcw

ryevplcw1#

.value * 属性 * 只有在脚本编写者调用setAttribute('value'来设置新值时才会改变,这是一件很奇怪的事情。在几乎所有情况下,我都希望通过直接赋值给value属性来设置值,例如:

input.value = 'foo';

字符串
调用setAttribute确实会在检查的DOM * 属性 * 中显示更改,例如:

<input value="somevalue">

const input = document.querySelector('input');
input.setAttribute('value', 'foo');
console.log(input.outerHTML);
<input>

的字符串
但是仅仅赋值给元素的.valueproperty 不会导致这样的变化:

const input = document.querySelector('input');
input.value = 'foo';
console.log(input.outerHTML);
<input>

.value的调用实际上在HTMLInputElement.prototype上调用了一个 *setter函数 *:

console.log(HTMLInputElement.prototype.hasOwnProperty('value'));


您可以通过直接在元素本身上放置value的getter/setter来隐藏它,setter调用您自己的函数,允许您侦听更改:

const { get, set } = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value');
const input = document.querySelector('input');
Object.defineProperty(input, 'value', {
  get() {
    return get.call(this);
  },
  set(newVal) {
    console.log('New value assigned to input: ' + newVal);
    return set.call(this, newVal);
  }
});


// example of autocomplete trying to change the input value:
input.value = 'foo';
<input>
v8wbuo2f

v8wbuo2f2#

考虑创建和触发输入事件

var event = new Event('input', {
    bubbles: true,
    cancelable: true,
});

字符串
然后

myelement.dispatchEvent(event);

more info

wa7juj8i

wa7juj8i3#

上面的其他解决方案需要侦听所有输入或所有DOM,但这里有一个不同的解决方案,旨在检测特定元素的值更改:
你可以使用一个setInterval。我需要观察一个特定的DOM元素值的变化,我可以用下面的方法来定位特定的elementID:

var watchID ;
var el = document.getElementById('elementID') ;
var oldValue = el.value ;
var watchCount = 0 ;  // create a built in timeout function
watchID = setInterval(function() {
  watchCount++ ;
  if (el.value != oldValue) {
    console.log("Element Changed:" +el.value) ;
    ... do something ...
    clearInterval(watchID) ;
  }
  // 30 second timeout
  if (watchCount == 60) {
    console.log("Interval Timeout")          
    clearInterval(watchID) ;
  }
},500) ;  // execute every 1/2 second for 30 seconds

字符串
在我的例子中,我有一个复杂的文件下载,需要一个不同的黑客解决方案,上面的工作没有任何事件监听器或其他更复杂的解决方案,监测一切(如:MutationObserver)。当然,你不需要自定义超时.但如果你不需要,你可能需要一个比我更友好的解决方案。连续的间隔可能会使资源紧张。

f45qwnt8

f45qwnt84#

您可以在以编程方式更改.value后运行此命令

document.querySelector('#element-id').dispatchEvent(new Event('input'));

字符串
监听值更改:

document.querySelector('#element-id').addEventListener('input', function() {
  console.log(this.value);
});

相关问题