Как я могу определить, что элемент с именем класса является родителем / выше всех других имен классов? - PullRequest
0 голосов
/ 28 января 2019
  1. Мне даны имена классов, такие как class-1, class-2 или class-3
  2. Может быть много классов (не обязательно 3), но я буду знать все имена классов.
  3. Я не знаю структуру DOM.
  4. И я просто знаю, что существует один класс (элемент с этим классом), который является родительским для всех.

Но как мне найти тот класс, который является родителем / над всеми другими известными классами? Это class-1, class-2 или class-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 голосов
/ 28 января 2019

Если вы используете современный браузер, вы можете использовать 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>
0 голосов
/ 28 января 2019

Самый простой и болезненный подход состоит в том, чтобы пройти 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
0 голосов
/ 28 января 2019

Единственное, о чем я могу думать, это перебрать массив и выбрать элемент, а затем проверить, есть ли в нем два других элемента.Родителем будет тот, у кого больше совпадений.Это предполагает, что есть только один элемент каждого.Если их будет больше, потребуется больше логики.(И нам понадобятся тестовые случаи для всех возможных результатов)

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>
0 голосов
/ 28 января 2019

Как только вы обнаружите наличие (существование) отдельных классов, посмотрите на .innerHTML отдельных элементов в каждом массиве классов, чтобы увидеть, найдены ли там другие найденные классы (делая его родителем найденного),Тогда следи.Теперь, есть ли у последующего найденного класса элемент, который содержит текущего родителя?Сделайте то же самое: ищите innerHTML для каждого элемента в нем.Удачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...