Рекурсивный JQuery для форматирования значений узлов HTML в тексте - PullRequest
0 голосов
/ 26 апреля 2018

function insideNest(theindex, count) {
  count++;
  console.log("(\n)");
  if (theindex == null) {
    theindex = $(document);
  }
  $(theindex).children("#nest").each(function() {
    $(this).children("#value").each(function() {
      $(this).children("input").each(function() {
        for (i = 0; i < count; i++) {
          console.log("\t");
        }
        console.log($(this).val() + "\n");
      });
    });
    insideNest($(this));
  });
  console.log(")\n)");
}
$(document).ready(function() {
  insideNest($(this), -1);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="nest">
  <div id="value">
    <input type="text" id="hasvalue" value="level1" />
  </div>
  <div id="value">
    <input type="text" id="hasvalue" value="level1" />
  </div>
  <div id="value">
    <input type="text" id="hasvalue" value="level1" />
  </div>
  <div id="nest">
    <div id="value">
      <input type="text" id="hasvalue" value="level2" />
    </div>
    <div id="value">
      <input type="text" id="hasvalue" value="level2" />
    </div>
    <div id="nest">
      <div id="value">
        <input type="text" id="hasvalue" value="level3" />
      </div>
    </div>
    <div id="value">
      <input type="text" id="hasvalue" value="level2" />
    </div>
  </div>
  <div id="value">
    <input type="text" id="hasvalue" value="level1" />
  </div>
  <div id="value">
    <input type="text" id="hasvalue" value="level1" />
  </div>
</div>

Мой вывод:

(
)
)
)

Ожидаемый результат:

level1
level1
level1
(
  level2
  level2
  (
    level3
  )
  level2
)
level1
level1

Я хочу получить значения внутри полей input, а скобки начинаются только тогда, когда есть вложенный #nest. Я пытался вызвать ту же функцию, когда javascript находит #nest, и просто печатать вывод, когда он находит #value. Я думаю, что хитрость заключается в том, чтобы найти только одноуровневых детей из nest Скрипка: https://jsfiddle.net/2fq8u8wk/

Ответы [ 2 ]

0 голосов
/ 26 апреля 2018

Сходство, основанное на ответе Crazy Train, позволяет создавать функции посещения. Вы можете контролировать, что происходит при посещении, во время посещения и после посещения каждого узла.

const indent = (count, char) => (char || '\t').repeat(count);

function walkDom(node, preVisitFn, visitFn, postVisitFn, depth) {
  preVisitFn(node, depth);
  for (const child of node.children) {
    if (child.classList.contains('value')) {
      visitFn(child, depth + 1);
    } else if (child.classList.contains('nest')) {
      walkDom(child, preVisitFn, visitFn, postVisitFn, depth + 1)
    }
  }
  postVisitFn(node, depth);
}

walkDom(
  // The element we want to walk.
  document.body.querySelector('.nest'),

  // Before we visit children
  function(node, currentDepth) {
    console.log(indent(currentDepth) + '(')
  },

  // While we visit each child (depth +1)
  function(node, currentDepth) {
    console.log(indent(currentDepth) + node.firstElementChild.value)
  },

  // After all children have been visited
  function(node, currentDepth) {
    console.log(indent(currentDepth) + ')')
  },

  // Initial depth is zero.
  0
);
.nest { display: none; }

.as-console-wrapper { top: 0; max-height: 100% !important; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="nest">
  <div class="value">
    <input type="text" class="hasvalue" value="level1" />
  </div>
  <div class="value">
    <input type="text" class="hasvalue" value="level1" />
  </div>
  <div class="value">
    <input type="text" class="hasvalue" value="level1" />
  </div>
  <div class="nest">
    <div class="value">
      <input type="text" class="hasvalue" value="level2" />
    </div>
    <div class="value">
      <input type="text" class="hasvalue" value="level2" />
    </div>
    <div class="nest">
      <div class="value">
        <input type="text" class="hasvalue" value="level3" />
      </div>
    </div>
    <div class="value">
      <input type="text" class="hasvalue" value="level2" />
    </div>
  </div>
  <div class="value">
    <input type="text" class="hasvalue" value="level1" />
  </div>
  <div class="value">
    <input type="text" class="hasvalue" value="level1" />
  </div>
</div>
0 голосов
/ 26 апреля 2018

Я не знаю точную природу вашей ошибки, потому что я не хочу пытаться проанализировать, как поведет себя jQuery.

Вместо этого проще просто переписать. Это простая рекурсивная функция, которая использует собственный API, чтобы делать то, что вы хотите.

function indent(n) { return "\t".repeat(n) }
function print(depth, s) { console.log(indent(depth) + s) }

function walk(root, depth) {
  print(depth, "(")
  
  for (const ch of root.children) {
    if (ch.matches(".value")) {
      print(depth + 1, ch.firstElementChild.value)

    } else if (ch.matches(".nest")) {
      walk(ch, depth + 1)
    }
  }
  print(depth, ")")
}

// Run after the DOM is loaded
document.addEventListener("DOMContentLoaded", function() {
  walk(document.body.querySelector(".nest"), 0)
})
<div class="nest">
  <div class="value">
    <input type="text" class="hasvalue" value="level1" />
  </div>
  <div class="value">
    <input type="text" class="hasvalue" value="level1" />
  </div>
  <div class="value">
    <input type="text" class="hasvalue" value="level1" />
  </div>
  <div class="nest">
    <div class="value">
      <input type="text" class="hasvalue" value="level2" />
    </div>
    <div class="value">
      <input type="text" class="hasvalue" value="level2" />
    </div>
    <div class="nest">
      <div class="value">
        <input type="text" class="hasvalue" value="level3" />
      </div>
    </div>
    <div class="value">
      <input type="text" class="hasvalue" value="level2" />
    </div>
  </div>
  <div class="value">
    <input type="text" class="hasvalue" value="level1" />
  </div>
  <div class="value">
    <input type="text" class="hasvalue" value="level1" />
  </div>
</div>

Я изменил ваши атрибуты id на class, поскольку идентификаторы в документе должны быть уникальными. Учитывая мою переписанную выше, мы могли бы получить с идентификаторами, но это все еще не здорово.

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