2

我有一个简单的 js 函数,它返回我点击元素的 dom 路径。但是有时某些元素(通常是我点击的那个)会计算两次

所以如果我有以下代码

<ul>
<li><a href ='#'>Some link</a></li>
</ul>

输出可能类似于ul:nth-child(1) > li:nth-child(1) > a:nth-child(2) whilea应该是 1 个孩子。

这是函数的代码

var getDomPath;

getDomPath = function(el) {
  var count, element, nth, path, selector, sib;
  element = el;
  if (!(el instanceof Element)) {
    return;
  }
  path = [];
  while (el.nodeType === Node.ELEMENT_NODE && el.id !== "jobs") {
    selector = el.nodeName.toLowerCase();
    if (el.id) {
      selector += "#" + el.id;
    } else if (el.className) {
      selector += "." + el.className;
    } else {
      sib = el;
      nth = 1;
      count = 1;
      while (sib.nodeType === Node.ELEMENT_NODE && (sib = sib.previousSibling) && $(el).prev().prop('tagName') !== "STYLE" && $(el).prev().prop('tagName') !== null) {

        count += $(el).prevAll().size();
      }
      selector += ":nth-child(" + count + ")";
    }
    path.unshift(selector);
    el = el.parentNode;
  }
  return path.join(" > ");
};

代码从咖啡转换为 javascript,所以可能看起来有点糟糕

这是我试图获取路径的html

<td width="50%"><strong>Leveringssadresse</strong>
<br>
Hans Andersen
<br>
Andevej 123
<br>
1234 Andeby
<br>
Denmark
<br>
Telefon: 31122345
<br>
Mobiltelefon: 12232345
<br>
<a href="mailto:mail@gmail.com">mail@gmail.com</a>
<br>
</td>

在这里,当我单击a元素时,我希望它是nth-child(8),但不知何故我得到它 17(16 + 1 在我的代码中以 1 递增)

4

2 回答 2

2

刚刚注意到您使用 jQuery。

为什么不将其简化为

function getDomPath(element){
    var path = $(element).parents().andSelf().map(function(){
        var index = $(this).index() + 1;
        return this.nodeName.toLowerCase() + ':nth-child('+ index +')';
    }).get();

  return path.join(' > ');
}

演示在http://jsfiddle.net/BEUrn/3/

于 2013-11-05T13:23:22.067 回答
1

问题在于这一行:

while (sib.nodeType === Node.ELEMENT_NODE && (sib = sib.previousSibling) && $(el).prev().prop('tagName') !== "STYLE" && $(el).prev().prop('tagName') !== null) {

我已多次阅读此行,但我无法弄清楚您要做什么。

你的代码说:

  • 确保当前检查的节点是一个元素
  • 将当前检查的节点设置为其前一个兄弟节点
  • 检查原始节点之前的元素是否具有不是STYLE

我不知道该步骤序列的意图是什么,但如果最终条件通过,它将计算n * (x + 1) + 1,其中n是前面元素兄弟x的数量,并且是不干预文本节点的直接前面元素兄弟的数量。

下一行是这样的:

count += $(el).prevAll().size();

当然,这应该只运行一次,根本不需要条件。

count = $(el).prevAll().length + 1;

jsFiddle与工作代码。

于 2013-11-05T13:03:05.197 回答