我想在我的网站上有两个(甚至更多)相同的 html 表单。
例如,一个 - 在顶部,另一个 - 在页面底部。
我想要的是让他们在任何给定时间都拥有完全相同的内容。如果用户更改其中一个值,则其余所有值都会更新。
有没有更好的同步javascript onchange
/onkeyup
事件的方法?
onchange
仅在元素失去焦点后触发。
onkeyup
也不完美。onkeydown
它在长文本复制上浪费了大量的 CPU,并且如果元素在和onkeyup
事件之间失去焦点,则不会触发。
1 回答
更新:我刚刚了解到 HTML5 对此有更合适的事件oninput
,但当然它在旧浏览器中不起作用。oninput
将检测任何类型的文本更改,包括Paste
、Cut
和Delete
从右键单击菜单。所以最好的选择可能是检查浏览器是否支持oninput
(例如通过使用这里推荐的功能),如果不支持则回退到下面的方法。在旧版本的 IE 上,onpropertychange
可以用来模拟oninput
.
我决定根据 KnockoutJS 的实现方式来改变我的答案。从Knockout 文档中的此页面:
“afterkeydown” - 一旦用户开始输入字符,就会更新您的视图模型。这是通过捕获浏览器的 keydown 事件并异步处理事件来实现的。
在这些选项中,如果您想实时更新视图模型,“afterkeydown”是最佳选择。
它通过使用setTimeout
零时间值来完成异步行为。除此之外,它看起来就像一个常规的keydown
事件处理程序。
这是一个使用 jQuery 的简单示例,我相信它的行为等同于 Knockout 的“afterkeydown”事件:
$('#email').keydown(function() {
setTimeout( $.proxy(handler, this), 0);
});
function handler() {
console.log( this.value );
}
注意:这不会捕获右键单击粘贴事件和拖放事件。如果您也想更新这些事件的文本,只需以与 keydown 相同的方式监听它们,例如:
$('#email').on('keydown paste drop', function() {
setTimeout( $.proxy(handler, this), 0);
});
Like keydown
,paste
并且drop
还需要setTimeout
以使用文本的最新值进行更新。
原答案:
onkeyup
可能是要走的路,但如果元素在 keydown 和 keyup 之间失去焦点,你会提出一个很好的观点,即它不会触发。基于这个答案,我很确定解决方案是监听容器元素(或主体上的 keyup 事件,尽管在这种情况下将它绑定到<form>
元素可能最有意义)。
至于粘贴时的 CPU 使用率,您可以尝试取消该事件,除非经过一定时间(比如 50 毫秒)......希望这已经足够了。如果没有,你可以看看一些流行的 2 路数据绑定框架是如何处理这个问题的……我见过的大多数都使用onkeyup
.