1

はじめに

contenteditable DOM オブジェクトのコンテンツを編集する場合、ブラウザーが異なれば動作も異なります。たとえば、Firefox 18.0 では新しい段落 ( <p>) または改行<br/>が作成される場合がありますが、Chrome 24 では<div>.

これに対処するために、DOMNodeInsertedイベントをリッスンして、新しく挿入されたノードを p タグに置き換えています。


問題

問題は、キャレットを配置することです。この同じ件名に関する SO の投稿をたくさん読みましたが、少なくとも Chrome 24 では、提供された回答はどれも機能しませんでした。


コード

JSFiddle

obj.addEventListener("DOMNodeInserted", onNodeInsert, false);

function onNodeInsert(e) {
    var range    = document.createRange(),
        sel      = window.getSelection(),
        newNode  = e.target,
        tagName  = newNode.tagName.toLowerCase(),
        lnbrNode = document.createElement('br'),
        pNode    = document.createElement('p');

    if (tagName === 'div' && newNode.getAttribute("id") === null) {
        // First we remove the event listener so that it doesn't get triggered again
        this.removeEventListener('DOMNodeInserted', onNodeInsert, false);

        // Creates a p node and removes the div
        newNode.parentNode.replaceChild(pNode, newNode);
        pNode.appendChild(lnbrNode);

        // Places the caret where it belongs
        range.setStart(pNode, 0);
        sel.removeAllRanges();
        sel.addRange(range);    

        //We can restore the event listener now
        this.addEventListener("DOMNodeInserted", onNodeInsert, false);
    }
}
4

1 に答える 1

0

私と同じ問題に遭遇する可能性がある人のために、ここに私の汚い修正があります...


関連コード

JSFiddle

obj.addEventListener("DOMNodeInserted", onNodeInsert, false);

function onNodeInsert(e) {
    var range    = document.createRange(),
        sel      = window.getSelection(),
        newNode  = e.target,
        tagName  = newNode.tagName.toLowerCase(),
        lnbrNode = document.createElement('br'),
        pNode    = document.createElement('p');

    if (tagName === 'div' && newNode.getAttribute("id") === null) {
        // First we remove the event listener so that it doesn't get triggered again
        this.removeEventListener('DOMNodeInserted', onNodeInsert, false);

        // Creates a p node and removes the div
        newNode.parentNode.replaceChild(pNode, newNode);
        pNode.appendChild(lnbrNode);

        // Places the caret where it belongs
        var placeCursor = function () {
            range.setStart(pNode, 0);
            sel.removeAllRanges();
            sel.addRange(range);    
        }

        //placeCursor(); // DOES NOT WORK (cursor disappears)
        setTimeout(placeCursor,1); // WORKS

        //We can restore the event listener now
        this.addEventListener("DOMNodeInserted", onNodeInsert, false);
    }
}
于 2013-01-16T00:46:45.223 に答える