如何在另一个div的内容中插入div?

时间:2013-06-25 14:54:44

标签: javascript jquery css

如何在另一个内容可编辑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 个答案:

答案 0 :(得分:2)

这似乎对我有用。我刚刚添加了$(this).append(...)

$("#target").keydown(function(e) {

//  console.log(e, String.fromCharCode(e.which));

  if(e.which === 50 && e.shiftKey === true ){
      if(flag === true){
        flag = false;      
        return;
      }      
      flag = true;
    $(this).append('<div id="target2" contenteditable="true">New Div</div>');
      //console.log($('#target'),$('#target').prop('selectionStart'));
    } 
});

答案 1 :(得分:1)

一个选项是检测'@'字符上的keydown事件,然后在当前光标位置放置一个绝对定位的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);

他们的小提琴是here,它是为回应this question.

而写的

小提琴包括在当前光标位置放置一个新div。

答案 2 :(得分:0)

我修改了onKeyDown事件监听器。 将keydown事件绑定到id等于target的div。

希望这对你有所帮助。 http://jsbin.com/ilikay/4/edit

答案 3 :(得分:-1)

终于有办法达到它......这就是我做到的......

  1. 使用selectionStart
  2. 获取textarea中光标位置的字符串索引
  3. 将字符串从索引0切片到光标位置
  4. 将其插入跨度(因为span具有多个边框)
  5. 使用相对于视口的element.getClientRects()获取边框的尺寸。 (这是MDN Reference
  6. 计算顶部和左侧并将其提供给下拉列表
  7. 这适用于所有最新的浏览器。没有在旧的测试

    这是Working bin