首页 > 解决方案 > 新 div 中的每个单词

问题描述

我想要光标在文本区域中的正常行为,请尝试使用 chrome navigator。

我正在使用 acontenteditable但它应该像 textarea 一样工作,每个单词都必须在非常必要的范围内,我不想使用纯文本

对于每个空格,每个写入的单词都必须变成一个 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>

我无法让光标正常运行,光标跳转到所有部分,如何解决?

我只对使用空格键感兴趣,不要用回车键尝试

使用@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">
</div>

标签: javascript

解决方案


我正在使用 contenteditable 但它应该像 textarea 一样工作

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

想法只是在运行中替换为divtextarea并在获得用户的输入后将其替换为div

您可以参考下面的代码片段:

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>


推荐阅读