10

CKEditorで新しい段落を作成すると、前の段落の属性(スタイル、クラス)が新しい段落にコピーされます。これを防ぐ方法はありますか?

たとえば、中央の段落に書き込んでいて、Enterキーを押して新しい段落を作成する場合、ユーザーは新しい段落を単純なものにしたいと考えています。

デフォルトでは、前のものから何も「継承」しません。


編集

私はそれを(危険なほどテストされていない)Reinmarのヒントで動作させることができました。これが私が終わらせたものです。これが他の誰かに役立つことを願っています。ここで明白なエラーが表示された場合は、教えてください

CKEDITOR.on('instanceCreated', function(e) {
    e.editor.on('key', function(evt) {
        if (evt.data.keyCode === 13) {
            // if we call getStartElement too soon, we get the wrong element
            setTimeout(function () {
                var se = e.editor.getSelection().getStartElement();
                if(se.getName() == "span") {
                    var text = se.getText(); // Store text, we are about to nuke the spans
                    while (se.getName() == "span") { // possible infinite loop danger
                        se = se.getParent();
                    }
                    if (text.length == 0)
                        se.setHtml(" "); // It's important that this is not empty
                    else
                        se.setHtml(text);
                }
                debug(se.getHtml());
                se.removeAttribute("class");
                se.removeAttribute("mycustomattr");
                se.removeAttribute("myothercustomattr");
                window.bla = se; // useful for debugging
            }, 10);
        }
    });
}); 
4

3 に答える 3

12

今後のCKEditorv4(現在のナイトリー)でも同様の問題が発生しました。カスタム画像ブラウザから画像とカスタムクラスを含む段落を挿入すると、CKEditorは画像の後に作成された段落にクラスをコピーし続けました。

keyイベントの後にの呼び出しのアイデアが気に入らなかったsetTimeoutので、ソースを少し調べてみると、非常に単純であることがわかりました。

Enterキーを押すと、CKEditorは実際にenterコマンドを発行します。あなたがする必要があるのは、afterCommandExecイベントを設定し、新しく作成された空の要素を見つけることです:

editor.on('afterCommandExec', function (e) {
    if (e.data.name == 'enter') {
        var el = e.editor.getSelection().getStartElement();

        // when splitting a paragrah before it's first character,
        // the second one is selected
        if (el.getHtml() != '<br>') {
            if (el.hasPrevious() && el.getPrevious().getHtml() == '<br>') {
                el = el.getPrevious();
            } else {
                // both paragraphs are non-empty, do nothing
                return;
            }
        }

        // modify el according to your needs
    }
});

お役に立てれば!

于 2012-11-15T15:20:45.937 に答える
2

私はこの2日間あなたの質問について考えていました、そして私は考えを持っています。プラグインコードの入力をチェックしましたが、そのままにしておくことをお勧めします。代わりに、Enterキーを聞くことができ、カスタムEnterを実行した後、新しく作成されたブロックからスタイルをクリアする必要があります。

これらの方法は便利です:

  • editor.on( 'key', function( evt ) { evt.data.key... } )
  • editor.getSelection().getStartElement()-入力後、選択開始は新しく作成されたブロックに配置されます(+太字、下線などのインライン要素)。
  • CKEDITOR.dtd.*-要素のセットは、どの要素がインラインスタイルであり、削除する必要があるかを判断するのに役立つ場合があります。
  • element.isEmptyInlineRemoveable-カーソルが置かれた空のインライン要素を削除する必要があります。
  • editor.createRange().setStartAt( block, 0 ).select()-最後に、カレットを正しい場所に配置する必要があります(ブロックの先頭- <p>/ <div>/ <li>/ etc。)。

残念ながら、ご覧のとおり、これを書くのは簡単ではないので、頑張ってください:)

于 2012-10-18T07:09:08.840 に答える
2

これは古い投稿ですが、私はこれと同じ問題を抱えていて、ようやく何かが機能するようになったので、解決策を共有したいと思いました。なぜこの機能が必要なのかわからない人のために、ここに私の説明があります:

デフォルトでは、CKEDITORは、Enterキーを押して新しい行を挿入するときに、ユーザーが同じスタイルを続行できるようにします。つまり、テキストが太字で中央揃えになっているときにEnterキーを押すと、ckeditorはそのスタイルを複製して、新しい行も太字で中央揃えになります。これは、属性を持つネストされた要素(プラグインなど)など、より複雑なものを挿入するまでは便利です。クラスを持つ要素内でEnterキーを押すと、ckeditorは同じクラスで新しい段落要素を作成しますが、そのクラスが親要素の存在に依存している場合は機能しません(これが問題になる例は次のとおりです:http: //jsfiddle.net/B4yGJ/158/)。

私が思いついたソリューションは、ReinmarとNenotlepからのコードと提案を組み合わせたものです。

// create object of safe classes
var safe_classes = {};
$.each(ckeditor_styles_full, function(i, style) {
    if(style['attributes']) {
        var style_classes = style['attributes'].class;
        var style_element = style['element'];

        if(typeof safe_classes[style_element] != "object") {
            safe_classes[style_element] = [];
        }

        style_classes = style_classes.split(" ");
        $.each(style_classes, function(i, v) {
            if($.inArray(v, safe_classes[style_element]) <= -1) {
                safe_classes[style_element].push(v);
            }
        });
    }
});

$.each(CKEDITOR.instances, function(i, editor) {
    editor.on('key', function(e) {
        if (e.data.keyCode === 13) {
            setTimeout(function () {
                var se = e.editor.getSelection().getStartElement();
                var parent = se.getParent().getName();
                if(parent == "html" || parent == "body") {
                    var se_classes = se.getAttribute('class');
                    var new_classes = [];
                    se.removeAttribute("class");

                    if(se_classes !== null) {
                        se_classes = se_classes.split(" ");
                        $.each(se_classes, function(i, v) {
                            if(typeof safe_classes[se.getName()] != 'undefined') {
                                if($.inArray(v, safe_classes[se.getName()]) > -1) {
                                    se.addClass(v);
                                }
                            }
                        });
                    }
                }
            }, 10);
        }
    });
});

仕組みは次のとおりです。最初に、スクリプトはクラス名の選択されたスタイルリストを取得し、要素タイプごとにそれらをオブジェクトにコンパイルします。次に、イベントをEnterキーにバインドするCKEDITORのすべてのインスタンスを繰り返します。次に、Enterキーを押したときに作成された要素が、HTMLまたはBODY以外の親要素内にあるかどうか(つまり、より大きな要素ツリーの一部であるかどうか)を確認します。最後に、コンテナ要素内にない場合は、前に作成した「safe_classes」オブジェクトにないすべてのクラスをその要素から削除します。

2つの重要な注意事項:1)「forceEnterMode:true」を設定する必要があります。2)「forceEnterMode」はtrueに設定されているため、段落要素のみをネストすることをお勧めします。例:

<div class="container"><p class="title">Title Text</p><p class="content">Content Goes Here</p></div>

それ以外の場合、ネストされたdiv内でEnterキーを押すと、ckeditorはそのdivのすべての属性を段落要素に複製します。

于 2014-08-13T00:34:24.587 に答える