javascript - 新 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>
解决方案
我正在使用 contenteditable 但它应该像 textarea 一样工作
我认为您不需要维护您编写的太多代码。
想法只是在运行中替换为div
,textarea
并在获得用户的输入后将其替换为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>
推荐阅读
- python - 使用多个适合图像制作图像立方体
- cmake - 如何在 valgrind 中抑制 GOT 的“无效读取”警告?
- ios - Swift - 如何从枚举变量中获取枚举 case 参数?
- unity3d - 如何在 unity3D 中将顶点数据绑定到 GLSL?
- python - 同时用单个值替换字符串列表
- c# - 为什么我的 DataGridCell 拒绝每个输入?
- python - MSER 文本检测问题
- karate - 空手道 0.9.1 不生成用于黄瓜报告的 cucumber.json
- c# - 关于 SQL 的问题 - INSERT with DISTINCT 和 JOIN
- php - Symfony 4 DQL - 查询返回 null