【JS】仿Jquery

/*

  • @caiquan (396022671.qq.com)
  • @version 1.0 / 2015-09-14
    1. 创建
  • @version 2.0 / 2015-11-16
    1. SLIDER:移动端轮播图
    2. LOAD:移动端顶部下拉刷新、底部加载更多、左右侧边栏滑动
  • @version 3.0 / 2016-1-14
    1. 使用原型链重写
      */

(function(){

/*
    给构造函数Function的原型添加方法method
    Function / Object / String / Array 实质上都是一个函数
    是函数就能继承method方法
    通过method方法添加框架方法
*/
Function.prototype.method = function(name,fn){
    this.prototype[name] = fn;
}

var _O = Object;
var _S = String;
var _A = Array;
// 全局变量$cq,用于外部调用
var _F = new Function();
window.$cq = new _F();


/* element string array 操作 */
_F.method('id'                  ,_id);                  // 选取id
_S.method('trim'                ,_trim);                // 清除string前后空格
_S.method('trimL'               ,_trimLeft);
_S.method('trimR'               ,_trimRight);
_O.method('text'                ,_text);                // 输入text纯文本(带html标签用innerHTML)
_O.method('textAppend'          ,_textAppend);          // 追加text纯文本(带html标签用innerHTML)
_O.method('getIndex'            ,_getIndex);            // 获取指定对象在数组中的序列号(group中排在第几个)
_O.method('getStyle'            ,_getStyle);            // 获取样式,不能获取复合样式,如background,只能获取background-color这样的
_O.method('setStyle'            ,_setStyle);            // 设置行内style
_F.method('htmlCollectionToArr' ,_htmlCollectionToArr); // 将getElementsByTagName(Name)获取到的对象,转换成数组返回
_F.method('removeBlankNode'     ,_removeBlankNode);     // childNodes获取的对象,删除空文本节点后,数组形式返回

/* event */
_F.method('e'                   ,_e);                   // 获取event兼容对象
_F.method('getEvent'            ,_getEvent);            // 获得event对象
_F.method('getTarget'           ,_getTarget);           // 获取事件对象

/* 事件侦听 / 取消冒泡 / 阻止默认事件 */
_O.method('aEvent'              ,_addEvent);            // 添加事件侦听
_O.method('rEvent'              ,_removeEvent);         // 移除事件侦听
_F.method('cancelBubble'        ,_cancelBubble);        // 取消冒泡
_F.method('preventDefault'      ,_preventDefault);      // 取消默认事件

/* 浏览器 */
_F.method('getScrollTop'        ,_getScrollTop);        // 获取scrollTop
_F.method('getScrollLeft'       ,_getScrollLeft);       // 获取scrollLeft
_F.method('getBrower'           ,_getBrower);           // 获取浏览器名称和版本
_F.method('isMobile'            ,_isMobile);            // 判断是否是移动设备

_O.method('animate'             ,_animate);             // 动画

/* cookie */
_F.method('getCookie'           ,_getCookie);           // 获取指定cookie
_F.method('getCookieAll'        ,_getCookieAll);        // 获取所有cookie
_F.method('setCookie'           ,_setCookie);           // 设置cookie
_F.method('removeCookie'        ,_removeCookie);        // 删除cookie

/* AJAX */
_F.method('AJAX'                ,_AJAX);                //AJAX请求

/* plug */
_F.method('slider'              ,_slider);              // 轮播图
_F.method('loadMobile'          ,_loadMobile);          // mobile顶部刷新 + 底部加载更多 + 侧边栏
_F.method('selectCheckbox'      ,_selectCheckbox);      // 复选框全选/取消全选
_F.method('cb'                  ,_cb);
_F.method('grade'               ,_grade);
_F.method('SLIDBLOCK'           ,_SLIDBLOCK);           // checkbox滑块(打开/关闭)
_F.method('tabControl'          ,_tabControl);          // 选项卡切换

/* 类操作 */
_F.method('extend'                      ,_extend);                      // 类的继承
_F.method('mixin'                       ,_mixin);                       // 类的聚合
_F.method('interfaceAttrImplement'      ,_interfaceAttrImplement);      // 接口:属性检验法
_F.method('interfaceCreate'             ,_interfaceCreate);             // 接口:鸭式变形法(新建接口)
_F.method('interfaceEnsuerImpletement'  ,_interfaceEnsuerImpletement);  // 接口:鸭式变形法(检验实现)


/*
解释:切换选项卡
示例:
    DOM:
        

t1

t2

t3

m1
m2
m3
调用: var titleArr = document.getElementsByTagName('h3'); var mainArr = document.getElementsByTagName('div'); cn = 'tSelect'; new $cq.tabControl().start(titleArr,mainArr,cn); */ function _tabControl(){ var t,m,c; this.start = function(titleArr,mainArr,cn){ init(titleArr,mainArr,cn); bindEvent(); } function init(titleArr,mainArr,cn){ t = titleArr; m = mainArr; c = cn; } function bindEvent(){ for (var i = 0; i < t.length; i++) { _addEvent('click',action,t[i]) }; } function action(){ var index = _getIndex(t,this); for (var i = 0; i < t.length; i++) { if (i==index) { t[i].className = c; _setStyle('display:block',m[i]); }else{ t[i].className = ''; _setStyle('display:none',m[i]); } }; } } /* 解释:滑块打开/关闭 示例: DOM:
CSS: .slidOpen, .slidClose{ line-height: 1.5em; width: 3em; position: relative; padding: 1px; cursor: pointer; overflow: hidden; border-radius: 0.7em; } .slidOpen dt, .slidClose dt{ background-color: #fff; width: 1.5em; height: 1.5em; line-height: 1.5em; text-align: center; border-radius: 0.7em; box-shadow: 0em 0em 0.2em #666; position: relative; left: 1.5em; } .slidOpen{ animation :slidOpenColor 500ms forwards; -moz-animation :slidOpenColor 500ms forwards; -webkit-animation :slidOpenColor 500ms forwards; -o-animation :slidOpenColor 500ms forwards; } .slidOpen dt{ animation :slidOpenOffset 500ms forwards ; -moz-animation :slidOpenOffset 500ms forwards ; -webkit-animation :slidOpenOffset 500ms forwards ; -o-animation :slidOpenOffset 500ms forwards ; } .slidClose{ animation :slidCloseColor 500ms forwards; -moz-animation :slidCloseColor 500ms forwards; -webkit-animation :slidCloseColor 500ms forwards; -o-animation :slidCloseColor 500ms forwards; } .slidClose dt{ animation :slidCloseOffset 500ms forwards ; -moz-animation :slidCloseOffset 500ms forwards ; -webkit-animation :slidCloseOffset 500ms forwards ; -o-animation :slidCloseOffset 500ms forwards ; } @keyframes slidOpenColor{ 0% {background-color: #ccc} 100%{background-color: #4cd964} } @-moz-keyframes slidOpenColor{ 0% {background-color: #ccc} 100%{background-color: #4cd964} } @-webkit-keyframes slidOpenColor{ 0% {background-color: #ccc} 100%{background-color: #4cd964} } @-o-keyframes slidOpenColor{ 0% {background-color: #ccc} 100%{background-color: #4cd964} } @keyframes slidOpenOffset{ 0% {left: 0em;} 100%{left: 1.5em;} } @-moz-keyframes slidOpenOffset{ 0% {left: 0em;} 100%{left: 1.5em;} } @-webkit-keyframes slidOpenOffset{ 0% {left: 0em;} 100%{left: 1.5em;} } @-o-keyframes slidOpenOffset{ 0% {left: 0em;} 100%{left: 1.5em;} } @keyframes slidCloseColor{ 0% {background-color: #4cd964;} 100%{background-color: #ccc;} } @-moz-keyframes slidCloseColor{ 0% {background-color: #4cd964;} 100%{background-color: #ccc;} } @-webkit-keyframes slidCloseColor{ 0% {background-color: #4cd964;} 100%{background-color: #ccc;} } @-o-keyframes slidCloseColor{ 0% {background-color: #4cd964;} 100%{background-color: #ccc;} } @keyframes slidCloseOffset{ 0% {left: 1.5em;} 100% {left: 0em;} } @-moz-keyframes slidCloseOffset{ 0% {left: 1.5em;} 100% {left: 0em;} } @-webkit-keyframes slidCloseOffset{ 0% {left: 1.5em;} 100% {left: 0em;} } @-o-keyframes slidCloseOffset{ 0% {left: 1.5em;} 100% {left: 0em;} } 调用: new $cq.SLIDBLOCK().start(); */ function _SLIDBLOCK(){ var slidBlocks = []; var init = function(){ var dl = document.getElementsByTagName('dl'); var className = null; for (var i = 0; i < dl.length; i++) { className = dl[i].className; if (className == 'slidOpen' || className == 'slidClose') { slidBlocks.push(dl[i]); }; }; } var slidActive = function(){ var className = this.className; if (className == 'slidOpen') { this.className = 'slidClose'; } else if (className == 'slidClose') { this.className = 'slidOpen';}; this.blur(); this.getElementsByTagName('dt')[0].blur(); } var bindEvent = function(){ if (slidBlocks.length <=0) { console.log('未获取到滑动块');return; }; for (var i = 0; i < slidBlocks.length; i++) { _addEvent('click',slidActive,slidBlocks[i]); }; } this.start = function(){ init(); bindEvent(); } } /* 解释:类似五星☆好评 示例: DOM:

CSS: ul{zoom:1;background-color: #f1f1f1;overflow: hidden;} ul:after{content: '';display: block;height: 0;overflow: hidden;clear: both;} li{width: 20px;height: 20px;float:left; list-style: none;margin:20px; border-radius: 12px; background-position: center;background-repeat: no-repeat;background-size: auto 100%;} 调用: var arg = { tips :['非常差','差','一般','好','非常好'], iconBg :{bad:'../images/starGray.png',good:'../images/starYellow.png',normal:'../images/star.png'}, iconBox :document.getElementsByTagName('ul')[0], iconList :document.getElementsByTagName('li'), tipBox :document.getElementsByTagName('p')[0] }; new $cq.grade(arg).start(); */ function _grade(_agr){ var iconBox, // icon 外壳: ul标签 iconList, // icon 列表:li标签集合 iconBg, // icon 图片类型:{bad:'', good:'',normal:''} iconBgNow, // icon 此时的图片类型 tipBox, // 提示框: p标签 tips, // 提示 ['非常差','差','一般','好','非常好'] dataNum; // 表示高亮的icon数 this.start = function(){ // 初始化 init(); // 绑定事件 bindEvent(); } function init(){ // 初始化变量,从参数获取值 iconBox = _agr.iconBox; iconList = _agr.iconList tipBox = _agr.tipBox iconBg = _agr.iconBg; tips = _agr.tips // 从iconBox获取高亮数 dataNum = iconBox.getAttribute('data-num'); // 初始化icon的颜色和高亮数,输出提示 BgColor(dataNum); changeColor(dataNum); Tip(dataNum) } // 绑定事件 function bindEvent(){ for (var i = 0; i < iconList.length; i++) { _addEvent('mouseover',toChange,iconList[i]); _addEvent('click',toChange,iconList[i]) }; _addEvent('mouseout',toChange,iconBox); } // 选择当前icon的颜色/图片 function BgColor(num){ num<2?iconBgNow=iconBg.bad:iconBgNow=iconBg.good; } // 改变icon状态 function toChange(){ var event = $cq.getEvent(); var _this = $cq.getTarget(event); var num = _getIndex(iconList,_this); BgColor(num); Tip(num) switch(event.type){ case 'click' : dataNum = num; iconBox.setAttribute('data-num',dataNum); break; case 'mouseover' : changeColor(num);break; case 'mouseout' : if (_this == iconBox) {BgColor(dataNum);Tip(dataNum);changeColor(dataNum);};break; } } // 改变icon颜色/图片 function changeColor(num){ for (var i = 0; i < iconList.length; i++) { i<=num?iconList[i].style.backgroundImage = 'url('+iconBgNow+')':iconList[i].style.background = 'url('+iconBg.normal+')'; }; } // 输出提示 function Tip(num){ tipBox.innerHTML = tips[num]; } } /* 解释:自定义复选框 示例: DOM: CSS: #cb{display: inline-block;} #cb input{visibility: hidden;} 调用: new $cq.cb().start({ id:'cb', width:'2.32em', height:'2.32em', def:'images/cbDef.png', ok:'images/cbOk.png' }); */ function _cb(){ var lab = null, inp = null, args=null,styleBase=null; this.start = function(arg){ init(arg); bindEvent(); } function init(arg){ args = arg; lab = _id(arg.id); inp = lab.getElementsByTagName('input')[0]; styleBase = 'width:'+arg.width+';height:'+arg.height+';display: inline-block;'; var sty = styleBase + 'background: url('+arg.def+') no-repeat center center / '+arg.width+' '+arg.height; _setStyle(sty,lab) _setStyle('visibility: hidden;',inp) } function bindEvent(){ _addEvent('change',changeState,inp); } function changeState(){ switch(this.checked){ case true:_setStyle(styleBase + 'background: url('+args.ok+') no-repeat center center / '+args.width+' '+args.height,lab); break; case false:_setStyle(styleBase + 'background: url('+args.def+') no-repeat center center / '+args.width+' '+args.height,lab); break; } } } /* 功能: 复选框全选/取消全选 示例: DOM:
调用: var list = $cq.id('clist').getElementsByTagName('input'); var btn = $cq.id('btn'); var cb = new $cq.selectCheckbox(list,btn); cb.start(); 备注:_cbList:checkbox列表数组,_cbAll:全选chechbox */ function _selectCheckbox(_cbList,_cbAll){ this.start = function(){ init(); bindEvent(); } var _this = this; var oInps = _cbList; var oInpAll = _cbAll; function init(){ for (var i = 0; i < oInps.length; i++) { if (!oInps[i].checked) { oInpAll.checked = false; break; } if (i == oInps.length-1) { oInpAll.checked = true; }; }; } function bindEvent(){ _addEvent('change',cList,oInpAll); for (var i = 0; i < oInps.length; i++) { _addEvent('change',cAll,oInps[i]) }; } function cList(){ var e = $cq.getEvent(); oInpAll.checked?listCheck(true):listCheck(false); } function listCheck(_isTrue){ for (var i = 0; i < oInps.length; i++) { oInps[i].checked = _isTrue; }; } function cAll(){ var e = $cq.getEvent(); var o = $cq.getTarget(e); var check = o.checked; if (!check) { oInpAll.checked = false; }else{ for (var i = 0; i < oInps.length; i++) { if (!oInps[i].checked) { oInpAll.checked = false; break; }; if (i == oInps.length-1) { oInpAll.checked = true; }; }; } } } /* 功能: 顶部刷新 + 底部加载更多 + 侧边栏 示例: DOM:
正文内容
调用方法: // 1. 实例化 // 2. 设置参数 // 4. 启动 // 实例化 var page = new $cq.loadMobile(); // 顶部下拉刷新 refreshTop page.refreshTop.isOpen = true; page.refreshTop.ele = $cq.id('refreshBar'); page.refreshTop.heightMin = 100; page.refreshTop.heightMax = 2000; page.refreshTop.active.openHalf = function(){ page.refreshTop.ele.innerHTML = '外部:下拉刷新!'; }; page.refreshTop.active.openAll = function(){ page.refreshTop.ele.innerHTML = '外部:松开刷新!'; }; page.refreshTop.active.ajaxAndClose = function(){ page.refreshTop.ele.innerHTML = '外部:AJAX请求,完成后隐藏'; }; // 底部加载更多 loadMoreBottom page.loadMoreBottom.isOpen = true; page.loadMoreBottom.ele = $cq.id('loadMoreBottom'); page.loadMoreBottom.active.load = function(){ page.loadMoreBottom.ele.innerHTML = '提示正在加载更多,并ajax请求' }; // 左侧边栏 page.subBar.left.isOpen = true; page.subBar.left.active.open = function(){ alert('左侧边栏打开'); }; page.subBar.left.active.close = function(){ alert('左侧边栏关闭'); }; // 右侧边栏 page.subBar.right.isOpen = true; page.subBar.right.active.open = function(){ alert('右侧边栏打开'); }; page.subBar.right.active.close = function(){ alert('右侧边栏关闭'); }; // 启动 page.start(); */ function _loadMobile(){ // 顶部刷新栏 this.refreshTop = { isOpen :false, // 开启顶部刷新(true开启 / false关闭) ele :'', // 顶部刷新栏的标签 heightMin :60, // 高度超过60就提示刷新 heightMax :120, // 高度最大120 status :'close', // (不建议重写)默认值close active :{ controller :function(){}, // (不建议重写)总控制器,判断各状态执行的动作 close :function(){}, // (不建议重写)关闭 openHalf :function(){}, // 打开一半,提示 “下拉可刷新” 时执行的动作 openAll :function(){}, // 打开超过一半,提示 “松手刷新” 时执行的动作 ajaxAndClose :function(){} // 松开后,提示正在加载数据,并ajax请求,完成后调用close关闭 } }; // 底部加载更多 this.loadMoreBottom = { isOpen :false, // 开启底部加载更多(true开启 / false关闭) ele :'', // 底部加载栏标签对象 active :{ load:function(){} // 加载更多,执行的动作, } } // 侧边栏 this.subBar = { left:{ isOpen:false, // 开启左侧边栏(true开启 / false关闭) status:'close', // (不建议重写)默认值close active:{ open:function(){}, // 打开的动作 close:function(){} // 关闭的动作 } }, right:{ isOpen:false, // 开启右侧边栏(true开启 / false关闭) status:'close', // (不建议重写)默认值close active:{ open:function(){}, // 打开的动作 close:function(){} // 关闭的动作 } } } // 坐标 this.pos = { // 坐标 x:{ push :null, // 页面滑到顶部(scrollTop==0)时,记录的坐标 start :null, // touchstart 坐标 move :null, // touchmove 坐标 end :null // touchend 坐标 }, y:{ push :null, start :null, move :null, end :null } }; this.start = function(){ init(); bindEvent(); }; var _this = this; var ev = { // 使用的事件(mouse or touch) start :'touchstart', move :'touchmove', end :'touchend' }; var w = { client :0, scrollLeftStart :0, scrollLeftMove :0 } var h = { // 存储高度 client :0, // 客户端屏幕高 body :0, // body的高度 scrollTopStart:0, // touchstart时候的scrollTop scrollTopMove :0 // touchmove时候的scroll }; var init = function(){}; // 绑定事件 var bindEvent = function(){ _addEvent(ev.start, pushStart,document.documentElement); _addEvent(ev.move , pushMove,document.documentElement ); _addEvent(ev.end , pushOver,document.documentElement ); }; /***********************************pushStart - start **********************************/ var pushStart = function(){ var event = $cq.getEvent(); // 获取初始坐标 _this.pos.x.start = event.touches[0].clientX; _this.pos.y.start = event.touches[0].clientY; // 获取高度 & 宽度 h.client = document.documentElement.clientHeight; h.body = document.documentElement.offsetHeight; h.scrollTopStart = $cq.getScrollTop(); w.client = document.documentElement.clientWidth; } /***********************************pushStart - end **********************************/ /***********************************pushMove - start **********************************/ // 页面拉到底部,自动加载更多内容 var pushMove = function(){ var event = $cq.getEvent(); event.preventDefault(); // 获取移动坐标 _this.pos.x.move = event.touches[0].clientX; _this.pos.y.move = event.touches[0].clientY; pushMovePageScroll(); pushMoveScrollTop(event); pushMoveLoadMoreBottom(); }; // 手指滑动时,页面滚动 var pushMovePageScroll = function(){ var tmpScrollTop = parseInt(h.scrollTopStart - (_this.pos.y.move-_this.pos.y.start)*1.5); var tmpScrollLeft = parseInt(h.scrollLeftStart - (_this.pos.x.move-_this.pos.x.start)*1.5); window.scrollTo(0,tmpScrollTop); } // 手指滑动时,顶部刷新蓝 执行的操作 var pushMoveScrollTop = function(event){ // _this.refreshTop.标记为true,并且记录坐标 h.scrollTopMove = $cq.getScrollTop(); if (_this.refreshTop.status == 'close' && h.scrollTopMove == 0) { _this.refreshTop.status = 'open'; _this.pos.x.push = event.touches[0].clientX; _this.pos.y.push = event.touches[0].clientY; }; // status为true,并且开启顶部刷新功能时,执行顶部刷新栏下拉动作 var yx = {}; yx.y = Math.abs(_this.pos.y.start - _this.pos.y.move); yx.x = Math.abs(_this.pos.x.start - _this.pos.x.move); if (_this.refreshTop.status == 'open' && _this.refreshTop.isOpen && yx.y>=yx.x) { _this.refreshTop.active.controller(); }; } // 手指滑动时,底部加载更多 执行的操作 var pushMoveLoadMoreBottom = function(){ console.log('s'+h.scrollTopMove) console.log('b-c'+(h.body-h.client)) if (h.scrollTopMove >= h.body-h.client-10 && _this.loadMoreBottom.isOpen) { _this.loadMoreBottom.active.load(); }; } /***********************************pushMove - end **********************************/ /***********************************pushOver - start *********************************/ var pushOver = function(){ var event = $cq.getEvent(); // 获取结束坐标 _this.pos.x.end = event.changedTouches[0].clientX; _this.pos.y.end = event.changedTouches[0].clientY; pushOverRefreshTop(); pushOverSubBar(); }; // 松手后,判断顶部刷新栏需要执行的动作 var pushOverRefreshTop = function(){ // 关闭状态,当scrollTop为0的时候,设置status if (_this.refreshTop.status == 'open') { _this.refreshTop.status = 'close'; }; // 开启顶部刷新功能时,松手后执行顶部刷新请求 if (_this.refreshTop.isOpen) { var loadBarHeight = parseInt(_getStyle('height',_this.refreshTop.ele)); if (loadBarHeight<_this.refreshTop.heightMin) { _this.refreshTop.active.close(); }else{ _this.refreshTop.active.ajaxAndClose() } }; } // 松手后,判断侧边栏需要执行的动作 var pushOverSubBar = function(){ // 手指滑动超过屏幕 1/3 ,则执行 var levelMove = _this.pos.x.end - _this.pos.x.start; if (levelMove > w.client/3) { if (_this.subBar.left.isOpen && _this.subBar.left.status == 'close') { _this.subBar.left.active.open(); }else if (_this.subBar.right.isOpen) { _this.subBar.right.active.close(); }; } if (-1*levelMove > w.client/3) { if (_this.subBar.right.isOpen && _this.subBar.right.status == 'close') { _this.subBar.right.active.open(); }else if (_this.subBar.left.isOpen) { _this.subBar.left.active.close(); }; }; } /***********************************pushOver - end **********************************/ /****************************顶部刷新栏 在各个状态执行的动作 start*******************/ this.refreshTop.active.controller = function(){ var loadBarHeight = _this.pos.y.move - _this.pos.y.push; _setStyle('height:'+loadBarHeight+'px', _this.refreshTop.ele); if (loadBarHeight<_this.refreshTop.heightMin) { _this.refreshTop.active.openHalf(); }else if (loadBarHeight<_this.refreshTop.heightMax){ _this.refreshTop.active.openAll(); }else{ _setStyle('height:'+_this.refreshTop.heightMax+'px', _this.refreshTop.ele); }; }; // 刷新栏拉开,提示继续下拉可以刷新 // 刷新栏拉开,提示松开就可以刷新 // 刷新栏关闭 // 刷新栏松手后的操作:AJAX请求,完成后关闭刷新栏 this.refreshTop.active.openHalf = function(){ _this.refreshTop.ele.innerHTML = '下拉刷新!'; } this.refreshTop.active.openAll = function(){ _this.refreshTop.ele.innerHTML = '松开刷新!'; } this.refreshTop.active.close = function(){ _setStyle('height:0',_this.refreshTop.ele); } this.refreshTop.active.ajaxAndClose = function(){ _this.refreshTop.ele.innerHTML = 'AJAX请求,完成后隐藏'; /*模拟ajax请求的延时*/ setTimeout(function(){ _this.refreshTop.active.close(); },1000); } /****************************顶部刷新栏 在各个状态执行的动作 end *******************/ /****************************底部加载更多 在各个状态执行的动作 start ***************/ // 执行底部加载更多 this.loadMoreBottom.active.load = function(){ _this.loadMoreBottom.ele.innerHTML = '正在加载更多。。。';/*模拟ajax请求的延时*/ setTimeout(function(){ _this.loadMoreBottom.ele.innerHTML = '上拉加载';},1000);} /****************************底部加载更多 在各个状态执行的动作 end *****************/ /*******************************侧边栏 在各个状态执行的动作 start ******************/ this.subBar.left.active.open = function(){ alert('左侧边栏打开'); } this.subBar.left.active.close = function(){ alert('左侧边栏关闭'); } this.subBar.right.active.open = function(){ alert('右侧边栏打开'); } this.subBar.right.active.close = function(){ alert('右侧边栏关闭'); } /*******************************侧边栏 在各个状态执行的动作 end ********************/ } /* 功能: 轮播图 示例: DOM:
CSS: 调用: new $cq.slider('sliderID').start(); */ function _slider(_sliderId){ var id = null; // 幻灯片ID var ele = { // 各种对象 sliderBox :null, // 幻灯片盒子 ul :null, lis :null, dotP :null, // 点的外壳 dotIs :null // 每个店 } var posX = { // 手指触发的 X 坐标 start :0, move :0, end :0 } var mark = 'mark'; // 当前显示图片的标记 data-mark='mark' var clientWidth = 0; // 页面宽度 var speed = 20; // 滑动速度(1s移动多少像素,值为屏幕宽度的倍数) var intervalTime = 2000; // 滚动隔间时间(单位:ms) var intervalAuto = null; // 自动滚动 //入口 this.start = function(){ init(); // 初始化 bindEvent(); // 绑定事件 autoSlid(0); // 自动播放开始 }; // 初始化 var init = function(){ clientWidth = document.documentElement.clientWidth; speed *= clientWidth; // 1s内移动的距离 id = _sliderId; // 从参数获取id printDot(); // 向页面输出点 getElement(); // 获取元素 setLiWidth(); // 设置li的宽度,img宽度 == li.width ele.lis[0].setAttribute('data-mark','mark');// 将第一个li标记成当前显示项 } // 输出点(数量跟li图片的数量一样) var printDot = function() { var dotP = document.createElement('p'); var dotI = null; var num = $cq.id(id).getElementsByTagName('li').length; for (var i = 0; i < num; i++) { dotI = document.createElement('i'); if (i == 0) { dotI.className = 'selectI'; }; dotP.appendChild(dotI); }; $cq.id(id).appendChild(dotP); } // 获取元素,存入ele var getElement = function(){ ele.sliderBox = $cq.id(id); ele.ul = ele.sliderBox.getElementsByTagName('ul')[0]; ele.lis = ele.ul.getElementsByTagName('li'); ele.dotP = ele.sliderBox.getElementsByTagName('p')[0]; ele.dotIs = ele.dotP.getElementsByTagName('i'); } // 设置li的宽度,img宽度 == li.width var setLiWidth = function() { for (var i = 0; i < ele.lis.length; i++) { _setStyle( 'width:' + clientWidth + 'px',ele.lis[i]); }; } // 获取当前图片的序列号 var getIndex = function() { for (var i = 0; i < ele.lis.length; i++) { if (ele.lis[i].getAttribute('data-mark') == mark) { return i; }; }; } //绑定事件 var bindEvent = function(){ for (var i = 0; i < ele.lis.length; i++) { _addEvent( 'touchstart',function(){ slidActivePos('start');},ele.lis[i]); _addEvent( 'touchmove' ,function(){ slidActivePos('move' );},ele.lis[i]); _addEvent( 'touchend' ,function(){ slidActivePos('end' );},ele.lis[i]); _addEvent('click' ,dotClickActive,ele.dotIs[i]); }; } // 点击圆点的动作 var dotClickActive = function() { var event = $cq.getEvent(); var _this = _getTarget(event); _this.setAttribute('data-mark', mark); for (var i = 0; i < ele.dotIs.length; i++) { if (ele.dotIs[i].getAttribute('data-mark') == mark) { slidActive(i); break; }; }; _this.setAttribute('data-mark', '') } // 手指滑动时触发的事件 var slidActivePos = function(touchName) { event = $cq.getEvent(); switch (touchName) { case 'start': // 设置起始坐标 console.log('event.touches[0]') posX.start = event.touches[0].clientX; break; case 'move': event.preventDefault(); //设置移动时的坐标 posX.move = event.touches[0].clientX; break; case 'end': posX.end = event.changedTouches[0].clientX; // 当前显示的图片序列号 var showNum = getIndex(); // distance 手指划过的距离 var distance = posX.end - posX.start; // 当距离大于屏幕 1/6 时,进行切换,否则回复原状 if (distance > (clientWidth / 6) && showNum > 0) { slidActive(--showNum); } else if ((-1 * distance) > (clientWidth / 6) && showNum < (ele.lis.length - 1)) { slidActive(++showNum); } else { slidActive(showNum); } break; } } // 滑动:显示_showNum指向的图片 var slidActive = function(_showNum){ // 禁止自动播放,等手动播放结束后,再重新开启 clearInterval(intervalAuto); // 滑动的时候,显示影响圆点,并标记最新显示li的mark for (var i = 0; i < ele.lis.length; i++) { if (i == _showNum) { ele.dotIs[_showNum].className = 'selectI'; ele.lis[_showNum].setAttribute('data-mark', mark); } else { ele.dotIs[i].className = ''; ele.lis[i].setAttribute('data-mark', ''); } }; // 滑动图片 var leftNew = -1*clientWidth*_showNum; var leftOld = parseInt(_getStyle('left',ele.ul)); var leftNow = leftOld; if (leftNew < leftOld) { if (speed > 0) { speed *= -1; }; var interval1 = setInterval(function() { leftNow += Math.round(speed / 1000); if (leftNow > leftNew) { _setStyle( 'left:' + leftNow + 'px',ele.ul); } else if (leftNow <= leftNew && leftNow > leftNew + speed / 1000) { _setStyle( 'left:' + leftNew + 'px',ele.ul); } else { clearInterval(interval1); } }, 1) } else if (leftNew > leftOld) { if (speed < 0) { speed *= -1; }; var interval2 = setInterval(function() { leftNow += Math.round(speed / 1000); if (leftNow < leftNew) { _setStyle( 'left:' + leftNow + 'px',ele.ul); } else if (leftNow >= leftNew && leftNow < leftNew + speed / 1000) { _setStyle( 'left:' + leftNew + 'px',ele.ul); } else { clearInterval(interval2); } }, 1) }; // 恢复自动播放 autoSlid(_showNum); } // 自动播放 var autoSlid = function(_autoNum) { var autoNum = _autoNum; intervalAuto = setInterval(function() { if (autoNum >= ele.lis.length - 1) { autoNum = 0; } else { autoNum++; } slidActive(autoNum); }, intervalTime) }; } /* 功能:接口:鸭式变形法 原理:用$cq.interfaceCreate创建带 接口名 和 方法名数组 的接口 在接口实现类中调用$cq.interfaceEnsuerImpletement, ensureImpletement会将接口中的方法,匹配接口实现类中的方法 如果接口中的方法,全部匹配到了,就说明已全部实现 示例: // 创建接口 var inter1 = new $cq.interfaceCreate('inter1',['add1','remove1']) // 实现接口类 function imp(){ this.add1 = function(){ console.log('sdf')} this.remove1 = function(){ console.log('123')} // 检查接口中的方法是否都已经实现 $cq.interfaceEnsureImpletement(this,inter1); } // 实例化调用 var d1 = new imp(); d1.add1(); */ function _interfaceCreate(InterfaceName,InterfaceMethods){ if (arguments.length != 2 ) { throw new Error('创建接口,必须有2个参数(接口名,接口方法array)');}; this.name = InterfaceName; this.methods = []; for (var i = 0; i < InterfaceMethods.length; i++) { if ((typeof InterfaceMethods[i]).toLowerCase() == 'string') { this.methods.push(InterfaceMethods[i]) }else{ throw new Error('创建接口时,第二个参数为接口方法的数组,每个成员必须是string类型'); } }; } function _interfaceEnsuerImpletement(ImpletementInterfaceObj){ if (arguments.length<2) { console.log('ensureInterfaceImpletement()至少传2个及以上的参数:第一个是实现接口的类,其他是需要实现的接口'); }; for (var i = 1; i < arguments.length; i++) { var thisInterface = arguments[i]; if (thisInterface.constructor != _interfaceCreate) { throw new Error('接口必须由CreateInterface实例化创建'); }; for(var j = 0; j < thisInterface.methods.length; j++){ var methodName = thisInterface.methods[j]; if (!ImpletementInterfaceObj[methodName] || typeof ImpletementInterfaceObj[methodName] != 'function') { throw new Error(thisInterface.name+' 内的 '+methodName+' 方法没有实现'); }; } }; } /* 解释:接口:属性检验法 原理:在接口类中,定义interfaceImplement属性 检查接口是否已经实现(未实现return false,否则true) 示例: // 定义接口 // interface PersonDao(){ // function add(){} // function remove(){} // function find(){} // } // 实现接口类 function PersonDao(){ this.interfaceImplement = ['add','remove']; }; PersonDao.prototype.add = function(){} PersonDao.prototype.remove = function(){} // 实例化类 var Tom = new PersonDao(); // 检查PersonDao是否已经实现'add','remove'等接口 var result = $cq.interfaceAttrImplement(Tom,'add','remove',……); if(result){ Tom.add(); }else{ throw new Error('接口未实现'); } */ function _interfaceAttrImplement(Obj){ for (var i = 1; i < arguments.length; i++) { var interfaceName = arguments[i]; var interfaceFound = false; var interfaceList = Obj.interfaceImplement; for (var j = 0; j < interfaceList.length; j++) { if (interfaceName == interfaceList[j]) { interfaceFound = true; }; }; }; if (!interfaceFound) { return false; }else{ return true; } } /* 功能:聚合类(将givingClass中的属性和方法,如果receivingClass没有,则加到receivingClass.prototype中) 示例: function PERSON(){ this.name = 'Tom'; this.speek = 'OK'; } function AUTHOR(){ this.name = 'Jim'; this.book = 'books'; } $cq.mixin(AUTHOR,PERSON); */ function _mixin(receivingClass, givingClass){ var givingObj = null; if (typeof givingClass == 'function') { givingObj = new givingClass(); }else if (typeof givingClass == 'object') { givingObj = givingClass; }else{ console.log('参数givingClass必须是对象{}或函数function') } var status = true; for(gKey in givingObj){ for(rKey in receivingClass.prototype){ if (gKey == rKey) { status = false }; } status?receivingClass.prototype[gKey] = givingObj[gKey]:status = true; } } /* 功能:类的继承 示例: teacher 继承 person function person(name){ this.name = name; } function teacher(name,course){ // 调用父类并传参,将父类this指向teacher的实例, teacher.superClass.constructor.call(this,name); this.course = course; } // 实现继承 $cq.extend(teacher,person); // 实例化 var t1 = new teacher('Tom','English'); console.log(t1.name) === 'Tom'; console.log(t1.course) === 'English' */ function _extend(subClass,superClass){ function F(){} F.prototype = superClass.prototype; subClass.prototype = new F(); subClass.prototype.constructor = subClass; subClass.superClass = superClass.prototype; // 如果父类的原型类是Object,那么把构造函数级别降下来 if (superClass.prototype.constructor == Object.prototype.constructor) { superClass.prototype.constructor = superClass; }; } /* 功能:动画 示例: 1. ele.animate('left',500,15,fn1); 2. function fn1(){ ele.animate('height',200,5,fn1)} 参数: this: 需要改变的对象 _attr:需要改变的属性 _speed:改变的速度(int) _target:目标值(int) _callBack:执行完成后,可以触发的动作(可选) */ function _animate( _attr, _target, _speed, _callBack, _this) { _this = _this || this; _speed = parseInt(_getStyle(_attr,_this)) < _target ? _speed : -_speed; clearInterval(_this.timer); _this.timer = setInterval(function() { var speed = parseInt(_getStyle( _attr,_this)) + _speed; if (speed > _target && _speed > 0 || speed < _target && _speed < 0) { speed = _target; } _this.style[_attr] = speed + 'px'; if (speed == _target) { clearInterval(_this.timer); _callBack && _callBack(); } }, 30); } /* 功能:获取scrollTop / scrollLeft */ function _getScrollTop(){ return document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop; } function _getScrollLeft(){ return document.documentElement.scrollLeft || window.pageXOffset || document.body.scrollLeft; } /* 功能:childNodes获取的对象,删除空文本节点后,数组形式返回 */ function _removeBlankNode(_child){ var child = []; for (var i = 0; i < _child.length; i++) { child.push(_child[i]); }; for (var i = 0; i < child.length; i++) { if (child[i].nodeType == 3 && /^\s+$/gi.test(child[i].textContent)) { child.splice(i,1) }; }; return child; } /* 功能:将getElementsByTagName(Name)获取到的对象,转换成数组返回 */ function _htmlCollectionToArr(_htmlCollection){ var arr = []; for (var i = 0; i < _htmlCollection.length; i++) { arr.push(_htmlCollection[i]); }; return arr; } /* 功能:判断是否是移动设备 返回:是移动设备返回true, 否就返回false */ function _isMobile() { return (navigator.userAgent.match(/Android/i) || navigator.userAgent.indexOf('iPhone') != -1 || navigator.userAgent.indexOf('iPod') != -1 || navigator.userAgent.indexOf('iPad') != -1) ? true : false; } /* 功能:AJAX 示例: 1. var temp = new $cq.AJAX('json'); 如果返回json,则参数里写json 2. temp.get(url, before, after, true); temp.post(url, before, after, true, _params, _paramsType); 备注: before/after为请求前后要执行的函数 实例化时,参数代表返回数据类型:返回字符串则不用传参,返回json,传‘json’ */ function _AJAX(_type) { /* ajax = { type : 返回的数据格式,由实例化AJAX的时候传入, xhr : XMLHttpRequest对象, versions : IE的XMHttpRequest的版本分类数组, after : 请求完成后执行的操作 str : 返回到值 } */ var ajax = {}; ajax.type = _type; // 获取XMLHttpRequest对象 ajax.getXhr = function() { var http; try{ http = new XMLHttpRequest(); // 将获取getXhr方法变成直接返回对象,以后请求就不需要判断 getXhr = function(){ return new XMLHttpRequest(); } }catch(e){ var msxml = ['Microsoft.XMLHTTP', 'MSXML.XMLHTTP', 'Msxml2.XMLHTTP.7.0', 'Msxml2.XMLHTTP.6.0', 'Msxml2.XMLHTTP.5.0', 'Msxml2.XMLHTTP.4.0', 'MSXML.XMLHTTP.3.0', 'MSXML.XMLHTTP']; for (var i = 0; i < msxml.length; i++) { try{ http = new ActiveXObject(msxml[i]); // 将获取getXhr方法变成直接返回对象,以后请求就不需要判断 getXhr = function(){ return new ActiveXObject(msxml[i]); }; break; }catch(e){} }; } ajax.xhr = http; } // get请求 this.get = function(_url, _before, _after, _asyn) { ajax.after = _after; ajax.getXhr(); if (ajax.xhr) { try { _before() } catch (e) {} ajax.xhr.open("GET", _url, _asyn); if (ajax.after) { ajax.xhr.onreadystatechange = ajax.doAfter; }; ajax.xhr.send(); }; } // post请求:自动从form中获取name和value,组成url参数 // _paramsType:如果传入的_params为form的id,就传入'formId';否则不传 this.post = function(_url, _before, _after, _asyn, _params, _paramsType) { ajax.getXhr(); ajax.after = _after; if (ajax.xhr) { try { _before(); } catch (e) {}; ajax.xhr.open("POST", _url, _asyn); ajax.xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); if (ajax.after) { ajax.xhr.onreadystatechange = ajax.doAfter; }; if (_paramsType == 'formId') { ajax.urlParameter = ajax.getUrlParameter(_params); }else{ ajax.urlParameter = _params; } ajax.xhr.send(ajax.urlParameter); }; }/* // post请求:手动传入url参数 this.postUrl = function(_url, _before, _after, _asyn, _urlParameter) { ajax.getXhr(); ajax.after = _after; if (ajax.xhr) { try { _before(); } catch (e) {}; ajax.xhr.open("POST", _url, _asyn); ajax.xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); if (ajax.after) { ajax.xhr.onreadystatechange = ajax.doAfter; }; ajax.xhr.send(_urlParameter); }; }*/ // 请求成功后执行的操作 ajax.doAfter = function() { if (ajax.xhr.readyState == 4 && ajax.xhr.status == 200) { if (ajax.type == 'json') { ajax.str = eval("(" + ajax.xhr.responseText + ")"); } else { ajax.str = ajax.xhr.responseText; } ajax.after(ajax.str); }; } // 获取表单中所有key和val,返回: key1=val1&key2=val2&…… ajax.getUrlParameter = function(_formID) { var urlParameter = ''; var inputs = document.getElementById(_formID).getElementsByTagName('input'); for (var i = 0; i < inputs.length; i++) { if (i == 0) { urlParameter = inputs[i].name + '=' + inputs[i].value; } else { urlParameter += '&' + inputs[i].name + '=' + inputs[i].value; } }; return urlParameter; } } /* 功能:cookie:获取 / 获取全部 / 设置 / 删除 */ function _getCookie(key) { var arrStr = document.cookie.split('; '); for (var i = 0; i < arrStr.length; i++) { var temp = arrStr[i].split('='); if (temp[0] == key) { return unescape(temp[1]); } } } function _getCookieAll() { var cookies = {}; console.log(cookies) var arr = document.cookie.split('; '); if (arr.length <= 0) alert('没有cookie!'); else { for (var i = 0; i < arr.length; i++) { var keyval = arr[i].split('='); var key = keyval[0]; var val = unescape(keyval[1]); cookies[key] = val; } } return cookies; } function _setCookie(key, val, h) { var str = key + '=' + escape(val); if (h > 0) { var date = new Date(); date.setTime(date.getTime() + h * 3600 * 1000); str += ";expires=" + date.toGMTString(); } document.cookie = str; } function _removeCookie(key) { var date = new Date(); date.setTime(-1000); var str = key + '=a; expires=' + date.toGMTString(); document.cookie = str; } /* 功能:取消默认事件 */ function _preventDefault(e) { if (e && e.preventDefault) { e.preventDefault(); } else { window.event.returnValue = false; } } /* 功能:取消冒泡 */ function _cancelBubble(e) { e.stopPropagation ? (e.stopPropagation()) : (e.cancelBubble); } /* 功能:设置行内style */ function _setStyle(attr,_this) { _this = _this || this; // console.log(_this); typeof(window.getComputedStyle) != 'undefined'?_this.setAttribute('style', attr):_this.style.cssText =_attr; } /* 功能:获取样式,不能获取复合样式,如background,只能获取background-color这样的 示例:div.getStyle('background-color'); 备注:获取行内style,使用div.style.cssText */ function _getStyle(attr,_this) { _this = _this || this; var styleInfo = window.getComputedStyle ? window.getComputedStyle(_this, "") : _this.currentStyle; return styleInfo[attr]; } /* 功能:获取浏览器名称和版本 备注:return {all='',name='',version=''} */ function _getBrower() { var browers = {}; browers.all = navigator.userAgent.toLowerCase(); if (browers.all.match(/firefox\/\d+/)) { var browersNameVersion = browers.all.match(/firefox\/\d+/)[0].split('/'); browers.name = browersNameVersion[0]; browers.version = browersNameVersion[1]; } else if (browers.all.match(/msie \d+/)) { var browersNameVersion = browers.all.match(/msie \d+/)[0].split(' '); browers.name = browersNameVersion[0]; browers.version = browersNameVersion[1]; } else if (browers.all.match(/chrome\/\d+/)) { var browersNameVersion = browers.all.match(/chrome\/\d+/)[0].split('/'); browers.name = browersNameVersion[0]; browers.version = browersNameVersion[1]; } else if (browers.all.match(/safari\/\d+/)) { var browersNameVersion = browers.all.match(/safari\/\d+/)[0].split('/'); browers.name = browersNameVersion[0]; browers.version = browersNameVersion[1]; } else { console.log('未识别的浏览器'); } return browers;

}

/*
功能:获取指定对象在数组中的序列号(group中排在第几个)
示例:li.index(liArr);
参数:liArr为数组,li为数组中的一个对象
备注:
*/
function _getIndex(_group, _this){
    _this = _this || this;
    _this.setAttribute('data-indexmark','mark');
    for (var i = 0; i < _group.length; i++) {
        if (_group[i].getAttribute('data-indexmark') == 'mark') {
            _group[i].setAttribute('data-indexmark','');
            return i;
        };
    };
};

/*
功能:获取事件对象
*/
function _getTarget(e) {
    return e.target || e.srcElement;
}

/*
功能:获得event对象
*/
function _getEvent(){
    return window.event || arguments.callee.caller.arguments[0];
}

/*
功能:获取event兼容对象
*/
function _e(e){
    return window.event || e;
}

/*
功能:选择id元素
*/
function _id(idName){
    return document.getElementById(idName);
}

/*
功能:选择元素(id/class/tagName,first/last/eq)
执行:
示例:$cq.ele('#idname .className tagName, .className');
参数:
备注:
*/
function _ele(selector){

/*

    var eles = [];
    var eleBlocks = selector.split(',');
    eleBlocks = delSpace(eleBlocks);
    console.log('eleBlocks:↓')
    console.log(eleBlocks)
    for (var i = 0; i < eleBlocks.length; i++) {
        var eleLine= eleBlocks[i].split(/\s+/);
        console.log('i'+i+'->'+eleLine);
        var one = document;
        for(var j = 0; j'+eleLine[j])
            var keyName;
            switch(eleLine[j].charAt(0)){
                case '#':
                    keyName = getKeyName(eleLine[j]);
                    one = one.getElementById(keyName);
                    break;
                case '.':
                    keyName = getKeyName(eleLine[j]);
                    if (isGetPart(keyName)) {
                        var keyNameArr = keyName.split(':');

                        .cn:eq(3)
                        .cn:first
                        .cn:last


                    }else{


                        // div:eq(2)
                        // div:first
                        // div:last

你可能感兴趣的:(【JS】仿Jquery)