按顺序递归元素

时间:2017-10-30 17:33:35

标签: javascript html recursion

今天在课堂上,我们被赋予了一个“重新创建”jQuery功能的任务(我不知道为什么,我猜老师是虐待狂)。

我们得到以下指示:
仅使用纯javascript(甚至不是ECMEScript 2015)创建一个函数'$',它将接收标签/ id / class。

  • 如果您只获得一个令牌[例如$(“#id)],则返回合适的元素。

  • 如果您获得了多个令牌[例如$(“nav div div p”)] - 按层次搜索最后一个令牌。

输入: $('nav div p');

目标:获取所有p元素,这些元素的div位于div之上,其导航位于div之上。

if (query.split(" ").length > 1) {

  var first = query.split(" ")[0];
  var rest = query.split(" ").slice(1);
  var curr_elements;

  if (first.match(/^#.*/i)) {
    curr_elements = (document.getElementById(first.substring(1)));
  } else if (query.match(/^\..*/i)) {
    curr_elements = document.getElementsByClassName(first.substring(1));
  } else if (query.match(/^\w.*/i)) {
    curr_elements = document.getElementsByTagName(first);
  }
  curr_elements = [].slice.call(curr_elements);

  for (var e = 0; e < curr_elements.length; e++) {
    if (curr_elements[e].hasChildNodes()) {
      for (var i = 0; i < rest.length; i++) {
        var temp = rest[i];
        var children;
        if (temp.match(/^#.*/i)) {
          children = (document.getElementById(temp.substring(1)));
        } else if (temp.match(/^\..*/i)) {
          children = document.getElementsByClassName(temp.substring(1));
        } else if (temp.match(/^\w.*/i)) {
          children = document.getElementsByTagName(temp);
        }
        alert(children);
        //curr_elements += children;
      }
    }
  }

  this.elements = curr_elements;
} else {
  if (query.match(/^#.*/i)) {
    this.elements.push(document.getElementById(query.substring(1)));
  } else if (query.match(/^\..*/i)) {
    this.elements = document.getElementsByClassName(query.substring(1));
  } else if (query.match(/^\w.*/i)) {
    this.elements = document.getElementsByTagName(query);
  }

}
<nav>
  <p id="1"></p>
</nav>

<nav>
  <div>
  </div>
  <p>
    <div>
      <p id=2></p>
    </div>
  </p>
</nav>
<nav>
  <div>
    <p id="3"></p>
    <p id="4"></p>
    <div>
    </div>
  </div>
</nav>

<nav>
  <div>
    <div>
      <div>
        <p id="5"></p>
      </div>
    </div>
  </div>
</nav>

变量:

查询:第一个arg是标签/ ID /类名 curr_elements:数组,用于临时存储我得到的元素 this.elements:最终的HTMLCollection。

与单个令牌($(“p”);)相关的部分工作正常,但我无法弄清楚如何递归/迭代元素以获得段落。

希望得到某人关于如何继续的想法/建议。

1 个答案:

答案 0 :(得分:1)

您的代码非常可靠,您只是不使用递归,在这种情况下非常有用。

我已将代码更改为使用递归方法:

function $(selector, context) {
  if (!selector) return false;
  // context should be an array of previous nodes we have found.  If it's undefined, assume the single-item array [document] as the starting context
  if (!context) context = [document];
  
  var s = selector.split(" ");
  var first = s.shift();
  var curr_elements = [], els;
  
  for (var i=0; i < context.length; i++) {
    var c = context[i];
    // make sure els gets converted into a real array of nodes
    if (first.match(/^#.*/i)) {
      els = [c.getElementById(first.substring(1))];
    } else if (first.match(/^\..*/i)) {
      els = [].slice.call(c.getElementsByClassName(first.substring(1)));
    } else if (first.match(/^\w.*/i)) {
      els = [].slice.call(c.getElementsByTagName(first));
    }
    curr_elements = curr_elements.concat(els);
  }
  
  // if there are more items in s, then curr_elements is the context in which to find them.  Otherwise, curr_elements is the array of elements we were looking for.
  if (s.length) return $(s.join(" "), curr_elements);
  
  return curr_elements;
}

var a = $(".test span");
console.log(a);
<div class="test">
  <span>1</span><span>2</span><span>3</span>
</div>
<div class="not_test">
  <span>4</span><span>5</span><span>6</span>
</div>
<p class="test">
  <span>7</span><span>8</span><span>9</span>
</p>