我正在尝试实现自己的插入符号,当它在文本的开头并向左移动时,它应该转到DOM中的前一个文本节点。我的问题是,这并不总是只是我以前能够轻松找到的兄弟姐妹。可能是它位于父母兄弟的树的底部。这应该澄清我的问题:
function getPreviousTextElement(node) {
var prev = $('.caret').closest(':text');
prev.css('color', 'green');
}
#carot{
color:red;
}
<div>
1 <div>
2
<div>3</div>
<div>4</div>
<div>5
<div>6</div>
<div>
7
<div>8</div>
<div>9</div>
</div>
</div>
</div>
</div>
<div>
<span id="carot">|</span>10
</div>
因此,当插入符号位于“10”并且你向左按它时应该转到“9”但是如何获得这个元素?我缺少JS或jQuery函数吗? jQuery nearest(),prevAll()或parent()似乎没有完成这项工作。
https://jsfiddle.net/jqb816a1/5/
我尝试了几种不同的解决方案。最初我认为从DOM元素的基本向上遍历可以工作,但不幸的是,因为你在你的问题中指定你也希望它也通过未知数量的父元素的兄弟姐妹,我不能完全得到它牛仔舞。
我最终创建了一个对象,其中包含一个Set Object
来保存所有这些文本节点,以及一个getPrev
方法,当给定包含页面上的文本节点的元素时,它将返回前一个文本节点。在这种情况下,你的span
标签的id为carot
安装程序
function findTextNodes(node) {
let text_node_set = new Set();
traversal(node);
function traversal(node) {
check_for_text(node);
let ele = node.nextSibling;
while (ele) {
check_for_text(ele);
ele = ele.nextSibling;
}
}
function check_for_text(ele) {
if (ele.childNodes) {
for (let child of ele.childNodes) {
if (child.nodeType == 3 && new RegExp(/\S/g).test(child.textContent)) {
text_node_set.add(child);
} else {
traversal(child);
}
}
}
}
return {
getPrev: function(ele_node) {
let text_node;
if (ele_node.childNodes) {
for (let child of ele_node.childNodes) {
if (child.nodeType == 3 && new RegExp(/\S/g).test(child.textContent)) {
text_node = child;
}
}
}
if (this.text_node_set.has(text_node)) {
let prev, previousNode;
this.text_node_set.forEach(function(node) {
if (node === text_node) {
if (prev) previousNode = prev;
}
prev = node;
})
return previousNode;
}
},
text_node_set
}
}
使用return对象:
let text_nodes = findTextNodes(document.body);
// object: text_nodes
// methods: getPrev
// properties: text_node_set
let caret = document.getElementById('carot');
//print the previous node to the console
console.log(text_nodes.getPrev(carot));
//or turn its text green
let prevNode = text_nodes.getPrev(carot);
//(we need to grab the parent node of the text for styling)
prevNode.parentNode.style.color = "lightGreen";