如何在 contenteditable div 中获取已删除的元素?
How to get a deleted element in a contenteditable div?
我将根 div 设置为 contenteditable
,它包含许多 img
和 video
元素。那么当用户编辑它并按退格键删除一个元素时,如何获取用户删除了哪个元素并获取删除元素的属性值?
为事件 input
注册事件侦听器。如果您需要 IE 支持,您可以考虑使用 keypress
事件。
事件可能会在实际更改发生之前触发,并且 keypress
可能不会注册 paste 和 cut 更改,因此你也想处理这些事件(input
也会触发这些事件)。
然后计算编辑前后的差异,分析一下就可以了。
如果您对删除的元素及其属性感兴趣,一种方法是设置 MutationObserver
以跟踪对 DOM 的修改。它的回调提供更改和受影响的元素以及其他有用的信息。
(new MutationObserver(function(mutations){
mutations.forEach(function(mutation){
if(mutation.type=='attributes')
console.log('Element attributes may have changed, see record:',mutation);
else
if(mutation.type=='childList')
console.log('Child nodes were modified, see record:',mutation,
'or removedNodes:',mutation.removedNodes);
});})).observe(document.getElementById('edit'),{
subtree:true,
attributes:true,
childList:true,
characterData:true,
characterDataOldValue:true
});
Fiddle: https://jsfiddle.net/0tdm1wwv/2/
在其他浏览器中也看看它,因为 contenteditable
有一些有趣的风格。
https://jsfiddle.net/814j80z2/
<html>
<head>
<script>
var myContent = {
currentList: [], //List since last time.
initialList: [], //Starting list, just if we need it at some point.
//Storing all current nested elements in currentList and initialList
Init: function(){
var tRoot = document.getElementById('Contenteditable');
var tL = document.querySelectorAll('a, img'); //Or just all '*'.
for(var i=0, j=tL.length; i<j; i++){
this.currentList.push(tL[i]);
this.initialList.push(tL[i]);
}
if (!tRoot.oninput) tRoot.oninput = function(){myContent.onInput(this)} //Depending on your requirements use others.
if (!tRoot.onkeyup) tRoot.onkeyup = function(){myContent.onInput(this)} //Depending on your requirements use others.
},
//Comparing current nested elements with currentList and set new currentList
checkChangedElements: function(e){
if (e){
var tE = []; //Storing the exceptions.
var tN = []; //Our new current list.
var tC = []; //Current elements:
var tL = document.querySelectorAll('a, img'); //Or just all '*'.
for(var i=0, j=tL.length; i<j; i++) tC.push(tL[i]);
for(var i=0, j=myContent.currentList.length; i<j; i++){
//if (tC.some(function(item){return item === myContent.currentList[i]}) tE.push(tL[i])
if (tC.indexOf(myContent.currentList[i]) === -1) tE.push(myContent.currentList[i])
else tN.push(myContent.currentList[i])
}
myContent.currentList = tN;
return tE;
}
},
//Our input function firing each two seconds
onInput: function(e){
if (e){
if (e.inputTimer) clearTimeout(e.inputTimer); //We fire it after two seconds without any input
e.inputTimer = setTimeout(function(e){
var tL = myContent.checkChangedElements(e);
e.inputTimer = null;
console.log('Deleted elements: ', tL)
}.bind(undefined, e), 2000)
}
}
}
</script>
</head>
<body onload = 'myContent.Init()'>
<div contenteditable = 'true' id = 'Contenteditable'>
<img alt = '' src = 'https://www.google.com//images/srpr/logo11w.png' />
<a href = 'https://www.google.com/'>Google</a>
<img alt = '' src = 'https://www.google.com//images/srpr/logo11w.png' />
<a href = 'https://www.google.com/'>Google</a>
<img alt = '' src = 'https://www.google.com//images/srpr/logo11w.png' />
<a href = 'https://www.google.com/'>Google</a>
<img alt = '' src = 'https://www.google.com//images/srpr/logo11w.png' />
</div>
</body>
</html>
编辑:为较旧的 IE 版本添加了 onkeydown。
我将根 div 设置为 contenteditable
,它包含许多 img
和 video
元素。那么当用户编辑它并按退格键删除一个元素时,如何获取用户删除了哪个元素并获取删除元素的属性值?
为事件 input
注册事件侦听器。如果您需要 IE 支持,您可以考虑使用 keypress
事件。
事件可能会在实际更改发生之前触发,并且 keypress
可能不会注册 paste 和 cut 更改,因此你也想处理这些事件(input
也会触发这些事件)。
然后计算编辑前后的差异,分析一下就可以了。
如果您对删除的元素及其属性感兴趣,一种方法是设置 MutationObserver
以跟踪对 DOM 的修改。它的回调提供更改和受影响的元素以及其他有用的信息。
(new MutationObserver(function(mutations){
mutations.forEach(function(mutation){
if(mutation.type=='attributes')
console.log('Element attributes may have changed, see record:',mutation);
else
if(mutation.type=='childList')
console.log('Child nodes were modified, see record:',mutation,
'or removedNodes:',mutation.removedNodes);
});})).observe(document.getElementById('edit'),{
subtree:true,
attributes:true,
childList:true,
characterData:true,
characterDataOldValue:true
});
Fiddle: https://jsfiddle.net/0tdm1wwv/2/
在其他浏览器中也看看它,因为 contenteditable
有一些有趣的风格。
https://jsfiddle.net/814j80z2/
<html>
<head>
<script>
var myContent = {
currentList: [], //List since last time.
initialList: [], //Starting list, just if we need it at some point.
//Storing all current nested elements in currentList and initialList
Init: function(){
var tRoot = document.getElementById('Contenteditable');
var tL = document.querySelectorAll('a, img'); //Or just all '*'.
for(var i=0, j=tL.length; i<j; i++){
this.currentList.push(tL[i]);
this.initialList.push(tL[i]);
}
if (!tRoot.oninput) tRoot.oninput = function(){myContent.onInput(this)} //Depending on your requirements use others.
if (!tRoot.onkeyup) tRoot.onkeyup = function(){myContent.onInput(this)} //Depending on your requirements use others.
},
//Comparing current nested elements with currentList and set new currentList
checkChangedElements: function(e){
if (e){
var tE = []; //Storing the exceptions.
var tN = []; //Our new current list.
var tC = []; //Current elements:
var tL = document.querySelectorAll('a, img'); //Or just all '*'.
for(var i=0, j=tL.length; i<j; i++) tC.push(tL[i]);
for(var i=0, j=myContent.currentList.length; i<j; i++){
//if (tC.some(function(item){return item === myContent.currentList[i]}) tE.push(tL[i])
if (tC.indexOf(myContent.currentList[i]) === -1) tE.push(myContent.currentList[i])
else tN.push(myContent.currentList[i])
}
myContent.currentList = tN;
return tE;
}
},
//Our input function firing each two seconds
onInput: function(e){
if (e){
if (e.inputTimer) clearTimeout(e.inputTimer); //We fire it after two seconds without any input
e.inputTimer = setTimeout(function(e){
var tL = myContent.checkChangedElements(e);
e.inputTimer = null;
console.log('Deleted elements: ', tL)
}.bind(undefined, e), 2000)
}
}
}
</script>
</head>
<body onload = 'myContent.Init()'>
<div contenteditable = 'true' id = 'Contenteditable'>
<img alt = '' src = 'https://www.google.com//images/srpr/logo11w.png' />
<a href = 'https://www.google.com/'>Google</a>
<img alt = '' src = 'https://www.google.com//images/srpr/logo11w.png' />
<a href = 'https://www.google.com/'>Google</a>
<img alt = '' src = 'https://www.google.com//images/srpr/logo11w.png' />
<a href = 'https://www.google.com/'>Google</a>
<img alt = '' src = 'https://www.google.com//images/srpr/logo11w.png' />
</div>
</body>
</html>
编辑:为较旧的 IE 版本添加了 onkeydown。