- /**
- * 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[i] = source[i];
- }
- 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[key] === 'undefined' ? '' : data[key]
- })
- },
- })
- /**
- * 查询功能的模块化
- */
- $.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[i].indexOf("="); // 获取每个参数中的等号=小标的位置
- if (c == -1)
- continue // 如果没有发现等号=的位置,则忽略
- var d = arr[i].substring(0, c); // 截取等号前的参数名称
- var e = arr[i].substring(c + 1); // 截取等号后面的位置
- json[d] = 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) === '[object Array]';
- },
- })
- /**
- * 事件监听的核心代码
- */
- $.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[eventType] = 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 () {
-
- }
- })
复制代码
|