1

コンテンツの編集可能なdivがあります。<pre>some code</pre>この中にタグを挿入しています。このタグは、ユーザーがSOと同様にフォーマットされたコードを入力できるように設計されています。

私が抱えている問題は、FFが<br>\ r \ nの代わりにタグを挿入していることです。これは通常のHTMLでは正しいですが、事前に\ r\nが必要です。

contenteditableの親にデリゲートをアタッチしてみました。ただし、これはネストされたdom要素に対しては起動しません。それで

$('#contenteditablediv').delegate('pre', 'keyup', function() { ... });

発火しません。また、親divで通常のキーアップを処理し、preタグのすべてのbrを\ r\nに置き換えてみました。しかし、これはカレットを台無しにし、不格好です。

これを行うための好ましい方法はありますか?

サーバー側でそれらを取り除くことに頼らなければならないかもしれませんが、私はむしろしたくありません。

どうもありがとう

4

2 に答える 2

5

私は実際に解決策を見つけました。それは完璧ではなく、Mrchiefが提案したようにコードミラーの統合を検討しています。唯一の問題は、現在のソリューションでは、バックエンドに保存されて後で表示されるマークアップを編集できることです。まさにWYSIWYGです。私のエディターは、いくつかのコードフラグメントを追加したい、より優れたコンテンツ編集可能な記事の一部であることを述べておかなければなりません。

codemirrorのようなエディターを使用するのは素晴らしいことですが、保存する前にそれを取り除く必要があり、コードブロックをtextareaとして表示する必要があります(以前のRSSフレンドリーではありません)。

とにかく、ここに興味がある人は私の解決策/ハックです。


<pre>を含む要素でラップされている限り、contenteditablesのネストされたタグなどからイベントを委任できますcontenteditable="false"。したがって、挿入する代わりに:

<pre>some code</pre

私が挿入した:

<code contenteditable="false"><pre>code snippet here</pre></code>

次に、そのような代理人を追加しました。

var getFirstRange = function() {
    var sel = rangy.getSelection();
    return sel.rangeCount ? sel.getRangeAt(0) : null;
}

contenteditablediv
    .delegate('pre', 'keydown', function(event) { 
        switch(event.keyCode) {
            case 13:
                var range = getFirstRange(), 
                    added = false,
                    newline = document.createTextNode('\r\n');

                if (range) {
                    range.insertNode(newline);              
                    range.setEndAfter(newline);
                    range.setStartAfter(newline);
                    var sel = rangy.getSelection();
                    sel.setSingleRange(range)
                    added = true;
                } 

                if (added) {
                    event.preventDefault();
                }
                break;
            case 9:
                // insert a tab
                var range = getFirstRange(),
                    tab = document.createTextNode('\t');
                if (range) {
                    range.insertNode(tab);
                    var sel = rangy.getSelection();
                    range.setEndAfter(tab);
                    range.setStartAfter(tab);
                    sel.setSingleRange(range)
                } 
                return false;   
        }
    }).delegate('pre', 'click', function() { 
        $(this).attr('contenteditable', true);
    }).delegate('pre', 'blur', function() {
        $(this).removeAttr('contenteditable');
    });

このイベントが発生します。クリック/ぼかし削除を追加して、内側のpreタグでcontenteditableを切り替えて、これが後で保存されないようにしましたが、サーバー側で実行できます。これにより、タブキーに\ t文字を挿入し、brの代わりに\ r\nを挿入できます。

于 2011-07-27T01:55:42.573 に答える
1

簡単な答え:サーバー側で実行してください。contentEditablediv内はすべてテキストです。したがって、あなたdelegateは決して発砲しません。

また、これらすべてをすでに処理している可能性のあるcodemirrorプラグインを確認することをお勧めします。

于 2011-07-27T01:05:24.393 に答える