当用户编辑具有contentteditable属性的div的内容时,我想运行一个函数。onchange事件的等价物是什么?

我使用jQuery,所以使用jQuery的任何解决方案都是首选。谢谢!


当前回答

考虑使用MutationObserver。这些观察器设计用于对DOM中的更改做出反应,并作为突变事件的性能替代品。

优点:

当发生任何变化时触发,这很难通过听其他答案所建议的关键事件来实现。例如,所有这些工作都很好:拖放,斜体,复制/剪切/粘贴上下文菜单。 设计时考虑到性能。 简单、直接的代码。比起监听10个事件的代码,理解和调试监听一个事件的代码要容易得多。 谷歌有一个优秀的突变摘要库,使得mutationobserver的使用非常简单。

缺点:

需要最新版本的Firefox (14.0+), Chrome(18+)或IE(11+)。 需要理解的新API 关于最佳实践或案例研究的信息还不多

了解更多:

我写了一个小片段来比较使用mutationobserver处理各种事件。我用了balupton的密码,因为他的答案得到了最多的好评。 Mozilla有一个关于API的优秀页面 看一下MutationSummary库

其他回答

看看这个想法。 http://pastie.org/1096892

我觉得很接近了。HTML 5确实需要将更改事件添加到规范中。唯一的问题是回调函数在$(this). HTML()中内容实际更新之前计算if (before == $(this). HTML())。setTimeout不起作用,这很可悲。让我知道你的想法。

这里有一个更有效的版本,它对所有可内容使用on。这是基于上面的答案。

$('body').on('focus', '[contenteditable]', function() {
    const $this = $(this);
    $this.data('before', $this.html());
}).on('blur keyup paste input', '[contenteditable]', function() {
    const $this = $(this);
    if ($this.data('before') !== $this.html()) {
        $this.data('before', $this.html());
        $this.trigger('change');
    }
});

项目在这里:https://github.com/balupton/html5edit

下面是我最终使用的解决方案,效果非常好。我使用$(this).text()代替,因为我只是使用了内容可编辑的一行div。但是你也可以使用.html(),这样你就不必担心全局/非全局变量的作用域,而before实际上是附加到编辑器div的。

$('body').delegate('#editor', 'focus', function(){
    $(this).data('before', $(this).html());
});
$('#client_tasks').delegate('.task_text', 'blur', function(){
    if($(this).data('before') != $(this).html()){
        /* do your stuff here - like ajax save */
        alert('I promise, I have changed!');
    }
});

两个选择:

1)对于现代(常青树)浏览器: “输入”事件将充当另一个“更改”事件。

https://developer.mozilla.org/en-US/docs/Web/Events/input

document.querySelector('div').addEventListener('input', (e) => {
    // Do something with the "change"-like event
});

or

<div oninput="someFunc(event)"></div>

或(使用jQuery)

$('div').on('click', function(e) {
    // Do something with the "change"-like event
});

2)考虑到IE11和现代(常青树)浏览器: 这将监视div中的元素变化及其内容。

https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver

var div = document.querySelector('div');
var divMO = new window.MutationObserver(function(e) {
    // Do something on change
});
divMO.observe(div, { childList: true, subtree: true, characterData: true });

在MutationEvents下使用domcharacterdatmodified会导致同样的结果。超时设置是为了防止发送错误的值(例如,在Chrome中,我有一些空格键的问题)

var timeoutID;
$('[contenteditable]').bind('DOMCharacterDataModified', function() {
    clearTimeout(timeoutID);
    $that = $(this);
    timeoutID = setTimeout(function() {
        $that.trigger('change')
    }, 50)
});
$('[contentEditable]').bind('change', function() {
    console.log($(this).text());
})

JSFIDDLE例子