前沿

这是之前淘宝的一道面试题,题目借用了 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遍历会导致性能问题,所以递归调用的方法可能会存在效率上的问题。所以各自权衡吧~

随机推荐

  1. Python 以正确的宽度在盒子中居中打印一个字符

    注意://为整除的意思 代码: # -*- coding:UTF-8 -*- sentence = input("Sentence:") screen_width = 80 tex ...

  2. oracle group 语句探究(笔记)

    1.group by语句在oracle中没有排序功能,必须依靠order by才能实现按照预定结果的排序 2.group by 的cube扩展 with test as ( id, name from ...

  3. AppCan4.0:开发者要做有价值的APP

    在当今的移动盛世,谈论APP“生存”话题未免太过沉重.但面对百万级移动应用大军所产生的激烈竞争,且保证“立而不倒”,这样的探讨就显得格外重要了. 主打“价值牌”才能“一条龙” 有这样一组数据,在我国, ...

  4. 关于asp.net和iis的进程/线程问题,假如网站有1000个人访问,会产生多少个进程/线程啊

    详解 ASP.NET异步   超好的文章

  5. c/c++常用代码--string trim

    typedef std::basic_string<TCHAR> tstring; inline static void trim(tstring& s){    s.erase( ...

  6. Android编程: Activity生命周期和LogCat使用

    学习内容:Activity生命周期和LogCat使用 ====Activity生命周期==== 图示(转载): 创建    onCreate重启    onRestart开始    onStart恢复 ...

  7. 【上传AppStore】iOS项目上传到AppStore步骤流程(第一章) - 上传新的app

    1.登录developer.apple.com 2.点击member center后 然后如下图 3.点击certificates Identifiers 进下图 界面基本介绍请看图 : 4. 其次创 ...

  8. Implementation Documentation[转]

    原文地址:http://prasanna-adf.blogspot.tw/2009/04/implementation-documentation.html Following are the lis ...

  9. (补)PSP三张表

    学生     司新红 日期  2014.3.14 教师  王建民 项目计划总结 编程 完善程序 测试程序 阅读书籍 日总计 周日 10:00-10:30 pm 0.5 周一 10:00-10:30 p ...

  10. backgroundworker的使用问题

    这几天做项目懒了就用backgroundworker这个控件,觉得它比多线程方便一些,然后这个线程里面在开线程,然后惨剧就发生了:当我打开一个主窗口后,在打开一个子窗口,子窗口里有个backgroun ...