$("#id a") - $("#id .c a") = ?
前沿
这是之前淘宝的一道面试题,题目借用了 jQuery 选择器的语法。大概的意思是,从 #id 元素内选出所有不是 .c 后代的 a 元素,即父元素 #id 内的所有后代元素中,选出不是 .c 后代元素里的所有a元素。题目主要考察的是 DOM 操作的知识,来筛选DOM元素,并且不能使用jQuery等框架。
思路
先选出所有 a 元素。对每个 a 元素,从其所在位置沿着 DOM 树往上搜索,每走一步对比当前节点类名,含有 c 类立刻中止,否则继续上行直至根节点或父元素(#id)处,结束搜索并将 a 元素加入结果集里。对全部 a 元素执行完该操作后,返回结果集。
查找过程的流程图如下:

js核心代码:
// 参数依次为根元素、给出的类名、目标元素(即一一对应题目中的$("#id .c a"))
var domSelector = function(rootId, filterClass, targetTag) {
var root = document.getElementById(rootId),
nodes = root.getElementsByTagName(targetTag),
resultArr = [],
i,
len;
// 沿着DOM树查找
var ascend = function(start, end, current) {
if(current === end) { // 查找成功
resultArr.push(start);
// 没查找到则继续沿着DOM树往上搜索(递归调用)
} else if((" " + current.className.toLowerCase() + " ").indexOf(" " + filterClass + " ") == -1) {
ascend(start, end, current.parentNode);
}
};
for (i = 0, len = nodes.length; i < len; i++) {
ascend(nodes[i], root, nodes[i].parentNode); // 循环便利
}
return resultArr;
};
测试:
HTML结构:
<div id="id">
<div>
<a href="" class="A1">A1</a>
</div>
<div class="c">
<a href="" class="A2">A2</a>
</div>
<div class="d">
<a href="" class="A3">A3</a>
</div>
</div>
调用函数:
// 测试
window.onload = function() {
// 调用函数
var res = domSelector("id", "c", "a");
console.log(res); // 返回一个数组:[a.A1, a.A3]
};
结语
由于过多的DOM遍历会导致性能问题,所以递归调用的方法可能会存在效率上的问题。所以各自权衡吧~
随机推荐
- kettle过滤、生成随机数、改变开始复制数量
下面是一个用Kettle实现数据过滤.生成随机数.改变开始复制数量的连贯示意图. 首先,我们将控件一一建立,通过hop建立连接 下面对每一个控件进行设置 1.生成随机数控件(随机取一个数字与字符串) ...
- db2建立表空间
--缓冲池 CREATE BUFFERPOOL EMP_BUF_POOL IMMEDIATE ALL DBPARTITIONNUMS SIZE 250 NUMBLOCKPAGES 0 PAG ...
- Nginx初始化过程总结
对于Nginx这样一个模块化的服务器,看代码是最好的理解方式了.再此通过读main() 函数来简述一下Nginx的初始化过程: 这就是整个main函数的执行过程:
- hdu 5326 Work
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5326 Work Description It’s an interesting experience ...
- core java 1~4(HelloWorld & 标识符|关键字|数据类型 & 表达式|流程控制 & 数组)
MODULE 1 Java的编译和运行----------------------------编译:javac -d bin src\HelloWorld.java -d:指定编译后的class 文件 ...
- umask设置导致的weblogic中的应用上传的文件没有权限打开
去年,在公司的某一weblogic上部署的web应用上传文件后却没有读的权限.因为weblogic在Linux上部署,上传文件是mount到了一台安装了NFS的Windows Server上. 当时本 ...
- 调试mvc 源码【转:http://www.cnblogs.com/wucj/archive/2013/06/09/3128698.html】
最近在研究asp.net mvc的源码,于是在想,既然提供了源码,那我们如何进入源码调试了?在网上找了一些调试的方法,试了几个都不行,于是折腾了一上午,终于弄出来了,下面看看我的操作步骤. 一:准 ...
- 自学asp.net mvc(一)
之前一直做asp.net的webform,现在想学习一下mvc,把自学中遇到的问题记录到博客. 一.codeplex上托管代码 1. 2. 3. 4. 5. 6. 7. 8. 9.
- C#判断字符串为空
string str = null; if (string.IsNullOrWhiteSpace(str)) { MessageBox.Show("字符串为null"); } if ...
- 仿照CREATE_FUNC实现CCLayer中的返回CCScene* 的静态函数,宏包装成CREATE_SCENE(XXLayer)
#define CREATE_SCENE(__TYPE__)\ CCScene *scene()\ { CCScene *scene=CCScene::create();\ __TYPE__ *lay ...