13

contenteditable で順序付けされていない (または順序付けられた) リストを操作すると、頭痛の種になります。

2回押してリストの編集を終了したいときはいつでもENTER、ブラウザは閉じます<ul />が、. 例はこちら<p /><div /><br />

私の目標は、その余分な<p />or を回避し<div />、代わりに<ul />. 私は、ブラウザが挿入するのを妨げたり 、押したときに代わりにクリーンタグを挿入したりするTim Downの
ソリューション を変更しようとしました。例はこちら<p /><div />ENTER<br />

残念ながら、そのソリューションを使用すると、アイテムにタグのみが挿入される<ul />ため、ブラウザーによって閉じられることはありません。<br /><li />

だから私の質問は:

<ul />最後の空の で Enter キーを押すと、ノードを挿入するか html を貼り付けて、アクティブに閉じるにはどうすればよい<li />ですか?

更新:質問がまだ不明確な場合: タグを挿入せずに、代わりに古き良きプレーンを挿入するだけでを閉じる方法を探しています<ul /><p /><div /><br />

4

3 に答える 3

7

あなたの試みと同様に、ユーザーが Enter キーを押したときに contenteditable を変更します:デモ

if (window.getSelection) { // w3c
    $('div').keypress(function (e) {
        var sel, node, children, br, range;
        if (e.which == 13) {
            sel = window.getSelection();
            node = $(sel.anchorNode);
            children = $(sel.anchorNode.childNodes);

            // if nothing is selected and the caret is in an empty <li>
            // (the browser seems to insert a <br> before we get called)
            if (sel.isCollapsed && node.is('li') && (!children.length ||
                    (children.length == 1 && children.first().is('br')))) {
                e.preventDefault();

                // if the empty <li> is in the middle of the list,
                // move the following <li>'s to a new list
                if (!node.is(':last-child')) {
                    node.parent().clone(false)
                        .empty()
                        .insertAfter(node.parent())
                        .append(node.nextAll());
                }

                // insert <br> after list
                br = $('<br>').insertAfter(node.parent());

                // move caret to after <br>
                range = document.createRange();
                range.setStartAfter(br.get(0));
                range.setEndAfter(br.get(0));
                sel.removeAllRanges();
                sel.addRange(range);

                // remove <li>
                node.remove();
            }
        }
    });

} else if (document.selection) { // internet explorer
    $('div').keypress(function (e) {
        var range, node, children;
        if (e.which == 13) {
            range = document.selection.createRange();
            node = $(range.parentElement());
            children = $(range.parentElement().childNodes);

            // if nothing is selected and the caret is in an empty <li>
            // (the browser seems to insert a <br> before we get called)
            if (!range.htmlText.length && node.is('li') && (!children.length ||
                    (children.length == 1 && children.first().is('br')))) {
                e.preventDefault();

                // if the empty <li> is in the middle of the list,
                // move the following <li>'s to a new list
                if (!node.is(':last-child')) {
                    node.parent().clone(false)
                        .empty()
                        .insertAfter(node.parent())
                        .append(node.nextAll());
                }

                // insert <br> after list
                br = $('<br>').insertAfter(node.parent());

                // move caret to after <br>
                range = document.body.createTextRange();
                range.moveToElementText(br.get(0));
                range.collapse(false);
                range.select();

                // remove <li>
                node.remove();
            }
        }
    });
}

これは、ユーザーが Enter キーを押す前に何かを選択した場合を処理しないことに注意してください。このケースを処理したい場合は、ユーザーがコンテンツ全体を選択したかどうかを確認する必要があります<li>(これは簡単な作業ではないようです)。そうであれば、コンテンツを削除して、ユーザーが空の で Enter キーを押した場合<li>

于 2013-01-29T10:34:56.590 に答える
1

私はあなたの質問を理解していますが、なぜそのような要件が存在するのかは明らかではありません。その側面を明確にするのに役立つかもしれません。

とにかく、ここに1つのアイデアがあります。<div>空のタグとタグを交換または削除してみませんか<p>

