querySelector和querySelectorAll能获取以W3C标准规定的CSS选择器方式获取节点和节点集合(array-like)。

那么,一个类库的选择器模块假如不需要兼容IE67的话,实现就非常简单了。按照一般类库的使用方式,通常获取节点都是$(selector,context),

也就是在context里寻找selector,然后以数组的形式返回。利用querySelectorAll来封装这样的功能,是一件很简单的事情。

首先,最简单的,函数的内部实现转换一定是context.querySelectorAll(selector);再将其结果转换为数组,如下面实现:

var $ = function(selector,context){var elems = context.querySelectorAll(selector);return makeArray(elems);}//简单地将array-like转换为真正的数组
function makeArray(source){var target = [];for(var i = 0,len = source.length; i < len; i++){target[i] = source[i];}return target;
}

上面的代码,只是假设context是一个节点,但context有可能是一个节点集合,如我要在所有div中寻找span,写法将会是$('span',document.getElementsByTagName('div')),但querySelectorAll不能用在elements下,所以,需要将其一个一个分解成单个节点再分别获取selector组合成数组。那就可以先将context转换成数组,再遍历获取。如下:

var $ = function(selector,context){var elems = [];//通过nodeName判断context是否是节点if(context.nodeName){elems = context.querySelectorAll(selector);elmes = makeArray(elems);}else{context = makeArray(context);for(var i = 0, len = context.length; i < len; i++){var temp = context[i].querySelectorAll(selector);elems = elems.concat(makeArray(temp));}}return elems;}//简单地将array-like转换为真正的数组
function makeArray(source){var target = [];for(var i = 0,len = source.length; i < len; i++){target[i] = source[i];}return target;
}

这样子,貌似差不多了,但,假设有嵌套的相同名称的结构,如下:

<div id="a"><span>span1</span><span>span2</span><div id="a1"><span>span3</span></div>
</div>
<div id="b"><span>span4</span></div>

div#a里面还嵌套了<div id="a1"><span>span3</span></div>,按照上面的代码,这里面的span将会被重复获取,所以,需再加以区别。

可以通过判断context里面的包含关系,如div#a1是否包含在div#a里面,是的话则不在获取,如下代码:

var $ = function(selector,context){var elems = [];if(context.nodeName){elems = context.querySelectorAll(selector);elmes = makeArray(elems);}else{context = makeArray(context);var prevElem = context[0],curElem;for(var i = 0, len = context.length; i < len; i++){curElem = context[i];if(!contains(prevElem,curElem)){prevElem = curElem;var temp = curElem.querySelectorAll(selector);elems = elems.concat(makeArray(temp));}}}return elems;}//简单地将array-like转换为真正的数组
function makeArray(source){var target = [];for(var i = 0,len = source.length; i < len; i++){target[i] = source[i];}return target;
}function contains( root, el ){// 按照原则,先判断标准浏览器if( root.compareDocumentPosition ){return !!( root.compareDocumentPosition(el) & 16 );}else if( root.contains ){return root !== el && root.contains( el );}return false;
}

现在,就可以说完成了。

最后,我们整理下makeArray函数,让他可以更强大一点点,最终的完整代码如下:

var $ = function(selector,context){var elems = [];if(context.nodeName){elems = context.querySelectorAll(selector);elmes = makeArray(elems);}else{context = makeArray(context);var prevElem = context[0],curElem;for(var i = 0, len = context.length; i < len; i++){curElem = context[i];if(!contains(prevElem,curElem)){prevElem = curElem;elems = makeArray(curElem.querySelectorAll(selector),elems);}}}return elems;}//简单地将array-like转换为真正的数组
function makeArray(source,target){target = target || [];for(var i = 0,len = source.length; i < len; i++){target[target.length] = source[i];}return target;
}function contains( root, el ){// 按照原则,先判断标准浏览器if( root.compareDocumentPosition ){return !!( root.compareDocumentPosition(el) & 16 );}else if( root.contains ){return root !== el && root.contains( el );}return false;
}

参考资料:https://github.com/chenmnkken/easyjs/blob/master/src/selector.js

转载于:https://www.cnblogs.com/littledu/articles/2733151.html

标准浏览器的选择器封装相关推荐

  1. html5 图片上传,支持图片预览、压缩、及进度显示,兼容IE6+及标准浏览器

    原文:html5 图片上传,支持图片预览.压缩.及进度显示,兼容IE6+及标准浏览器 以前写过上传组件,见 打造 html5 文件上传组件,实现进度显示及拖拽上传,兼容IE6+及其它标准浏览器,对付一 ...

  2. IE下及标准浏览器下的图片旋转(二)—— Canvas(1)

    文章过长,一篇无法保存. IE下及标准浏览器下的图片旋转(一)--滤镜,CSS3 3. canvas canvas 是html5中的新标签,使用canvas之前我们先看下它的定义:<canvas ...

  3. IE下及标准浏览器下的图片旋转(二)—— Canvas(2)

    文章过长,一篇无法保存 IE下及标准浏览器下的图片旋转(二)-- Canvas(1) 同样,作为最后,我们使用使用jquery也为canvas写个旋转demo: javascript: $(funct ...

  4. 基于JxBrowser的浏览器控件封装实现Java Swing的浏览器集成

    基于JxBrowser的浏览器控件封装实现Java Swing的浏览器集成 背景 实现目标 实现代码 运行效果 完整的代码及依赖jar文件下载 背景 进期客户提出在一个Java Swing项目要集成另 ...

  5. 探讨浏览器CSS选择器的权重!!!

    <!DOCTYPE html> <html> <head lang="en"><meta charset="UTF-8" ...

  6. web标准 浏览器介绍 开发工具介绍 HTML介绍 HTML颜色介绍 规范 HTML结构详解 {前端之前端初识}...

    前端之前端初识 前端初识 本节目录 一 web标准 二 浏览器介绍 三 开发工具介绍 四 HTML介绍 五 HTML颜色介绍 六 规范 七 HTML结构详解 一 web标准 web准备介绍: 1.w3 ...

  7. 区分IE6、IE7、IE8及标准浏览器的最佳方法

    由于E6和IE7存在不同的Css  bug.所以有有时候在IE6中运行可以,但是在IE7中运行会出现想不到的错误,现在IE8,IE10都会有不同的问题. CSS Hack 直接在CSS文件中写CSS ...

  8. 调用金蝶EAS系统标准凭证接口,封装凭证对象,调用业务接口前需先登录

    第三方系统与金蝶EAS系统凭证集成时,调用金蝶EAS系统标准凭证接口WSGLWebServiceFacade,下载对应的wsdl文件,生成客户端代码之后,可参考以下接口调用方式. 与EAS系统进行凭证 ...

  9. 跨浏览器Ajax调用封装

    2019独角兽企业重金招聘Python工程师标准>>> /*** 执行基本ajax请求,返回XMLHttpRequest* Ajax.request(url,{* async 是否异 ...

最新文章

  1. Adaboost通俗易懂入门教程
  2. php 调用php webservice
  3. 解读金山网盾3.5 0day漏洞免疫技术
  4. OpenJDK install
  5. ubuntu 12.04下apache 配置家目录地址
  6. STM32之Systick(系统时钟滴答定时器)
  7. 【c】写头文件要加#ifndef,#define, #endif
  8. 基于SVM的python简单实现验证码识别
  9. Android第五十二期 - 云之讯的代码混淆
  10. Linux驱动的platform机制
  11. LM算法+推导+C++代码实践
  12. 【Excel高阶技巧】条件函数、查找函数、字符串相关函数、公式审核、保护工作表/工作簿、模拟分析、宏
  13. 怎么样才能防御dos攻击
  14. Tensorflow2.5(gpu)+Python3.9+Spyder5的平台搭建
  15. Detecting Spacecraft Anomalies Using LSTMs and Nonparametric Dynamic Thresholding
  16. 智能家居雷达模块应用,毫米波雷达传感器,雷达感应技术应用
  17. AI Studio 精品项目 | 基于Few-shot Learning实现中文科学文献学科分类
  18. Access内置SQL函数
  19. 5V降压1.8V芯片,稳压电路设计建议PW2059
  20. Cadence IC618使用

热门文章

  1. 3.5.4 CSMA/CD 协议
  2. 一个电子工程师的经验之谈!
  3. Word中分节符的作用
  4. 如何有效抵抗电脑辐射
  5. 图解yolo目标检测如何进行运动估计
  6. jittor 和pytorch的生成网络对比之aae
  7. pyhton列表习题
  8. 只此一招,全屏操作从此易如反掌
  9. MFC中的几个常用类——CWnd
  10. 基于MATLAB和Python的频谱分析