Javascript向上遍历DOM

时间:2017-07-29 16:13:42

标签: javascript dom

在jQuery中向上遍历DOM几步而不是

#!/usr/bin/env bash

我可以写短版:

 $(this).parent().parent().parent().parent().parent().click();

所以,我想知道,如果有办法缩短代码而不是垃圾邮件'.parentNode'?

2 个答案:

答案 0 :(得分:2)

相当无足轻重:



function parent (element, n = 1) {
  let {parentNode} = element;
  for (let i = 1; parentNode && i < n; i++) {
    ({parentNode} = parentNode);
  }
  return parentNode;
}

const span = document.querySelector('span');
const directParent = parent(span);                  // direct parent node
const greatGreatGreatGrandParent = parent(span, 5); // parent node 5 times
console.log(directParent.getAttribute('data-foo'));                // baz
console.log(greatGreatGreatGrandParent.getAttribute('data-foo')); // bar
&#13;
<div data-foo="bar">
  <div>
    <div>
       <div>
         <div data-foo="baz">
          <span>Hello, World!</span>
         </div>
      </div>
    </div>
  </div>
</div>
&#13;
&#13;
&#13;

我检查parentNode,因为它可能是null。在这种情况下,我打破循环并返回null,因为继续循环会导致错误:

({parentNode} = null); // TypeError: can't convert null to object

括号是必要的,表明开头{没有开始一个块,而是一个解构赋值:

{parentNode} = parentNode; // SyntaxError: expected expression, got '='

编辑:

我必须承认我的解决方案相当简洁,并使用一些新的JavaScript功能使其更加简洁。

let {parentNode} = element;是什么意思?

Object destructuring允许您以更简洁的方式从对象中读取属性:

let {parentNode} = element;

相当于:

let parentNode = element.parentNode;

如上所述,

({parentNode} = parentNode);

相当于:

parentNode = parentNode.parentNode;

parentNode && i < n究竟是什么?

每个for - 循环都有一个条件。如果此条件为真,则继续循环。如果条件为假,则它会脱离循环。

我可以写:

for (let i = 1; i < n; i++) {
  // ...
}

那将运行循环n - 1次迭代。在最后一次迭代之后,i等于n,因此条件评估为false并且它会停止,这很好。

parentNode && i < n扩展了这个条件。它不仅会检查i是否小于n,还会检查parentNode是否包含真值。如果parentNodenull(可能会发生元素没有父节点),则循环将中断,因为它无法读取null的属性parentNode

我希望您理解以下功能的解释,这与原来的功能相同:

function parent (element, times) {
  var n; // how many times 'parentNode'?
  if (times) {
    n = times;
  } else {
    n = 1;
  }
  var elementToReturn = element.parentNode;
  for (var i = 1; i < n; i++) {
    if (elementToReturn === null) {
      break;
    } else {
      elementToReturn = elementToReturn.parentNode;
    }
  }
  return elementToReturn;
}

答案 1 :(得分:0)

巫师的一线... 它与@petermader的唯一短点相同。我猜这里不需要超级显式了,因为这可能只是导入的实用程序函数,并且它比for循环更可靠。

const getParentElement = ({ parentNode }, n = 1) =>
  Array.from({ length: n - 1 }, () => ({ parentNode } = parentNode)) && parentNode