代码之家  ›  专栏  ›  技术社区  ›  x-rw

一个新div中的每个单词

  •  8
  • x-rw  · 技术社区  · 6 年前

    我想要光标在文本区域的正常行为,请在chrome浏览器上试试。

    我用的是 contenteditable 但它应该像短信区一样工作, 每一个单词都必须在一个非常必要的范围内,我不想用纯文本

    对于每个空格,每个书写的单词都必须成为div或SPAN, 光标应该正常工作

    例子:

            "hello word" for the space the result will is 
             <div>hello</div>
    
    
             imagine that the second space is after the word "word", 
             for the second space the result will is 
             <div>hello</div><div>word</div>
    
            and written spacebar before the caracter 'r'
            the result will is <div>hello</div><div>wo</div><div>rd</div>
    

    window.onload = function() {
      document.getElementById('test').addEventListener('keyup', function(e) {
        if (e.which === 32) {
          var parent = document.getElementById("test");
          var range = document.createRange();
          var selection = window.getSelection();
          var number = window.getSelection().anchorNode.parentNode.id;
    
          convertirEnSpans();
          agregarIds();
          //parent.childNodes[parseInt(number) + 1] el nodo siguiente
          //el cursor debe situarse en el inicio del nodo siguiente
          if (parent.childNodes[parseInt(number) + 1] !== undefined) { //comprobamos que exista el nodo siguiente
            var element = parent.childNodes[parseInt(number) + 1];
            range.setStart(element, 0);
            range.collapse(true);
            selection.removeAllRanges();
            selection.addRange(range);
            element.focus();
          }
        }
      });
    
      function convertirEnSpans() {
        let text = document.getElementById('test');
        let spans = text.getElementsByTagName('span');
        if (spans.length > 0) {
          text = '';
          for (var i = 0; i < spans.length; i++) {
            text += spans[i].innerHTML + ' ';
          }
          text = text.substring(0, text.length - 1);
        } else {
          text = text.innerHTML;
        }
    
        var wordsWithSpan = text.split(' ').map(function(c) {
          return '<span class="word">' + c + '</span>';
        }).join('');
    
        document.getElementById('test').innerHTML = wordsWithSpan;
      }
    
      function agregarIds() { //agregamos ids para saber en que nodo esta en cursor
        text = document.getElementById('test');
        let nodeSpans = text.getElementsByTagName('span');
        for (var i = 0; i < nodeSpans.length; i++) {
          nodeSpans[i].id = i;
        }
      }
    }
    .word {
      color: red;
      padding-right: 2px;
    }
    
    div {
      border: 1px solid;
      margin: 50px;
    }
    <div contenteditable="true" id="test">
    </div>

    我不能让光标正常工作,光标跳到各个部位,怎么解决呢?

    我只对SpaceBar感兴趣, 不要用回车键尝试

    更新@durgeshahire的答案
    但是在单词中间写错误仍然存在。

    window.onload = function() {
      document.getElementById('test').addEventListener('keyup', function(e) {
        if (e.which === 32) {
          var parent = document.getElementById("test");
          var range = document.createRange();
          var selection = window.getSelection();
          var number = window.getSelection().anchorNode.parentNode.id;
    
          convertirEnSpans();
          agregarIds();
    
          //parent.childNodes[parseInt(number) + 1] el nodo siguiente
          //el cursor debe situarse en el inicio del nodo siguiente
          if (parent.childNodes[parseInt(number) + 2] !== undefined) { //comprobamos que exista el nodo siguiente
            var element = parent.childNodes[parseInt(number) + 1];
            range.setStart(element, 0);
            range.collapse(true);
            selection.removeAllRanges();
            selection.addRange(range);
            element.focus();
          } else {
            setEndOfContenteditable(parent);
          }
        }
      });
    
    
      function setEndOfContenteditable(contentEditableElement) {
        var range, selection;
        if (document.createRange) { //Firefox, Chrome, Opera, Safari, IE 9+
          range = document.createRange(); //Create a range (a range is a like the selection but invisible)
          range.selectNodeContents(contentEditableElement); //Select the entire contents of the element with the range
          range.collapse(false); //collapse the range to the end point. false means collapse to end rather than the start
          selection = window.getSelection(); //get the selection object (allows you to change selection)
          selection.removeAllRanges(); //remove any selections already made
          selection.addRange(range); //make the range you have just created the visible selection
        } else if (document.selection) //IE 8 and lower
        {
          range = document.body.createTextRange(); //Create a range (a range is a like the selection but invisible)
          range.moveToElementText(contentEditableElement); //Select the entire contents of the element with the range
          range.collapse(false); //collapse the range to the end point. false means collapse to end rather than the start
          range.select(); //Select the range (make it the visible selection
        }
      }
    
    
    
      function convertirEnSpans() {
        let text = document.getElementById('test');
        let spans = text.getElementsByTagName('span');
        if (spans.length > 0) {
          text = '';
          for (var i = 0; i < spans.length; i++) {
            text += spans[i].innerHTML + ' ';
          }
          text = text.substring(0, text.length - 1);
        } else {
          text = text.innerHTML;
        }
    
        var wordsWithSpan = text.split(' ').map(function(c) {
          return '<span class="word">' + c + '</span>';
        }).join('');
    
        document.getElementById('test').innerHTML = wordsWithSpan;
      }
    
      function agregarIds() { //agregamos ids para saber en que nodo esta en cursor
        text = document.getElementById('test');
        let nodeSpans = text.getElementsByTagName('span');
        for (var i = 0; i < nodeSpans.length; i++) {
          nodeSpans[i].id = i;
        }
      }
    }
    .word {
      color: red;
      padding-right: 3px;
    }
    
    div {
      border: 1px solid;
      margin: 50px;
    }
    <div contentEditable=“true”id=“test”>
    </分区>
    3 回复  |  直到 6 年前
        1
  •  0
  •   clickbait    6 年前

    此代码允许您在单词中间键入,而不会弄乱插入符号的位置!你甚至可以将文本粘贴到div中,它会立即更新!也支持一行多个空格!选择和删除一系列字符(通过文字切入)也可以!

    window.onload = function() {
      document.getElementById('test').addEventListener('keyup', function(e) {
        var parent = document.getElementById("test");
        var range = document.createRange();
        var selection = window.getSelection();
        var number = window.getSelection().anchorNode.parentNode.id;
    
        let pos = getCaret();
    
        convertirEnSpans();
        agregarIds();
    
        setCaret(pos);
      });
    
      function getCaret() {
        var caretOffset = 0;
        if (window.getSelection) {
          var range = window.getSelection().getRangeAt(0);
          var preCaretRange = range.cloneRange();
          preCaretRange.selectNodeContents(test);
          preCaretRange.setEnd(range.endContainer, range.endOffset);
          return preCaretRange.toString().length;
        }
      }
    
      function setCaret(offset) {
        let nodeSpans = test.getElementsByTagName('span');
        var temp = 0;
        for (var i = 0; i < nodeSpans.length; i++) {
          let len = (nodeSpans[i].innerText || nodeSpans[i].textContent).length;
          if (temp + len >= offset) {
            var range = document.createRange();
            var sel = window.getSelection();
            range.setStart(nodeSpans[i].childNodes[0], offset - temp);
            range.collapse(true);
            sel.removeAllRanges();
            sel.addRange(range);
            break;
          }
          else {
            temp += len;
          }
        }
      }
    
      function convertirEnSpans() {
        let text = test.innerText || test.textContent;
        var wordsWithSpan = text.split(/\s/ugmi).map(function(c) {
          if (c.length > 0) return `<span class="word">${c}</span>`;
          else return c;
        }).join('<span>&nbsp;</span>'); // non-breaking space
        test.innerHTML = wordsWithSpan;
      }
    
      function agregarIds() { // agregamos ids para saber en que nodo esta en cursor
        let nodeSpans = test.getElementsByClassName('word');
        for (var i = 0; i < nodeSpans.length; i++) {
          nodeSpans[i].id = "word" + i; // ids are not allowed to start with a digit
        }
      }
    }
    .word {
      color: red;
      border: 1px solid black;
    }
    
    div {
      border: 1px solid black;
      margin: 50px;
      padding: 5px;
    }
    <div contenteditable="true" id="test">
    </div>

    单词周围有黑色的边框,因此您可以很容易地看到元素。

        2
  •  1
  •   NullPointer    6 年前

    我正在使用ContentEditable,但它应该像文本区域一样工作

    我认为您不需要维护太多您编写的代码。

    我的想法是 div 具有 textarea 在飞行中以及从 用户 换成 分区

    您可以引用下面的代码段:

    function divClicked() {
        var divHtml = $(this).text();
        var editableText = $("<textarea />");
        editableText.val(divHtml);
        $(this).replaceWith(editableText);
        editableText.focus(); //sets focus to element
          var val = editableText.val(); //store the value of the element
          editableText.val(""); //clear the value of the element
         editableText.val(val);  //set that value back.  
        // setup the blur event for this new textarea
        editableText.blur(editableTextBlurred);
    }
    
    function editableTextBlurred() {
        var html = $(this).val();
         var wordsWithSpan = html.split(' ').map(function(c) {
          return '<span class="word">' + c + '</span>';
        }).join(' ');
        
        var viewableText = $("<div>");
        viewableText.html(wordsWithSpan);
        $(this).replaceWith(viewableText);
        // setup the click event for this new div
        viewableText.click(divClicked);
    }
    
    $(document).ready(function() {
        $("div").click(divClicked);
    });
    .word {
      color: red;
      padding-right: 2px;
    }
    
    
    
    div {
      border: 1px solid;
      margin: 50px;
      width:400px;
    }
    
    
    
    textarea {
         border: 1px solid;
      margin: 50px;
      width:400px;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div class="word" contenteditable="true"></diV>
        3
  •  0
  •   Durgesh Ahire    6 年前

    请检查更新的代码并让我知道

        window.onload = function() {
          document.getElementById('test').addEventListener('keyup', function(e) {
            if (e.which === 32) {
              var parent = document.getElementById("test");
              var range = document.createRange();
              var selection = window.getSelection();
              var number = window.getSelection().anchorNode.parentNode.id;
    
              convertirEnSpans();
              agregarIds();
              
              
              setEndOfContenteditable(parent);
    
             
            }
          });
    
      function setEndOfContenteditable(contentEditableElement) {
             var range,selection;
             if(document.createRange) { //Firefox, Chrome, Opera, Safari, IE 9+
                range = document.createRange();//Create a range (a range is a like the selection but invisible)
                range.selectNodeContents(contentEditableElement);//Select the entire contents of the element with the range
                range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
                selection = window.getSelection();//get the selection object (allows you to change selection)
                selection.removeAllRanges();//remove any selections already made
                selection.addRange(range);//make the range you have just created the visible selection
              }
              else if(document.selection)//IE 8 and lower
              { 
                 range = document.body.createTextRange();//Create a range (a range is a like the selection but invisible)
                 range.moveToElementText(contentEditableElement);//Select the entire contents of the element with the range
                 range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
                 range.select();//Select the range (make it the visible selection
            }
         }
    
          function convertirEnSpans() {
            let text = document.getElementById('test');
            let spans = text.getElementsByTagName('span');
            if (spans.length > 0) {
              text = '';
              for (var i = 0; i < spans.length; i++) {
                text += spans[i].innerHTML + ' ';
              }
              text = text.substring(0, text.length - 1);
            } else {
              text = text.innerHTML;
            }
    
            var wordsWithSpan = text.split(' ').map(function(c) {
              return '<span class="word">' + c + '</span>';
            }).join('');
    
            document.getElementById('test').innerHTML = wordsWithSpan;
          }
    
          function agregarIds() { //agregamos ids para saber en que nodo esta en cursor
            text = document.getElementById('test');
            let nodeSpans = text.getElementsByTagName('span');
            for (var i = 0; i < nodeSpans.length; i++) {
              nodeSpans[i].id = i;
            }
          }
        }
    .word {
      color: red;
      padding-right: 2px;
    }
    
    div {
      border: 1px solid;
      margin: 50px;
    }
    <div contenteditable="true" id="test">
    </div>