2

別のコンテンツ編集可能な div のコンテンツ内に div を挿入するにはどうすればよいですか? 親 div はコンテンツ編集可能なものであり、文字列コンテンツが含まれています。カーソル位置に「@」と入力すると、別のコンテンツ編集可能な div を挿入したいと考えています。

例えば、

 <div id="target" class="text-area" contenteditable='true'>This text can be anything... how to insert a div when i type start typing @... </div>

「@」を入力したときに別の div を挿入したいですか? どうすればこれを達成できますか?

これが私がJSBINを試したものです

私を助けてください。前もって感謝します

4

4 に答える 4

1

1 つのオプションは、'@' 文字のキーダウン イベントを検出し、現在のカーソル位置に絶対位置の div を配置することです。

カーソル位置を取得するのは、まともなコードです。幸いなことに、誰かがすでにそれを書いています。コードは次のとおりです。

function getTextAreaXandY() {



   // Don't do anything if key pressed is left arrow
    if (e.which == 37) return;     

    // Save selection start
    var selection = $(this).getSelection();
    var index = selection.start;

    // Copy text to div
    $(this).blur();
    $("div").text($(this).val());

    // Get current character
    $(this).setSelection(index, index + 1);
    currentcharacter = $(this).getSelection().text;

    // Get previous character
    $(this).setSelection(index - 1, index)
    previouscharacter = $(this).getSelection().text;

    var start, endchar;
    var end = 0;
    var range = rangy.createRange();

    // If current or previous character is a space or a line break, find the next word and wrap it in a span
    var linebreak = previouscharacter.match(/(\r\n|\n|\r)/gm) == undefined ? false : true;

    if (previouscharacter == ' ' || currentcharacter == ' ' || linebreak) {
        i = index + 1; // Start at the end of the current space        
        while (endchar != ' ' && end < $(this).val().length) {
            i++;
            $(this).setSelection(i, i + 1)
            var sel = $(this).getSelection();
            endchar = sel.text;
            end = sel.start;
        }

        range.setStart($("div")[0].childNodes[0], index);
        range.setEnd($("div")[0].childNodes[0], end);
        var nextword = range.toHtml();
        range.deleteContents();
        var position = $("<span id='nextword'>" + nextword + "</span>")[0];
        range.insertNode(position);
        var nextwordtop = $("#nextword").position().top;
    }

    // Insert `#caret` at the position of the caret
    range.setStart($("div")[0].childNodes[0], index);
    var caret = $("<span id='caret'></span>")[0];
    range.insertNode(caret);
    var carettop = $("#caret").position().top;

    // If preceding character is a space, wrap it in a span
    if (previouscharacter == ' ') {
        range.setStart($("div")[0].childNodes[0], index - 1);
        range.setEnd($("div")[0].childNodes[0], index);
        var prevchar = $("<span id='prevchar'></span>")[0];
        range.insertNode(prevchar);
        var prevchartop = $("#prevchar").position().top;
    }

    // Set textarea selection back to selection start
    $(this).focus();
    $(this).setSelection(index, selection.end);

    // If the top value of the previous character span is not equal to the top value of the next word,
    // there must have been some wrapping going on, the previous character was a space, so the wrapping
    // would have occured after this space, its safe to assume that the left and top value of `#nextword`
    // indicate the caret position
    if (prevchartop != undefined && prevchartop != nextwordtop) {
        $("label").text('X: ' + $("#nextword").position().left + 'px, Y: ' + $("#nextword").position().top);
        $('ul').css('left', ($("#nextword").position().left) + 'px');
        $('ul').css('top', ($("#nextword").position().top + 13) + 'px');
    }
    // if not, then there was no wrapping, we can take the left and the top value from `#caret`    
    else {
        $("label").text('X: ' + $("#caret").position().left + 'px, Y: ' + $("#caret").position().top);
        $('ul').css('left', ($("#caret").position().left) + 'px');
        $('ul').css('top', ($("#caret").position().top + 14) + 'px');
    }

    $('ul').css('display', 'block');
}

$("textarea").click(getTextAreaXandY);
$("textarea").keyup(getTextAreaXandY);

彼らのフィドルはここにあり、この質問への回答として書かれています。

フィドルには、現在のカーソル位置に新しい div を配置することが含まれます。

于 2013-06-25T16:12:10.907 に答える
0

onKeyDown イベントリスナーを修正しました。keydown イベントを、ID が target と等しい div にバインドします。

これがお役に立てば幸いです。 http://jsbin.com/ilikay/4/edit

于 2013-06-25T15:10:32.393 に答える
-1

ついに到達する方法がありました...これが私がやった方法です...

  1. selectionStart を使用して、テキストエリア内のカーソル位置の文字列インデックスを取得します
  2. 文字列をインデックス 0 からカーソル位置までスライスする
  3. スパンに挿入します(スパンには複数のボーダーボックスがあるため)
  4. ビュー ポートに相対的な element.getClientRects() を使用して、ボーダー ボックスの寸法を取得します。(ここにMDN リファレンスがあります)
  5. 上と左を計算し、ドロップダウンに入力します

これは、最新のすべてのブラウザーで機能します。古いものでテストしていない

作業ビンはこちら

于 2013-06-27T17:31:36.843 に答える