js原生框架

(function(global) {
var document = global.document,
init,
support = {};
// 核心函数
function itcast(selector) {
return new itcast.fn.init(selector);
}
// 核心原型--方法库
itcast.fn = itcast.prototype = {
constructor: itcast,
length: 0,
each: function(callback) {
itcast.each(this, callback);
// 实现链式编程
return this;
},
get: function(index) {
/*index = index - 0;
index = index < 0 ? index + this.length : index;
return this[index];*/
return index != null ?
(index < 0 ? this[index + this.length] : this[index]) :
Array.prototype.slice.call(this);
},
eq: function(index) {
return itcast(this.get(index));
},
first: function() {
return this.eq(0);
},
last: function() {
return this.eq(-1);
}
};
// 构造函数init
init = itcast.fn.init = function(selector) {
// handle: null undefined ''
if (!selector) {
return this;
}
// handle: string
if (itcast.isString(selector)) {
// handle: html string
if (itcast.isHTML(selector)) {
// 将html字符串 转换成 html元素
// '<div><p>123</p></div><div><p>456</p></div>'
// var o = {} == {0: 1,1: 2,2: 3,length: 3};
// var ar = [1, 2, 3];
Array.prototype.push.apply(this, itcast.parseHTML(selector));
}
// handle: selector
else {
Array.prototype.push.apply(this,
document.querySelectorAll(selector));
}
return this;
}
// handle: single node
if (itcast.isNode(selector)) {
this[0] = selector;
this.length = 1;
return this;
}
// handle: dom array | dom like array
if (itcast.isArrayLike(selector)) {
Array.prototype.push.apply(this, selector);
return this;
}
// handle: function DomContentLoaded onreadystatechange readyState === 'complete'
if (itcast.isFunction(selector)) {
// 获取到 之前已绑定的onload事件处理函数
var oldFn = global.onload;
// 判断其是否为函数类型。
// 如果是函数类型,那么就不要覆盖掉
if (itcast.isFunction(oldFn)) {
global.onload = function() {
oldFn();
selector();
}
} else { // 不是函数类型, 可以将其覆盖
global.onload = selector;
}
}
};
/* version 1.0
itcast.extend = itcast.fn.extend = function() {
var args = arguments;
for (var i = 0, l = args.length; i < l; i++) {
for (var k in args[i]) {
this[k] = args[i][k];
}
}
};*/
// version 2.0
itcast.extend = itcast.fn.extend = function() {
var args,
length = arguments.length,
target;

if(length > 1){
target = arguments[length - 1];
args = Array.prototype.slice.call(arguments, 0, length - 1);
} else {
args = arguments;
target = this;
}

for(var i = 0, l = args.length; i < l; i++){
for(var k in args[i]){
target[k] = args[i][k];
}
}
}

// 类型判断方法
itcast.extend({
isString: function(obj) {
return typeof obj === 'string';
},
isHTML: function(obj) {
return obj.charAt(0) === '<' && obj.charAt(obj.length - 1) === '>' &&
obj.length >= 3;
},
isNode: function(obj) {
return !!obj && 'nodeType' in obj;
// return !!obj && obj.nodeType;
},
isFunction: function(obj) {
return typeof obj === 'function';
},
isWindow: function(obj) {
return !!obj && obj.window === global;
},
isArrayLike: function(obj) {
var type = itcast.type(obj), // 获取obj类型
length = !!obj && 'length' in obj && obj.length; // 获取obj的length值
// 过滤window对象以及函数对象
if (itcast.isFunction(obj) || itcast.isWindow(obj)) {
return false;
}

return type === 'array' || length === 0 ||
typeof length === 'number' && length > 0 && (length - 1) in obj;
}
});
// 工具类方法
itcast.extend({
parseHTML: function(html) {
var div = document.createElement('div'),
node,
ret = [];

div.innerHTML = html;
for (node = div.firstChild; node; node = node.nextSibling) {
if (node.nodeType === 1) {
ret.push(node);
}
}
return ret;
},
each: function(obj, callback) {
var i = 0,
l = obj.length;

for (; i < l; i++) {
if (callback.call(obj[i], i, obj[i]) === false) {
break;
}
}
},
type: function(obj) {
if (obj == null) {
return obj + '';
}
return typeof obj === 'object' ?
Object.prototype.toString.call(obj).slice(8, -1).toLowerCase() :
typeof obj;
},
unique: function(arr) {
var ret = [];

if (!arr.indexOf) {
Array.prototype.indexOf = function(val) {
for (var i = 0, l = this.length; i < l; i++) {
if (this[i] === val) {
return i;
}
}

return -1;
};
}

for (var j = 0, jl = arr.length; j < jl; j++) {
if (ret.indexOf(arr[j]) === -1) {
ret.push(arr[j]);
}
}

return ret;
},
trim: function(str) {
return str == null ? '' : (str + '').replace(/^s+|s+$/g, '');
}
});
// 实现init对象继承自itcast.prototype
// init对象也 可 被称为itcast对象
init.prototype = itcast.prototype;
// 将 itcast函数 暴露在全局,提供给用户使用

// dom操作模块
itcast.fn.extend({
appendTo: function(target) {
// 存储所有分配出去的节点
var ret = [],
el;
// 统一target类型
target = itcast(target);
this.each(function(i, node) {
target.each(function(j, elem) {
el = j === 0 ? node : node.cloneNode(true);
ret.push(el);
elem.appendChild(el);
});
});
// 将ret转换成itcast对象返回,实现链式编程
return itcast(ret);
},
append: function(source) {
source = itcast(source);
source.appendTo(this);
return this;
},
remove: function() {
/*return this.each(function(i, node) {
node.parentNode.removeChild(node);
});*/
return this.each(function() {
this.parentNode.removeChild(this);
});
},
prependTo: function(target) {
var firstChild,
el,
ret = [],
self = this; // 存储prependTo方法的调用者
target = itcast(target);
target.each(function(i, elem) {
firstChild = elem.firstChild;
self.each(function(j, node) {
el = i === 0 ? node : node.cloneNode(true);
ret.push(el);
elem.insertBefore(el, firstChild);
});
});
return itcast(ret);
},
prepend: function(source) {
source = itcast(source);
source.prependTo(this);
return this;
},
empty: function() {
return this.each(function(i, el) {
el.innerHTML = '';
// this.innerHTML = '';
});
},
next: function() {
var ret = [],
node;

this.each(function(i, el) {
node = el.nextSibling;
while (node) {
if (node.nodeType === 1) {
ret.push(node);
break;
}
node = node.nextSibling;
}
});

return itcast(ret);
},
nextAll: function() {
var ret = [],
node;

this.each(function(i, el) {
for (node = el.nextSibling; node; node = node.nextSibling) {
if (node.nodeType === 1) {
ret.push(node);
}
}
});

return itcast(itcast.unique(ret));
},
prev: function() {
var ret = [];
this.each(function() {
for (var node = this.previousSibling; node; node = node.previousSibling) {
if (node.nodeType === 1) {
ret.push(node);
break;
}
}
});

return itcast(ret);
},
prevAll: function() {
var ret = [];
this.each(function() {
for (var node = this.previousSibling; node; node = node.previousSibling) {
if (node.nodeType === 1) {
ret.push(node);
}
}
});

return itcast(itcast.unique(ret));
},
before: function(source) {
source = itcast(source);
return this.each(function(i, elem) {
source.each(function(j, node) {
elem.parentNode.insertBefore(i === 0 ? node : node.cloneNode(true), elem);
});
});
},
after: function(source) {
var sibling;

source = itcast(source);
return this.each(function(i, elem) {
sibling = elem.nextSibling;
source.each(function(j, node) {
elem.parentNode.insertBefore(i === 0 ? node : node.cloneNode(true), sibling);
});
});
}
});

// 属性模块
itcast.propFix = {
'for': 'htmlFor',
'class': 'className'
};
itcast.each([
"tabIndex",
"readOnly",
"maxLength",
"cellSpacing",
"cellPadding",
"rowSpan",
"colSpan",
"useMap",
"frameBorder",
"contentEditable"
], function(i, v) {
itcast.propFix[v.toLowerCase()] = v;
});
console.log(itcast.propFix);
itcast.fn.extend({
attr: function(name, value) {
// 只传入一个参数
if (value == undefined) {
// 如果name为对象类型
if (typeof name === 'object') {
this.each(function(i, el) {
for (var k in name) {
el.setAttribute(k, name[k]);
}
});
} else { // 获取指定属性节点值
return this.length > 0 ? this[0].getAttribute(name) : undefined;
}
} else { // 如果传入两个参数
this.each(function(i, el) {
el.setAttribute(name, value);
});
}
// 实现链式编程
return this;
},
val: function(value) {
if (value == undefined) {
return this[0] ? this[0].value : undefined;
} else {
return this.each(function(i, dom) {
dom.value = value;
});
}
},
html: function(html) {
if (html == undefined) {
return this.length > 0 ? this[0].innerHTML : undefined;
} else {
return this.each(function(i, dom) {
dom.innerHTML = html;
});
}
},
text: function(txt) {
// console.log(support.textContent);
if (txt == undefined) {
return this.length > 0 ?
('textContent' in this[0] ? this[0].textContent : this[0].innerText) :
undefined;
} else {
return this.each(function(i, dom) {
if ('textContent' in dom) {
dom.textContent = txt;
} else {
dom.innerText = txt;
}
});
}
},
prop: function(name, value) {
var prop;
if (value == undefined) {
if (typeof name === 'object') {
this.each(function(i, el) {
for (var k in name) {
prop = itcast.propFix[k] ? itcast.propFix[k] : k;
el[prop] = name[k];
}
});
} else {
prop = itcast.propFix[name] ? itcast.propFix[name] : name;
return this.length > 0 ? this[0][prop] : undefined;
}
} else {
this.each(function(i, el) {
prop = itcast.propFix[name] ? itcast.propFix[name] : name;
el[prop] = value;
});
}

return this;
}
});

// 样式模块
itcast.fn.extend({
css: function(name, value) {
if (value == undefined) {
if (typeof name === 'object') {
this.each(function(i, el) {
for (var k in name) {
el.style[k] = name[k];
}
});
} else {
return this.length > 0 ?
(global.getComputedStyle ?
global.getComputedStyle(this[0])[name] :
this[0].currentStyle[name]) :
undefined;
}
} else {
this.each(function(i, el) {
el.style[name] = value;
});
}

return this;
},
hasClass: function(className) {
var ret = false;
this.each(function(i, el) {
if ((' ' + el.className + ' ').indexOf(' ' + className + ' ') !== -1) {
ret = true;
return false;
}
});

return ret;
},
addClass: function(className) {
return this.each(function(i, el) {
if (!itcast(el).hasClass(className)) {
el.className += ' ' + className;
}
});
},
removeClass: function(className) {
return this.each(function(i, el) {
el.className = itcast.trim((' ' + el.className + ' ').replace(' ' + className + ' ', ' '));
});
},
toggleClass: function(className, flag) {
return this.each(function(i, el) {
el = itcast(el);
flag = flag == undefined ? el.hasClass(className) : !flag;
if (flag) {
el.removeClass(className);
} else {
el.addClass(className);
}
});
}
});
// 事件模块
itcast.addEvent = function() {
return global.addEventListener ?
function(dom, type, fn, useCapture) {
dom.addEventListener(type, fn, useCapture || false);
} :
function(dom, type, fn) {
dom.attachEvent('on' + type, fn);
}
}();

itcast.removeEvent = function() {
return global.removeEventListener ?
function(dom, type, callback) {
dom.removeEventListener(type, callback);
} :
function(dom, type, callback) {
dom.detachEvent(type, callback);
}
}();

itcast.fn.extend({
on: function(type, callback, useCapture) {
return this.each(function(i, dom) {
itcast.addEvent(dom, type, callback, useCapture);
});
},
off: function(type, callback) {
return this.each(function(i, el) {
itcast.removeEvent(el, type, callback);
});
}
});

// 快捷事件绑定方法
itcast.each(["click", "dblclick", "mouseenter", "mouseleave", "mouseup", "mousedown", "keyup", "keydown", "keypress"], function(i, type) {
itcast.fn[type] = function(callback, useCapture) {
return this.on(type, callback, useCapture);
};
});

// Ajax模块
// 1:创建请求对象
function createRequest() {
return window.XMLHttpRequest ?
new window.XMLHttpRequest :
new window.ActivedXObejct('XMLHTTP');
}
// 2: 格式化数据
function formatData(data) {
var ret = [];

for (var k in data) {
ret.push(window.encodeURIComponent(k) + '=' + window.encodeURIComponent(data[k]));
}
// 小技巧:防止读取服务器缓存数据
ret.push(('_=' + Math.random()).replace('.', ''));
return ret.join('&');
}
itcast.extend({
ajaxSetting: {
type: "GET",
dataType: "text",
async: true,
contentType: "application/x-www-form-urlencoded",
timeout: 0,
data: null,
success: null,
fail: null
},
ajax: function(option) {
// 过滤无效参数值
if(!option || !option.url){
return;
}
// 请求上下文,存储请求的配置信息
var context = {},
postData = null;
itcast.extend(itcast.ajaxSetting, option, context);
// 1
var xhr = createRequest();
// 2
if(context.data){
if(context.type.toLowerCase() === "get"){
context.url += '?' + formatData(context.data);
} else {
postData = formatData(context.data);
xhr.setRequestHeader("Content-Type", context.contentType);
}
}
// 3
xhr.open(context.type.toUpperCase(), context.url, context.async);
// 4
xhr.onreadystatechange = function() {
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304){
context.success && context.success(context.dataType.toLowerCase() === 'json' ?
JSON.parse(xhr.responseText) : xhr.responseText, context, xhr
);
} else {
context.fail && context.fail({"errCode": xhr.status, "message": "请求错误."});
}
}
};
// 5
xhr.send(postData);
}
});

// 判断浏览器是否支持textContent属性。
(function() {
var div = document.createElement('div');
support.textContent = 'textContent' in div;
}());

global.$ = global.itcast = itcast;

}(window));

这是我自己写的原生js框架!其中有些请求数据或许有点抽象,只要仔细写几遍,就会有所感悟的!新人博客,喜欢的请点个赞!谢谢!知识贵在分享,生活贵在快乐!

原文地址:https://www.cnblogs.com/Gabriels/p/6296596.html