html的混合标记,javascript – 在contenteditable元素中,在HTML标记之间移动光标

http://jsfiddle.net/Y7tgx/2/

Firefox比Chrome更好地处理这个问题,但不是我想要的方式.它们将所有相邻的HTML标记混合在一起并将它们视为一个(我不想要).

Firefox:当光标留在标签(或一组相邻标签)上并向右按时,光标会跳过标签前面的第一个字符.然后,如果你按左键,它会在字符和标签之间移动. (按左,然后相同.)

Chrome:标记及其后面的第一个字符被集中在一起.将光标放在标签和后续字符之间是不可能的.

期望:标签被视为相对于光标的单个字符.如果光标位于标签的左侧并且您向右按,则它应该位于标签的右侧,反之亦然,以便向左按.

如何在浏览器上强制执行所需的行为?

这不适用于WYSIWIG编辑器.为了达到特定目的,标签在生产中以可视方式表示,就像它们在jsfiddle中一样.用户希望任意控制哪个元素包含光标.

b:before, b:after,

i:before, i:after,

p:before, p:after {

color: blue;

}

b:before {

content: '';

}

b:after {

content: '';

}

p:before {

content: '

';

}

p:after {

content: '

';

}

i:before {

content: '';

}

i:after {

content: '';

}​

----------

regular regularboldregular -

try moving the cursor to either side of either blue tag.

try it in this: regularbolditalic

在`contenteditable`容器中使用`HTML`元素后,获取和设置光标位置的方法与普通的`contenteditable`容器有所不同,因为获取和设置光标位置需要考虑到`HTML`元素的影响。下面是一个示例代码片段: ```javascript function getCaretPosition(element) { let caretOffset = 0; const range = window.getSelection().getRangeAt(0); const preCaretRange = range.cloneRange(); preCaretRange.selectNodeContents(element); // 如果光标HTML元素内部,则需要对光标位置进行偏移 if (range.startContainer.parentNode !== element) { const offset = getOffsetWithinParent(range.startContainer); caretOffset = preCaretRange.toString().length + offset; } else { preCaretRange.setEnd(range.endContainer, range.endOffset); caretOffset = preCaretRange.toString().length; } return caretOffset; } function setCaretPosition(element, caretPos) { const range = document.createRange(); const sel = window.getSelection(); const { childNodes } = element; let currentNode = element; let charCount = 0; let foundStart = false; for (let i = 0; i < childNodes.length; i++) { const node = childNodes[i]; if (node.nodeType === Node.ELEMENT_NODE) { if (caretPos <= charCount + node.textContent.length) { currentNode = node; foundStart = true; break; } charCount += node.textContent.length; } else if (node.nodeType === Node.TEXT_NODE) { if (caretPos <= charCount + node.length) { range.setStart(node, caretPos - charCount); foundStart = true; break; } charCount += node.length; } } if (!foundStart) { range.setStart(currentNode, currentNode.childNodes.length); } sel.removeAllRanges(); sel.addRange(range); } // 获取HTML元素在父节点中的偏移量 function getOffsetWithinParent(element) { let offset = 0; const parent = element.parentNode; const children = parent.childNodes; for (let i = 0; i < children.length; i++) { const child = children[i]; if (child === element) { break; } if (child.nodeType === Node.ELEMENT_NODE) { offset += child.outerHTML.length; } else if (child.nodeType === Node.TEXT_NODE) { offset += child.textContent.length; } } return offset; } ``` 其中,`getCaretPosition`函数可以获取当前光标在`element`中的位置,`setCaretPosition`函数可以将光标设置到`element`的指定位置,`getOffsetWithinParent`函数可以获取`HTML`元素在父节点中的偏移量。你可以在需要的时候调用这些函数来设置和获取光标位置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值