$(document).ready(function(){
    $("div").keyup(function(evt) { 
        $("div, p").filter( function() {
                $this = $(this);
            return !($.trim($(this).text()).length);
        }).replaceWith('<br />');
    });
});

実例:http: //jsfiddle.net/4xyR2/9/

私が気付いた問題の1つcontenteditableは、上記のソリューションを使用したカーソルにどのように影響するかに関するものです。<div>ChromeとFirefoxにはとが必要だと思う<p>ので、カーソルがのどこにあるかを追跡できます<div>。これは、ブラウザの解釈についての深い理解からではなく、テスト中の私の観察から来ていますcontenteditable

Chrome(24.0.1312.52 m)は、交換を嫌うようです。テストすると奇妙なカーソル配置が表示されますが、機能します。Firefox(17.0.1)は、置き換えを適切に処理します。

于 2013-01-26T04:50:36.417 に答える
0

Javascriptなしでワークアウトできた最高のものは

HTML:

<div contenteditable="true">
  <div>asdfasdf</div>
</div>

以下:

div[contenteditable=true] {
  outline: none;

  &>p,
  &>div {
      margin: 0 0 0 30px;
      display: list-item;
  }
}

ビンhttp://jsbin.com/idekix/6/edit

しかし、ここにはいくつかの欠点があります。

  1. Win8 上の最初の非常に大きな FireFox 18.0.1 では、代わりにdivorpタグを新しい行として挿入し、 doublebrのようなものを使用します。

  2. 2番目は、すべてを削除してタイプを開始してEnterキーを押すと、ブラウザの動作が大きく異なり、Chromeはcontenteditableコンテナのテキストノードとして最初の行を挿入し、すべての新しい行をに入れるよりもdiv、Opera 12.12がそれをよりよく処理し、最後のdivノードを削除できます.IE9-10はジャンプを開始し、再度開始した後はp代わりにタグを使用しますdiv(それはそのような災害ではなく、一貫性がないだけです)が、FireFoxはまだそのbr動作を変更しようとさえしていません. また、IE10デバッグモードでIE7-8をチェックアウトしようとしていますが、実際のブラウザではありませんが、Operaと同じです。

  3. 空のノードを挿入できる 3 つ目は、Opera によって行われた優れた仕事について言えば、Opera http://jsbin.com/uxesez/1/editでこのビンを参照してください。マークアップはここでオリジナルにより近くなっています。 empty を挿入することはできませんli

つまり、すべてのテストは Windows 8 64 ビット プラットフォームで実行され、Chrome 24.0.1312.56 m、FireFox 18.0.1、Opera 12.12、および IE デバッグ バーによって古い IE をエミュレートする IE10 が使用されています。他のプラットフォーム/バージョンでは状況が異なる可能性があることを認めてください。

上記のすべてを要約すると、contenteditable非常に優れたブラウザー サポート範囲http://caniuse.com/contenteditableがありますが、すべてのブラウザーには独自の実装があります。これは別の理由です。したがって、クロスブラウザ JavaScrpt の手間がなければ、それを使用することはできません。また、私の個人的な意見として、ブラウザーのほぼすべてのリッチ テキスト エディターの要素として使用する場合contenteditableの軽量な置き換えのような、コア アイデアの方が適しています。iframe

Mozilla ソースからの UPD https://developer.mozilla.org/en-US/docs/HTML/Content_Editable

HTML5 では、どの要素も編集可能です。この機能はかなり前に導入されましたが、現在は WHATWG (html 現在の仕様) によって標準化されています。一部の JavaScript イベント ハンドラーを使用すると、Web ページを完全で高速なリッチ テキスト エディターに変換できます。

次のステップは、私のささやかな提案です。私の意見では、代わりに実際の編集可能なフィールドを使用すると便利です。このビンhttp://jsbin.com/ojiyok/7/editに行った非常に多くのプロトタイプバージョンにはまだ改善の余地がありますが、実際よりも予測可能な動作をしているように見えconteneditablesます。一度にすべてのブラウザで必要です。

于 2013-01-31T15:20:25.757 に答える