如何在 contenteditable div 中获取已删除的元素?

How to get a deleted element in a contenteditable div?

我将根 div 设置为 contenteditable,它包含许多 imgvideo 元素。那么当用户编辑它并按退格键删除一个元素时,如何获取用户删除了哪个元素并获取删除元素的属性值?

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

为事件 input 注册事件侦听器。如果您需要 IE 支持,您可以考虑使用 keypress 事件。

事件可能会在实际更改发生之前触发,并且 keypress 可能不会注册 pastecut 更改,因此你也想处理这些事件(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。