您的位置:首页 > Web前端 > JQuery

纯JavaScript实现简易版的jQuery选择器,支持链式调用

2017-06-19 00:00 801 查看
jQuery是一个高端而不失奢华的框架。奇特的设计思想使其通过链式调用而显得更加整洁。不过这种链式模式是基于原型继承的,并且在每一个原型方法的实现上都返回当前对象this,使当前对象一直处于原型链作用域的顶端。这样即可实现链式调用。

本文基于原型式继承实现了一个类似jQuery的选择器。源码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head>
<meta charset="utf-8">
<style>
#containers div {
margin-right: 5px;
border:solid 1px blue;
padding: 5px;
float: left;
}
</style>
</head>
<body>
<div id="container"></div>
<span id="tspan" name="nspan">test</span>
<script type="text/javascript">
//小试牛刀,JavaScript的原型式继承
var A = function(){
return A.fn;
}
A.fn = A.prototype = { //为了减少变量的创建,直接将A的原型作为A的一个属性fn
length:2,
size:function(){
return this.length;
}
}
console.log(A().size());

//一个简易版jQuery选择器
var $ = function(selector,context){
return new $.fn.init(selector,context);
}
$.fn = $.prototype = {
constructor:$,//强化构造器,将__proto__指向$
push:[].push,
sort:[].sort,
splice:[].splice,
init : function(selector,context){
this.length = 0,
context = context || document;
//如果是id选择符,按位非将-1转化为0,转化为布尔值false
if(~selector.indexOf("#")){
this[0] = document.getElementById(selector.slice(1));
this.length = 1;
} else {
var doms = context.getElementsByTagName(selector),
i=0,
len = doms.length;
for(;i<len;i++){
this[i] = doms[i];
}
this.length = len;
}
this.context = context;
this.selector = selector;

return this;
},
length:2,
size:function(){
return this.length;
}
}
$.fn.init.prototype = $.fn;//将构造函数的原型指向一个已存在的对象

//方法拓展
$.extend = $.fn.extend = function(){
var i=1,//拓展对象从第2个参数算起
len = arguments.length,
target = arguments[0],//第1个对象为源对象
j;
if(i == len){//如果只有1个参数
target = this;//源对象为当前对象
i--;
}
for(;i<len;i++){
for(j in arguments[i]){
target[j] = arguments[i][j];//拓展源对象
}
}
return target;
}
//1、拓展监听事件
$.fn.extend({
on:(function(){
if(document.addEventListener){
return function(type,fn){
var i = this.length - 1;
for(;i>=0;i--){
this[i].addEventListener(type,fn,false);
}
return this;
}
}
})()
});
//2、拓展attr方法
$.fn.extend({
attr:function(){
var arg = arguments,
len = arg.length;
if(this.length < 1){
return this;
}
if(len === 1){ //如果只有1个参数
if(typeof arg[0] === 'string'){//为string则获取第一个元素的属性值
return this[0].getAttribute(arg[0]);
} else if(typeof arg[0] === 'object'){ //获取设置的多个属性值
for(var i in arg[0]){
for(var j = this.length - 1;j>=0;j--){
this[j].setAttribute(i,arg[0][i]);
}
}
}
} else if(len === 2){ //2个参数则设置属性
for(var j=this.length-1;j>=0;j--){
this[j].setAttribute(arg[0],arg[1]);
}
}
return this;
}
});
//3、拓展html方法
$.fn.extend({
html:function(){
var arg = arguments,
len = arg.length;
if(len === 0){
return this[0] && this[0].innerHTML;
} else {
for(var i=this.length-1;i>=0;i--){
this[i].innerHTML = arg[0];
}
}
return this;
}
});

//使用方法:获取值
console.log($("#tspan").attr("name"));//输出nspan
console.log($("#tspan").html());//输出test

//设置值,链式操作
$("span").attr("class","demo").html("add html").on("click",function(){
console.log("已被点击...");
});
</script>

</body>

</html>

执行结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  JavaScript