我正在使用jQuery,因此任何使用jQuery的解决方案都是首选。谢谢!
正如评论中指出的那样,这并没有回答问题所要求的与change
事件等同的内容,而是input
事件。不过,我将保留它原来的形式。
我建议在可编辑元素上附加键盘事件监听器,但需要注意keydown
和keypress
事件是在更改内容本身之前触发的。这不会涵盖每种可能更改内容的方法:用户还可以使用“剪切”、“复制”和“粘贴”从编辑或上下文浏览器菜单,因此您可能还想处理cut
、copy
和paste
事件。此外,用户还可以拖放文本或其他内容,因此有更多的事件(例如mouseup
)。您可能需要作为回退轮询元素的内容。
更新于2014年10月29日
HTML5 input
事件是长期的答案。在本文写作时,在当前版本的Mozilla(从Firefox14)和WebKit/Blink浏览器中支持contenteditable
元素,但不支持IE。
示例:
document.getElementById("editor").addEventListener("input", function() {
console.log("input event fired");
}, false);
<div contenteditable="true" id="editor">Please type something in here</div>
这里有一个更高效的版本,它使用 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');
}
});
document.getElementById('editor_input').innerHTML = 'ssss'
。缺点是它需要IE11。 - user133408了解更多:
input
事件不完全相同(在支持变异观察器的所有WebKit和Mozilla浏览器中,它支持contenteditable
),因为DOM变异可能会通过脚本以及用户输入发生,但对于那些浏览器来说,这是一个可行的解决方案。我想它可能比input
事件更影响性能,但我没有确凿的证据。 - Tim Down无需使用jQuery,快速而简单粗暴的解决方案:
function setChangeListener (div, listener) {
div.addEventListener("blur", listener);
div.addEventListener("keyup", listener);
div.addEventListener("paste", listener);
div.addEventListener("copy", listener);
div.addEventListener("cut", listener);
div.addEventListener("delete", listener);
div.addEventListener("mouseup", listener);
}
var div = document.querySelector("someDiv");
setChangeListener(div, function(event){
console.log(event);
});
我已经按照lawwantsin的答案进行了修改,以下是我的修改结果并且它对我有效。我使用了keyup事件而不是keypress, 这个方法非常好用。
$('#editor').on('focus', function() {
before = $(this).html();
}).on('blur keyup paste', function() {
if (before != $(this).html()) { $(this).trigger('change'); }
});
$('#editor').on('change', function() {alert('changed')});
两个选项:
1)对于现代(常青)浏览器: “input”事件可作为“change”事件的替代。
https://developer.mozilla.org/en-US/docs/Web/Events/input
document.querySelector('div').addEventListener('input', (e) => {
// Do something with the "change"-like event
});
或者<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 });
input
事件即可!如果需要支持 IE11,则可以使用变动观察器。简洁明了,喜欢它。 - Jack Steaminput
会在您键入时触发。我正在触发一个 AJAX 请求 - 我不想在每次按键时都这样做。许多其他答案解释了如何处理这个问题。 - Auspexconst p = document.querySelector('p')
const result = document.querySelector('div')
const observer = new MutationObserver((mutationRecords) => {
result.textContent = mutationRecords[0].target.data
// result.textContent = p.textContent
})
observer.observe(p, {
characterData: true,
subtree: true,
})
<p contenteditable>abc</p>
<div />
这是我的解决方案:
var clicked = {}
$("[contenteditable='true']").each(function(){
var id = $(this).attr("id");
$(this).bind('focus', function() {
// store the original value of element first time it gets focus
if(!(id in clicked)){
clicked[id] = $(this).html()
}
});
});
// then once the user clicks on save
$("#save").click(function(){
for(var id in clicked){
var original = clicked[id];
var current = $("#"+id).html();
// check if value changed
if(original != current) save(id,current);
}
});
在我调查这个主题时,这个帖子对我非常有帮助。
我将这里提供的一些代码修改为jQuery插件,以便以可重用的形式出现,主要是为了满足我的需求,但其他人可能会欣赏一个更简单的界面,以启动使用contenteditable标记。
https://gist.github.com/3410122
由于其越来越受欢迎,该插件已被Makesites.org采用。
开发将继续从这里开始:
非 JQuery 解决方案...
function makeEditable(elem){
elem.setAttribute('contenteditable', 'true');
elem.addEventListener('blur', function (evt) {
elem.removeAttribute('contenteditable');
elem.removeEventListener('blur', evt.target);
});
elem.focus();
}
makeEditable(document.getElementById('myHeader'))
这个元素现在可以被用户编辑,直到失去焦点为止。
contenteditable
直到失去焦点。我认为这并没有回答问题。问题是:“当 contenteditable
元素改变时,如何运行一个函数?” - Jack Steam
document.getElementById("editor").oninput = function() { ...}
。 - Basj