简体   繁体   English

在contentEditable div中的inserted元素后面设置插入位置

[英]Set caret position right after the inserted element in a contentEditable div

I'm inserting an element into a contentEditable div but the browser sets the position of the cursor before the inserted element. 我正在将一个元素插入到contentEditable div中,但浏览器会在插入的元素之前设置光标的位置。 Is it possible to set the cursor right after the inserted element so that the user keeps typing without having to re-adjust the cursor position? 是否可以在插入的元素后面设置光标,以便用户不必重新调整光标位置就可以输入?

The following function will do it. 以下功能将执行此操作。 DOM Level 2 Range objects make this easy in most browsers. DOM Level 2 Range对象使这在大多数浏览器中变得容易。 In IE, you need to insert a marker element after the node you're inserting, move the selection to it and then remove it. 在IE中,您需要在插入的节点后插入标记元素,将选择移动到它,然后将其删除。

Live example: http://jsfiddle.net/timdown/4N4ZD/ 实例: http//jsfiddle.net/timdown/4N4ZD/

Code: 码:

function insertNodeAtCaret(node) {
    if (typeof window.getSelection != "undefined") {
        var sel = window.getSelection();
        if (sel.rangeCount) {
            var range = sel.getRangeAt(0);
            range.collapse(false);
            range.insertNode(node);
            range = range.cloneRange();
            range.selectNodeContents(node);
            range.collapse(false);
            sel.removeAllRanges();
            sel.addRange(range);
        }
    } else if (typeof document.selection != "undefined" && document.selection.type != "Control") {
        var html = (node.nodeType == 1) ? node.outerHTML : node.data;
        var id = "marker_" + ("" + Math.random()).slice(2);
        html += '<span id="' + id + '"></span>';
        var textRange = document.selection.createRange();
        textRange.collapse(false);
        textRange.pasteHTML(html);
        var markerSpan = document.getElementById(id);
        textRange.moveToElementText(markerSpan);
        textRange.select();
        markerSpan.parentNode.removeChild(markerSpan);
    }
}

Alternatively, you could use my Rangy library . 或者,您可以使用我的Rangy库 The equivalent code there would be 那里的等价代码

function insertNodeAtCaret(node) {
    var sel = rangy.getSelection();
    if (sel.rangeCount) {
        var range = sel.getRangeAt(0);
        range.collapse(false);
        range.insertNode(node);
        range.collapseAfter(node);
        sel.setSingleRange(range);
    }
}

If you're inserting an empty div, p or span, I believe there needs to be "something" inside the newly created element for the range to grab onto -- and in order to put the caret inside there. 如果你要插入一个空的div,p或span,我相信在新创建的元素中需要有“东西”才能抓住范围 - 以便将插入符号放在那里。

Here's my hack that seems to work OK in Chrome. 这是我的黑客,似乎在Chrome中运行正常。 The idea is simply to put a temporary string inside the element, then remove it once the caret is in there. 这个想法只是在元素中放入一个临时字符串,然后在插入符号后将其删除。

// Get the selection and range
var idoc = document; // (In my case it's an iframe document)
var sel = idoc.getSelection();
var range = sel.getRangeAt(0);

// Create a node to insert
var p = idoc.createElement("p"); // Could be a div, span or whatever

// Add "something" to the node.
var temp = idoc.createTextNode("anything");
p.appendChild(temp);
// -- or --
//p.innerHTML = "anything";

// Do the magic (what rangy showed above)
range.collapse(false);
range.insertNode( p );
range = range.cloneRange();
range.selectNodeContents(p);
range.collapse(false);
sel.removeAllRanges();
sel.addRange(range);

// Clear the non
p.removeChild(p.firstChild);
// -- or --
//p.innerHTML = "";

Here's what worked for me, using Rangy, in a VueJS context. 这是在VueJS环境中使用Rangy对我有用的东西。

// When the user clicks the button to open the popup to enter
// the URL, run this function to save the location of the user's
// selection and the selected text.
newSaveSel: function() {
  if (this.savedSel) {
    rangy.removeMarkers(this.savedSel);
  }
  // Save the location of the selected text
  this.savedSel = rangy.saveSelection();
  // Save the selected text
  this.savedSelText = rangy.getSelection().toString();
  this.showLinkPopup = true;
  console.log('newSavedSel', this.savedSel);
},
surroundRange: function() {
  // Restore the user's selected text. This is necessary since
  // the selection is lost when the user stars entering text.
  if (this.savedSel) {
    rangy.restoreSelection(this.savedSel, true);
    this.savedSel = null;
  }
  // Surround the selected text with the anchor element
  var sel = rangy.getSelection();

  var range = sel.rangeCount ? sel.getRangeAt(0) : null;
  if (range) {
    // Create the new anchor element
    var el = document.createElement("a");
    el.style.backgroundColor = "pink";
    el.href = this.anchorHref;
    el.innerHTML = this.savedSelText;
    if (this.checked) {
      el.target = "_blank";
    }
    // Delete the originally selected text
    range.deleteContents();
    // Insert the anchor tag
    range.insertNode(el);
    // Ensure that the caret appears at the end
    sel.removeAllRanges();
    range = range.cloneRange();
    range.selectNode(el);
    range.collapse(false);
    sel.addRange(range);
    this.showLinkPopup = false; 
  }
},

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在contenteditable div中设置插入符位置 - Set caret position in contenteditable div 如何在 contenteditable 元素(div)中设置插入符号(光标)position? - How to set the caret (cursor) position in a contenteditable element (div)? 在contenteditable div中的插入位置之前和之后获取节点/元素 - Get node/element before and after caret position in contenteditable div 将插入符号位置设置在contenteditable div中的特定位置 - Set caret position at a specific position in contenteditable div 在contenteditable div中创建新元素后设置插入符号 - Set caret after creating new element in contenteditable div 在有孩子的 'contenteditable' div 中设置插入符号 Position - Set Caret Position in 'contenteditable' div that has children 在ContentEditable的focus()之后移动插入符号的位置<DIV> - Move caret position after focus() for ContentEditable <DIV> 将插入符号设置为脱机后的内容可编辑div - Set caret to end in contenteditable div of after the dealine 在contenteditable div中重新生成innerHTML后如何在单词中间设置插入符号位置 - How to set caret position in middle of word after regenerating innerHTML within contenteditable div 修复 contenteditable div 上的插入符号位置 - Fix caret position on contenteditable div
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM