Добавить узел в contenteditable «div», где находится курсор (при нажатии на кнопку)

0

Я пытаюсь создать кусок кода в javascript для добавления узла ("span", "strong"...) в контентном "div", где находится карет (когда я нажимаю кнопку ")".

Я начал думать о коде вроде этого (он не работает, это просто начало): http://jsfiddle.net/Md8KX/2/

HTML:

<div id="myDiv" contenteditable="true">
    <strong>Test:</strong> This is a <strong>really</strong> good test.
</div>
<button type="button" id="myButton">Add a span</button>

CSS:

#myDiv{padding:15px;border:solid 1px #000;}

JS:

// Variable to stock the caret position
var caretPosition = 0;

// Event to get caret position on keyup and on blur
$('#myDiv').on('keyup focus', function () {
    caretPosition = getCaretPosition(this);
});

// Event to add node when click on button
$('#myButton').on('click', function (e) {
    e.preventDefault();
    addNode(this, caretPosition, '<span>Node</span>');
});

// Function to get caret position with 1 param : the editable box
var getCaretPosition = function (editableBox) {
    var position = 0;
    // TO DO : get caret position
    return position;
}

// Function to add node with 3 params : the editable box, the caret position and the node to add
var addNode = function (editableBox, caretPosition, nodeToAdd) {
    // TO DO : add node in element
}

Но я не имею абсолютно никакой идеи, чтобы получить позицию курсора, а затем вставить узел в этот момент :) Я прочитал вещи о свойстве "range" в javascript или "createTextRange", но я не уверен, что понимаю, и я не понимаю знаете, если это лучший способ сделать это.

У вас есть идея сделать это или трек, который может помочь мне начать, пожалуйста? Заранее спасибо!

  • 0
    Вот моя fiddle По схожему question . Надеюсь, это поможет вам.
  • 1
    stackoverflow.com/a/6691294/96100
Показать ещё 2 комментария
Теги:
contenteditable

2 ответа

0

Старый пост, я понял. Но это помогло мне совсем немного. Я нашел это решение где-то, извините, что не могу вспомнить, или я бы дал кредит.

function pasteHtmlAtCaret(html) {
var sel, range;
if (window.getSelection) {
    // IE9 and non-IE
    sel = window.getSelection();
    if (sel.getRangeAt && sel.rangeCount) {
        range = sel.getRangeAt(0);
        range.deleteContents();

        // Range.createContextualFragment() would be useful here but is
        // non-standard and not supported in all browsers (IE9, for one)
        var el = document.createElement("div");
        el.innerHTML = html;
        var frag = document.createDocumentFragment(), node, lastNode;
        while ( (node = el.firstChild) ) {
            lastNode = frag.appendChild(node);
        }
        range.insertNode(frag);

        // Preserve the selection
        if (lastNode) {
            range = range.cloneRange();
            range.setStartAfter(lastNode);
            range.collapse(true);
            sel.removeAllRanges();
            sel.addRange(range);
        }
    }
} else if (document.selection && document.selection.type != "Control") {
    // IE < 9
    document.selection.createRange().pasteHTML(html);
}
}
-1

Я создал рабочий пример для этого, хотя и не идеальный, я надеюсь, что он работает как основа того, чего вы хотите достичь. Это можно найти здесь: http://jsbin.com/jociy/2.

Это исходный код и он сам поясняет:

$(document).ready(function(){

  // helper function credit to http://stackoverflow.com/questions/3972014/get-caret-position-in-contenteditable-div
  function getCaretPosition(editableDiv) {
    var caretPos = 0, containerEl = null, sel, range;
    if (window.getSelection) {
        sel = window.getSelection();
        if (sel.rangeCount) {
            range = sel.getRangeAt(0);
            if (range.commonAncestorContainer.parentNode == editableDiv) {
                caretPos = range.endOffset;
            }
        }
    } else if (document.selection && document.selection.createRange) {
        range = document.selection.createRange();
        if (range.parentElement() == editableDiv) {
            var tempEl = document.createElement("span");
            editableDiv.insertBefore(tempEl, editableDiv.firstChild);
            var tempRange = range.duplicate();
            tempRange.moveToElementText(tempEl);
            tempRange.setEndPoint("EndToEnd", range);
            caretPos = tempRange.text.length;
        }
    }
    return caretPos;
  }

  // listener will keep track of caret position
  var position = 0;
  $('#myDiv').keyup(function() { 

     position = getCaretPosition(this);

  });

  // the special span element to insert
  var mySpan = "<span class='mySpan'>Yes!</span>";

  $("#myButton").on("click", function(){

    // sorry about this, this can and should be refactored
    var data1 = $("#myDiv").text().slice(0, position);
    var data2 = $("#myDiv").text().slice(position,$("#myDiv").text().length);

    $("#myDiv").html("<span>" + data1 + mySpan + data2 + "</span>");

  });


});

HTML-элементы для этого примера:

  <div id="myDiv" class="yellow foo" contenteditable="true">Zombie ipsum reversus ab viral inferno, nam rick grimes malum cerebro. De carne lumbering animata corpora quaeritis. Summus brains sit , morbo vel maleficia? De apocalypsi gorger omero undead survivor dictum mauris.</div>

  <button type="button" id="myButton">Add SPAN</button>

Некоторые стили, если хотите:

.foo {
  font-family: arial, sans-serif;
  margin: 10px;
  padding: 25px;
  opacity: 0.6;
}
.yellow {
  background-color: yellow;
  color: #000;
}
button {
  padding: 20px;
  margin-left: 10px;
  border: none;
  background-color: #ccc;
  color: #fff;
  font-weight: bold;
  text-shadow: 1px 1px 0px #888;
  text-transform: uppercase;
  cursor: pointer;
}
button:hover {
  opacity: 0.6;
}
.mySpan {
 background-color: red;
 color: yellow; 
}

Надеюсь это поможет!

  • 0
    К сожалению, это не то, что мне нужно :) В вашем примере вы используете свойство text (), которое не допускает одновременного использования нескольких узлов в contenteditable. Я думаю, что мы должны использовать свойство "html ()" и свойство "childNodes", но я не знаю как :) Но спасибо за помощь!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню