如何检测类名称为parent /在所有其他类名称之上的元素?

时间:2019-01-28 17:49:36

标签: javascript html dom

  1. 为我提供了class-1class-2class-3之类的类名
  2. 可以有很多类(不一定是3个),但是我会知道所有的类名。
  3. 我不知道DOM结构。
  4. 我只知道有一个类(该类的元素)是所有类的父类。

但是我应该如何找到哪个类是父类/在所有其他已知类之上?class-1class-2class-3吗?

我有类似这样的HTML

    <div>
      <div> Hey nice talking to you </div>
      <div> Hey how are you</div>
      <div><br/></div>
      <div class="class-1">
        <div>Hey, are you there?</div>
        <div class="class-2">
          <div>How was the day</div>
          <div class="class-3"><br/></div>
        </div>
      </div>
    </div>

这是我尝试过的东西

    _findClass_1(html) {
      return Array.from(html.querySelectorAll('.class-1'));
    }

    _findClass_2(html) {
      return Array.from(html.querySelectorAll('.class-2'));
    }

    _findClass_3(html) {
      return Array.from(html.querySelectorAll('.class-3'));
    }

    // Parser
    getNodes(html) {
      const parsers = [
        this._findClass_1,
        this._findClass_2,
        this._findClass_3,
      ];

      let quotedNodes = [];

      for (const parser of parsers) {
        quotedNodes.push(parser(html) || []);
      }

      // How can I detect here which one was the parent of all? 
      return quotedNodes;
    }

你能帮我吗? 请不要jQuery。

4 个答案:

答案 0 :(得分:2)

最痛苦的方法是从根节点遍历DOM,并在列表中的多个子类之一相等时立即停止。

const class_list = [];

recursion(element) {
  if (element === null) return false;

  // If element has one of the class from the list of class then return element.parentNode

  const children = element.children;
  children.forEach(child => recursion(element));

  return false;
}

通过调用

开始该过程
const parent_node = recursion(document.getElementById('body'));
if (parent_node) // this is the parent that has all the class element children

答案 1 :(得分:2)

如果您使用的是现代浏览器,则可以使用closest查看是否有任何具有其他类之一的祖先元素。如果没有,那么您将找到带有类的最顶层元素。假设DOM中每个类只有一个元素。

基本上,使用reduce可以让我遍历数组并使用函数进行聚合。该函数获取当前类并找到具有该类的元素。然后,它获取类的数组(我们正在测试的类除外),并查找当前元素是否将其中一个作为父元素。如果没有,我们拥有最顶层的元素。

const parent = ["class-1","class-2","class-3"].reduce((agg, cur, idx, arr) => {
  const sut = document.querySelector(`.${cur}`);
  const hasParent = arr.filter(e => e !== cur).some(clas => sut.closest(`.${clas}`) !== null);
  return hasParent ? agg : sut;
}, null);

console.log(parent.className);
    <div>
      <div> Hey nice talking to you </div>
      <div> Hey how are you</div>
      <div><br/></div>
      <div class="class-1">
        <div>Hey, are you there?</div>
        <div class="class-2">
          <div>How was the day</div>
          <div class="class-3"><br/></div>
        </div>
      </div>
    </div>

答案 2 :(得分:1)

我唯一想到的就是在数组上循环并选择元素,然后检查其中是否存在其他2个元素。父母将是最匹配的人。假设每个元素只有一个。如果存在更多逻辑,则将需要逻辑。 (并且我们将需要测试用例才能得出所有可能的结果)

var classes = [".class-1", ".class-2", ".class-3"]

var result = classes.reduce((obj, key, i, arr) => {
  const cpy = arr.slice()
  cpy.splice(i,1)
  const count =
    document.querySelector(key)
      .querySelectorAll(cpy.join(","))
        .length
  if (count > obj.count) {
    return { key, count }
  }
  return obj
}, {key:'', count:-1})

console.log(result.key)
    <div>
      <div> Hey nice talking to you </div>
      <div> Hey how are you</div>
      <div><br/></div>
      <div class="class-1">
        <div>Hey, are you there?</div>
        <div class="class-2">
          <div>How was the day</div>
          <div class="class-3"><br/></div>
        </div>
      </div>
    </div>

答案 3 :(得分:0)

一旦发现(存在)各个类的存在,请查看每个类数组中各个元素的.innerHTML,以查看是否在其中找到了其他找到的类(使之成为找到的类的父类) 。然后跟踪。现在,找到的后续类是否具有包含当前父项的元素?做同样的事情:在其中的每个元素上搜索innerHTML。祝你好运。