/**
* Created by xiuxiu on 2018/6/16
*/
// 框架的本质
/**
* 函数:工具
* 对象:工具包
* 框架:多个工具包
*/
/*
* V1.0:使用原型的方式实现一个框架
* 实现了对象获取,字符串操作,数据类型的检测等功能【extend, queryString, query是核心功能】
* on函数的封装(事件监听,考虑浏览器的兼容性)
* V2.0:使用对象的字面量方式来封装一个框架(JSON格式来封装一个框架)
* V3.0:使用Extend方式来封装一个框架
* V4.0: 事件框架的封装
* 事件流机制Dom2.0
* on,un,getEvent, getTarget,delegate等方法
* */
// 框架基础代码
var xframe = function () {
}
/**
* 使用原型方式封装框架
* @type {{$id: xframe.$id, $tag: xframe.$tag, ltrim: xframe.ltrim, rtrim: xframe.rtrim, trim: xframe.trim, formateString: xframe.formateString, isNumber: xframe.isNumber, isBoolean: xframe.isBoolean, isString: xframe.isString, isUndefined: xframe.isUndefined, isObject: xframe.isObject, isNull: xframe.isNull, isArray: xframe.isArray, extend: xframe.extend, queryString: xframe.queryString, query: xframe.query, on: xframe.on}}
*/
xframe.prototype = {
// 先写出接口,不用事先事先这个方法
/**
* 给一个对象扩充功能:将一个对象的所有属属性拷贝到另外一个对象上去(如果没有的话,就直接把属性添加进去)
* // 将一个对象的方法,拷贝给另外一个对象
* @param target
* @param source
* @returns {*}
*/
extend: function (target, source) {
// 把source对象的所有属性拷贝到target中去
for (var i in source) {
target = source;
}
return target;
},
}
// 创建一个我的框架对象实例
var $ = new xframe();
//Extend的好处:可以把框架的功能进行模块化, 实现功能的分类管理
/**
* 字符串的操作
*/
$.extend($, {
// 常用的字符串的操作-----------------------------------------------------------------------
/**
* 去除字符串左边的空格
* @param str
*/
ltrim: function (str) {
return str.replace(/(^\s*)/g, "");
},
/**
* 去除字符串右边的空格
* @param str
*/
rtrim: function (str) {
return str.replace(/(\s*$)/g, "");
},
/**
* 去除字符串中的空格
* @param str
*/
trim: function (str) {
return str.replace(/(^\s*)|(\s*$)/g, "");
},
/**
* 实现一个简单的数据绑定
* @param str
* @param data
*/
formateString: function (str, data) {
return str.replace(/@\((\w+)\)/g, function (match, key) {
return typeof data === 'undefined' ? '' : data
})
},
})
/**
* 查询功能的模块化
*/
$.extend($, {
/**
* 查询地址栏的字符串,用于页面间的传参(通过location.search可以获取查询字符串)
* @returns {{}}
*/
queryString: function () {
var str = window.location.search.substring(1); // 获取查询字符串,即"id=1&name=location"的部分
var arr = str.split('&'); // 用&分割数组
var json = {}; // 定义一个临时对象
// 遍历数组
for (var i = 0; i < arr.length; i++) {
var c = arr.indexOf("="); // 获取每个参数中的等号=小标的位置
if (c == -1)
continue // 如果没有发现等号=的位置,则忽略
var d = arr.substring(0, c); // 截取等号前的参数名称
var e = arr.substring(c + 1); // 截取等号后面的位置
json = e; // 用名称 : 值 的格式存储在json对象中
}
return json; // 返回json对象【json中存储数据的时候,key必须是唯一的,否则后面的会覆盖掉前面的内容哈】
},
/**
* 页面参数的查询(普通查询)
* @returns {string}
*/
query: function () {
var params = window.location.search; // 获取 arams : ? id , date……
var arr = params.substring(1).split(',');
return arr;
},
})
/**
* 常用数据类型的检测
*/
$.extend($, {
// 常用数据类型检测-----------------------------------------------------------------------------
/**
* 用于检测一个值是不是数字
* 要点:1.js中的==和!= 比较, 若两者类型不同,会先转换类型,再做值比较,最后返回值比较结果(不严格)
* 2.===和!=== 只有在相同类型的情况下,才会比较二者的值,否则直接返回false (比较更严格)
* @param val
* @returns {boolean}
*/
isNumber: function (val) {
// isFinite()函数是js自带函数,会过滤掉NaN和Infinity类型
return typeof val === 'number' && isFinite(val)
},
/**
* 是不是布尔类型
* @param val
* @returns {boolean}
*/
isBoolean: function (val) {
return typeof val === 'boolean';
},
/**
* 是不是字符串类型
* @param val
* @returns {boolean}
*/
isString: function (val) {
return typeof val === 'string';
},
/**
* 是不是未定义类型
* @param val
* @returns {boolean}
*/
isUndefined: function (val) {
return typeof val === 'undefined';
},
/**
* 是不是Object类型
* @param str
* @returns {boolean}
*/
isObject: function (str) {
if (str == null || typeof str === 'undefined') {
return false;
}
return typeof str === 'object';
},
/**
* 是否为null
* @param val
* @returns {boolean}
*/
isNull: function (val) {
return val === null;
},
/**
* 是否为数组类型
* @param arr
* @returns {boolean}
*/
isArray: function (arr) {
if (arr === null || typeof arr === 'undefined') {
return false;
}
// 这里可以通过两种方式来判断
return arr.constructor === Array || arr.prototype.toString.call(arr) === '';
},
})
/**
* 事件监听的核心代码
*/
$.extend($, {
/**
* 实现一个兼容各大浏览器的事件监听方法
* @param id 对象的ID
* @param type 事件类型:click, mouseover, mouseout……
* @param fn 事件处理的回调函数
*/
on: function (id, type, fn) {
//var dom = this.$id(id); // 获取这个dom对象
// 这种写法的好处:(三目运算符的使用,增强框架的健壮性)
// 1. 可以直接解析DOM节点
// 2. 可以直接把传过来的ID号码转换为DOM节点
var dom = !$.isString(id) ? id : document.getElementById(id);
// 如果浏览器支持addEventlistener方法
if (dom.addEventListener) {
// W3C
dom.addEventListener(type, fn, false);
} else {
// 微软公司提供的时间监听方法(不支持事件冒泡的方法)
if (dom.attachEvent) {
// btn.attachEvent('onclick', fn)
dom.attachEvent('on' + type, fn);
}
}
},
/**
* 用于解除事件的绑定(兼容浏览器)【使用较少】
* @param id
* @param type
* @param fn
*/
un : function (id, type, fn) {
// 这里先换一种方式来判断
var dom = !$.isString(id) ? id : document.getElementById(id);
// 判断浏览器是否兼容某种特效
if (dom.removeEventListener){
// 标准的W3c方式
dom.removeEventListener(type, fn);
} else if (dom.attachEvent){
// 微软的解除方式
dom.detachEvent(type, fn);
}
},
/**
* 鼠标点击事件
* @param id
* @param fn
*/
click : function (id, fn) {
this.on(id, 'click', fn);
},
/**
* 鼠标进入事件
* @param id
* @param fn
*/
mouseover : function (id, fn) {
this.on(id, 'mouseover', fn);
},
/**
* 鼠标移出事件
* @param id
* @param fn
*/
mouseout : function (id, fn) {
this.on(id, 'mouseout', fn);
},
/**
* 鼠标移入移出【鼠标悬浮事件】
* @param id
* @param fnOver
* @param fnOut
*/
hover : function (id, fnOver, fnOut) {
if (fnOver){
this.on(id, 'mouseover', fnOver);
}
if (fnOut){
this.on(id, 'mouseout', fnOut);
}
},
/**
* 用于获取Event对象(解决了浏览器的兼容性问题)
* @param e
* @returns {Event}
*/
getEvent : function (e) {
return e ? e : window.event;
},
/**
* 使用短路表达式来进行代码优化(尽量少用if语句)
* @param e
* @returns {*|Event | undefined}
*/
getEvent : function (e) {
return e || window.event;
},
/**
* 获取事件目标对象(兼容性)
* @param e
* @returns {Element | any}
*/
getTarget : function (e) {
// 获取事件目标
var e = this.getEvent(e);
// 使用短路表达式去获取目标
return e.target || e.srcElement;
},
/**
* 阻止默认事件的行为(兼容性)
* @param e
*/
preventDefault : function (e) {
var ev = this.getEvent(e)
// 三木表达式阻止默认事件
ev.preventDefault ? ev.preventDefault() : (ev.returnValue = false);
},
/**
* 阻止事件冒泡(兼容性)
* 防止事件向外传播
* @param e
*/
stopPropagation : function (e) {
// 获取事件Event对象,解除事件冒泡
this.getEvent(e).stopPropagation || (this.getEvent(e).cancelBubble = true);
},
/**
* 使用委托的方式实现事件
* @param pid
* @param eventType
* @param selector
* @param fn
*/
delegate: function(pid, eventType, selector, fn) {
var parent = $.$id(pid);
function handle(e) {
var target = $.getTarget(e);
// 这里会打印输出nodeName
console.log(target.nodeName); // tr
// select 这里传过来的是一个选择器, selector == 'tr'
if (target.nodeName.toLowerCase() === selector || target.id === selector || target.className.indexOf(selector) != -1){
// 使用call修改了this的指向, 去调用fn传过来的函数, 把当前的这个target对象传过去
fn.call(target);
}
}
parent = handle;
}
})
/**
* 选择器的操作
*/
$.extend($, {
// 根据ID,Tag获取对象-------------------------------------------------------------------------
/**
* 根据ID获取对象
* @param id
* @returns {HTMLElement | null}
*/
$id: function (id) {
return document.getElementById(id)
},
/**
* 根据tagName获取对象
* @param tag
* @returns {any}
*/
$tag: function (tag) {
return document.getElementsByTagName(tag)
},
$class : function () {
}
})
评论
填写昵称与邮箱即可评论,无需登录。