3

ノードが contenteditable div に挿入されるたびにトリガーされる eventHandler があります。この eventHandler は、新しく挿入されdiv nodeた をに置き換えp nodeます。

問題は、置換後にカーソルを配置することです。基本的に、カーソルは適切に配置されていません。つまり、新しく作成された p ノードに配置されるはずのカーソルが消えてしまいます。奇妙なことに、コンテンツの編集可能な div にはまだフォーカスがあり、window.selectionオブジェクトをダンプすると範囲が正しく設定されていることがわかります。

この問題を回避できる唯一の方法は、setTimeout を使用したダーティ フィックスを使用することでした。


Q. setTimeout を指定して placeCursor() を呼び出すのに、setTimeout を指定しないと呼び出せないのはなぜですか?


関連コード:

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);
    }
}

詳細については、この投稿を参照してください

4

1 に答える 1

2

うまく説明する方法がわかりませんが、DOM の永続化が遅れているためです。私は携帯電話に多くの問題を抱えています。そのため、リスナーのコールバックが実行されるとき、dom は準備ができていません。

したがって、選択を管理しようとしているため、機能しません。タイムアウトを設定すると、その関数は 4 ミリ秒後に実行されるため、DOM が範囲を指定して変更を永続化し、実行しようとしている変更を行うのに十分な時間です。

実際、ブラウザーは機能するために関数の実行を延期する必要はありません。理論的には、コードは なしで正しいですsetTimeoutが、この「バグ」は、DOM の変更によってトリガーされるリスナーを操作するときにさまざまな方法で見つけることができます。

あなたが知っているだけです。私のデスクトップ ブラウザでは正常に動作しますが、ネットブックで実行すると、setTimout を使用する必要があります。

于 2013-01-18T01:25:41.407 に答える