子DOM元素的递归函数

时间:2016-06-02 16:35:55

标签: javascript html dom

我正在尝试使用递归函数来显示/隐藏DOM上的多个嵌套UL / LI元素。

我有一个适用于单个嵌套的函数,但我试图使用递归函数来控制 x 数量的嵌套元素。

以下是我目前的情况:

HTML

<section data-range="true">
  <input type="range">
  <ul>
    <li>Item one</li>
    <li>Item two</li>
    <ul>
      <li>Nestd two-one</li>
      <li>Nestd two-two</li>
      <ul>
        <li>Double-nested one</li>
      </ul>
    </ul>
    <li>Item three</li>
  </ul>
</section>

JS:

/*  eventListener
 *  Attach an event listener to this element
 *
 *  @param Object - Event object
*/
function eventListener(el) {
  el.addEventListener('change', function(e) {
      // List
      else if (el.parentNode.children[1].nodeName == "UL" || el.parentNode.children[1].nodeName == "OL") {
          updateList(e, el.value);
      }
  });
}

/*  updateList
 *
 *  @param Object - Event object
 *  @param Real - Range value (i.e. 3.2)
*/
function updateList(e, range) {
    var target = e.srcElement || e.target;
    var list = target.nextSibling.nextElementSibling;
    var listNumber = list.childElementCount;

    displayChildren(list, listNumber);
}

/*  displayChildren
 *
 *  @param Object - Event object
*/
function displayChildren(list, listNumber) {

    for (var i = 0; i < listNumber; i++) {
        if (list.children[i].nodeName != 'UL') {
            list.children[i].style.display = (list.children[i].getAttribute('data-position') <= range) ? "":"none";
        }
        if (list.children[i].children.length > 0) {
            displayChildren(list.children[i], list.children[i].childElementCount);
        }
    }
}

以下是一些实例:

  • JSbin在嵌套元素上具有递归函数。
  • JSbin具有工作嵌套元素。

任何有用的提示表示赞赏。

1 个答案:

答案 0 :(得分:1)

好吧,你省略了一些参数。 :)

检查JsBin

function updateList(e, range) {
  ...
  displayChildren(list, listNumber, range); // add range param.
}

function displayChildren(list, listNumber, range) { // and here
  ...
  displayChildren(list.children[i], list.children[i].childElementCount, range); // and here.

为什么不使用jQuery?无论如何,这是你制作的很酷的剧本,祝你好运:)

----编辑

您的数据位置和输入范围的值不是“数字”,它们是“字符串”。

所以,如果超过10个'UL'元素,它会比较'10'和'4'('4'是更大的值')

JsBin (working demo)

修复它,在比较它们之前转换为数字类型

function eventListener(el) {
  ...
  updateList(e, parseInt(el.value));


function displayChildren(list, listNumber, range) {
  ...
  // Now range is Number. (and LHS will converted with number)
  list.children[i].style.display = (list.children[i].getAttribute('data-position') <= range) ? "":"none";

我想你已经明白了,请查看:) Javascript string/integer comparisons

----再次编辑

而且..如果你只是想展示和隐藏'LI'元素怎么样?

var Range = function(step) {
  var rangeElements = document.querySelectorAll("[data-range]");

  for(var i = 0; i < rangeElements.length; i++) {
    var el = rangeElements[i];
    var inputRange = el.children[0]; // input type="range"
    var sectionRange = el.children[1]; // root UL

    inputRange.min = 0;
    inputRange.max = inputRange.value = sectionRange.getElementsByTagName('LI').length;
    inputRange.step = Number(step) || 1;

    // for better UX use oninput event.
    inputRange.addEventListener('input', function(e) {
      var el = e.target;
      var rangeItems = el.parentNode.children[1].getElementsByTagName('LI');
      var range = Number(el.value);
      for(var i = 0; i < rangeItems.length; i++) { rangeItems[i].style.display = i < range ? '' : 'none'; }
    });
  }
  return rangeElements;
}