skip to Main Content

trying to create a Richt Texteditor in Javascript. I have a Tag

<span class="text-3xl">Foo</span>

and want to edit it to something like

<span class="text-3xl">F</span><span class="text-sm">o</span><span class="text-3xl">o</span>

My first attempt works, for inserting a Tag inside the other

<span class="text-3xl">F<span class="text-sm">o</span>o</span>

using this code:

  var spanElement= document.createElement("span");
  spanElement.className = size;
  var selection= window.getSelection().getRangeAt(0);
  var selectedText = selection.extractContents();
  elem.appendChild(selectedText);
  selection.insertNode(elem);


but need some help with closing/reopening the tag before/after the inner tag.

2

Answers


  1. Chosen as BEST ANSWER

    After reading some other threads, espacially Javascript: I can get the text of a selection, now how do I get the text outside the selection?

    is my temp solution

    function replaceOriginal(size) {
        var selection= window.getSelection().getRangeAt(0);
        var tagText = getOuterRange(findSelection());
        var parentNode =window.getSelection().focusNode.parentNode;
        var beforeTag= document.createElement("span");
        beforeTag.className = parentNode.className;
        beforeTag.innerHTML= tagText.before;
        var selectTag= document.createElement("span");
        selectTag.className = size;
        selectTag.innerHTML= tagText.selection;
        var afterTag= document.createElement("span");
        afterTag.className = parentNode.className;
        afterTag.innerHTML = tagText.after;
        parentNode.remove();
        selection.insertNode(afterTag);
        selection.insertNode(selectTag);
        selection.insertNode(beforeTag);
    
    
    }
    
    function getOuterRange(selection) {
        var rangeBefore = document.createRange();
        var rangeAfter = document.createRange();
        var r = selection.getRangeAt(0);
    
        rangeBefore.setStart(r.startContainer,0);
        rangeBefore.setEnd(r.startContainer,r.startOffset);
    
        rangeAfter.setStart(r.endContainer,r.endOffset);
        rangeAfter.setEnd(r.endContainer,r.endContainer.length);
    
        return {
            before: rangeBefore.toString(),
            selection: r.toString(),
            after: rangeAfter.toString()
        }
    }
    //returns the selection object.
    function findSelection(){
        var userSelection;
        if (window.getSelection) {
            userSelection = window.getSelection();
        } // Mozilla Selection object.
        else if (document.selection){
            userSelection = document.selection.createRange();
        } //gets Microsoft Text Range, should be second b/c Opera has poor support for it.
        if (userSelection.text){
            return userSelection.text
        } //for Microsoft Objects.
        else {
            return userSelection
        } //For Mozilla Objects.
    }

    That works as expected. Im in a learning process, coming from C#, so this feels really hacky and i think i need to read a bit/lot more to get it to a usable solution. So, every advise and/or recommendation to JS Books would be a great help too


  2. Once you have these two arrays:

    • character Array: ['F', 'o', 'o']
    • class Array: ['text-3xl', 'text-sm', 'text-3xl']

    You can build the string:

    <span class="text-3xl">F</span><span class="text-sm">o</span><span class="text-3xl">o</span>
    

    You’ll need to declare the class Array explicitly in your JavaScript.

    But you can extract the character Array from your original <span>.


    Working Example:

    // EXTRACT ARRAY OF CHARACTERS FROM ORIGINAL SPAN
    const originalSpan = document.querySelector('.original');
    const originalSpanText = originalSpan.textContent;
    const originalSpanTextArray = originalSpanText.split('');
    
    // DECLARE LIST OF CLASSES
    const classArray = ['text-3xl', 'text-sm', 'text-3xl'];
    
    // BUILD NEW HTML
    let newHTML = '';
    
    originalSpanTextArray.forEach((character, i) => {
      newHTML += `<span class="${classArray[i]}">${character}</span>`;
    });
    
    // LOG NEW HTML
    console.log(newHTML);
    <span class="original text-3xl">Foo</span>

    Further Reading:

    The example above uses a backtick-demarcated template literal:

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search