如何获取在给定文本之前显示的上一个文本节点?

时间:2017-04-14 15:14:50

标签: javascript jquery html

我正在尝试实现自己的插入符号,当它位于文本的开头并向左移动时,它应该转到DOM中的前一个文本节点。我的问题是,这并不总是只是我以前能够轻松找到的兄弟姐妹。可能是它位于父母兄弟的树的底部。这应该澄清我的问题:

find
function getPreviousTextElement(node) {
 var prev = $('.caret').closest(':text');
 prev.css('color', 'green');
}
#carot{
  color:red;
}

因此,当插入符号位于“10”并且你向左按它时应该转到“9”但是我如何得到这个元素?我缺少JS或jQuery函数吗? jQuery nearest(),prevAll()或parent()似乎无法完成这项工作。

1 个答案:

答案 0 :(得分:0)

https://jsfiddle.net/jqb816a1/5/

我尝试了一些不同的解决方案。最初我认为DOM元素的基本向上遍历是可行的,但不幸的是,因为你在你的问题中指明你也希望它也经历了未知数量的父元素的兄弟,我无法得到那就是jive。

我最终创建了一个包含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
  }
}

使用返回对象:

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";