仿jquery - zketer
2019-11-18 本文已影响0人
Viker_bar
本文章主要模仿jquery源码, 实现源码中常用功能及框架分析, 有兴趣的童鞋可以了解一下, 下面是功能简介和zketer库源码
功能简介:
1: 命名空间$$, zKeter的分离
2: 无 new 构造对象
3: 选择器的实现
4: 扩展函数的实现
5: 链式调用的实现
6: ready的实现 [参考文档]
zketer源码:
/**
*
* @Author zpw
* @Describe 仿jQuery - zKeter库
* @Time 2019/10/12
*
*/
;(function(win,undefined){
//避免 document 之类的全局变量被其他插件修改
var document = window.document,
navigator = window.navigator,
location = window.location;
var zKeter,
init,
arr = [],
classTools = {};
//节省查找内存地址时间,提高效率
var slice = arr.slice,
concat = arr.concat,
push = arr.push,
indexOf = arr.indexOf,
toString = classTools.toString,
hasOwn = classTools.hasOwnProperty;
zKeter = function(selector,context){
return new zKeter.fn.init(selector);
};
zKeter.fn = zKeter.prototype = {
version : "0.1.0",
constructor: zKeter,
ready : function(fn){
// Mozilla、Opera和webkit 525+内核支持DOMContentLoaded事件
if(document.addEventListener) {
document.addEventListener('DOMContentLoaded', function() {
document.removeEventListener('DOMContentLoaded',arguments.callee, false);
fn();
}, false);
}
//IE
else if(document.attachEvent) {
// 确保当页面是在iframe中加载时,事件依旧会被安全触发
document.attachEvent('onreadystatechange', function() {
if(document.readyState == 'complete') {
document.detachEvent('onreadystatechange', arguments.callee);
fn();
}
});
// 如果是IE且页面不在iframe中时,轮询调用doScroll 方法检测DOM是否加载完毕
if(document.documentElement.doScroll && typeof window.frameElement === "undefined") {
try{
document.documentElement.doScroll('left');
}
catch(error){
return setTimeout(arguments.callee, 20);
};
fn();
}
}
return this;
}
};
init = zKeter.fn.init = function(selector) {
var elem,
length;
//$(""), $(null), $(undefined), $(false)
if(!selector){
return this;
}
//判断selector是否为字符串
if(typeof selector === "string"){
//Class选择器
if(selector.indexOf('.') > -1){
elem = document.querySelectorAll(selector);
for(var i=0,len=elem.length;i<len;i++){
this[i] = elem[i];
}
length = len;
}
//ID选择器
else if(selector.indexOf('#') > -1){
elem = document.querySelector(selector);
this[0] = elem;
length = 1;
}
//HTML标签
else{
elem = document.querySelectorAll(selector);
for(var i=0,len=elem.length;i<len;i++){
this[i] = elem[i];
}
length = len;
}
}
//判断selector是否为DOMElement
else if(selector.nodeType){
elem = selector;
length = 1;
}
this.length = length;
this.context = document;
this.selector = selector;
return this;
}
init.prototype = zKeter.fn;
//扩展合并函数
zKeter.extend = zKeter.fn.extend = function() {
var key,
target = this,
source = arguments[0] || {};
for (key in source) {
if (hasOwn.call(source,key)) {
if (typeof(source[key]) === "object") {
target[key] = (source[key].constructor === Array) ? [] : {};
arguments.callee(source[key], target[key]);
} else {
target[key] = source[key];
}
}
}
return target;
};
//扩展静态方法
zKeter.extend({
});
//扩展实例方法
zKeter.fn.extend({
});
window.zKeter = window.$$ = zKeter;
}(window));
分析图:
测试代码如下:
//无 new 构造对象
console.dir($$("#btn"));
//选择器的实现
console.dir($$("#btn"));
console.dir($$(".btn"));
console.dir($$("li"));
//扩展函数的实现
zKeter.extend({
speak : function(){
console.log("说话")
return this;
},
drink : function(){
console.log("喝水")
return this;
}
});
zKeter.fn.extend({
swimming : function(){
console.log("游泳")
return this;
},
run : function(){
console.log("跑步")
return this;
}
});
//链式调用的实现
$$.speak().drink();
$$("#btn").swimming().run();
//ready的实现
$$(document).ready(function(){
console.log("hello world");
});