JS仿JQuery选择器功能


Posted in Javascript onMarch 08, 2017

JQuery作为应用最广的JS库,其最强大的功能之一就是几乎涵盖所有方法的且代码十分简短的选择器功能,我们也可用自己的代码实现此功能,代码逻辑、使用方法与JQuery一致

function ZQuery(arg){
 this.elements = [];  //存东西
 this.domString = '';  //保存字符串标签
 if(typeof arg=='function'){
 //DOMReady
 DOMReady(arg);
 }else if(typeof arg=='string'||arg instanceof String){
 if(arg.indexOf('<')!=-1){
  this.domString = arg;
 }else{
  //获取元素
  this.elements = getEle(arg);
  this.length = this.elements.length;
 }
 }else{
 //原生对象-》ZQuery对象
 this.elements.push(arg);
 this.length = this.elements.length;
 }
}
ZQuery.prototype.css = function(name,value){
 if(arguments.length==2){
  //设置一个样式
  for(var i=0;i<this.elements.length;i++){
  this.elements[i].style[name] = value;
  }
 }else{
  if(typeof name=='string'){
  //获取样式
  return getStyle(this.elements[0],name);
  }else{
  //批量设置样式
  var json = name;
  for(var name in json){
   for(var i=0;i<this.elements.length;i++){
   this.elements[i].style[name] = json[name];
   }
  }
  }
 }
};
ZQuery.prototype.attr = function(name,value){
 if(arguments.length==2){
  //设置一个属性
  for(var i=0;i<this.elements.length;i++){
  this.elements[i].setAttribute(name,value);
  }
 }else{
  if(typeof name=='string'){
  //获取属性
  return this.elements[0].getAttribute(name);
  }else{
  //批量设置属性
  var json = name;
  for(var name in json){
   for(var i=0;i<this.elements.length;i++){
   this.elements[i].setAttribute(name,json[name]);
   }
  }
  }
 }
};
ZQuery.prototype.addClass = function(sClass){
 var re = new RegExp('\\b'+sClass+'\\b','g');
 for(var i=0;i<this.elements.length;i++){
 if(this.elements[i].className){
  if(this.elements[i].className.search(re)==-1){
  this.elements[i].className += ' '+sClass;
  }
 }else{
  this.elements[i].className = sClass;
 }
 this.elements[i].className = this.elements[i].className.replace(/^\s+|\s+$/g,'').replace(/\s+/g,' ');
 }
 return this;
};
ZQuery.prototype.removeClass = function(sClass){
 var re = new RegExp('\\b'+sClass+'\\b','g');
 for(var i=0;i<this.elements.length;i++){
 if(this.elements[i].className){
  this.elements[i].className = this.elements[i].className.replace(re,'');
  this.elements[i].className = this.elements[i].className.replace(/^\s+|\s+$/g,'').replace(/\s+/g,' ');
  if(this.elements[i].className==''){
  this.elements[i].removeAttribute('class');
  }
 }
 }
 return this;
};
ZQuery.prototype.html = function(value){
 if(value||value==''){
 //设置
 for(var i=0;i<this.elements.length;i++){
  this.elements[i].innerHTML = value;
 } 
 }else{
 return this.elements[0].innerHTML;
 }
};
ZQuery.prototype.val = function(value){
 if(value||value==''){
 //设置
 for(var i=0;i<this.elements.length;i++){
  this.elements[i].value = value;
 } 
 }else{
 return this.elements[0].value;
 }
};
ZQuery.prototype.show = function(){
 for(var i=0;i<this.elements.length;i++){
 this.elements[i].style.display = 'block';
 }
 return this;
};
ZQuery.prototype.hide = function(){
 for(var i=0;i<this.elements.length;i++){
 this.elements[i].style.display = 'none';
 }
 return this;
};
;'click mouseover mouseout mousedown mouseup mousemove mouseenter mouseleave change keydown keyup contextmenu'.replace(/\w+/g,function(str){
 ZQuery.prototype[str] = function(fn){
 for(var i=0;i<this.elements.length;i++){
  addEvent(this.elements[i],str,fn);
 }
 };
});
ZQuery.prototype.get = function(n){
 for(var i=0;i<this.elements.length;i++){
 if(i==n){
  return this.elements[i];
 }
 }
};
ZQuery.prototype.eq = function(n){
 for(var i=0;i<this.elements.length;i++){
 if(i==n){
  return $(this.elements[i]);
 }
 }
};
ZQuery.prototype.index = function(){
 var aSiblings = this.elements[0].parentNode.children;
 for(var i=0;i<aSiblings.length;i++){
 if(aSiblings[i]==this.elements[0]){
  return i;
 }
 }
};
ZQuery.prototype.hover = function(fn1,fn2){
 for(var i=0;i<this.elements.length;i++){
 $(this.elements[i]).mouseenter(fn1);
 $(this.elements[i]).mouseleave(fn2);
 }
};
ZQuery.prototype.toggle = function(){
 var args = arguments;
 var _this = this;
 for(var i=0;i<this.elements.length;i++){
 ;(function(count){
  $(_this.elements[i]).click(function(ev){
  args[count%args.length].call(this,ev);
  count++;
  });
 })(0);
 }
};
ZQuery.prototype.animate = function(json,options){
 for(var i=0;i<this.elements.length;i++){
 move(this.elements[i],json,options);
 }
};
ZQuery.prototype.appendTo = function(arg){
 var aParent = $(arg);
 for(var i=0;i<aParent.length;i++){
 aParent.get(i).insertAdjacentHTML('beforeEnd',this.domString);
 }
 return this;
};
ZQuery.prototype.prependTo = function(arg){
 var aParent = $(arg);
 for(var i=0;i<aParent.length;i++){
 aParent.get(i).insertAdjacentHTML('afterBegin',this.domString);
 }
 return this;
};
ZQuery.prototype.insertAfter = function(arg){
 var aParent = $(arg);
 for(var i=0;i<aParent.length;i++){
 aParent.get(i).insertAdjacentHTML('afterEnd',this.domString);
 }
 return this;
};
ZQuery.prototype.insertBefore = function(arg){
 var aParent = $(arg);
 for(var i=0;i<aParent.length;i++){
 aParent.get(i).insertAdjacentHTML('beforeBegin',this.domString);
 }
 return this;
};
ZQuery.prototype.remove = function(){
 var oParent = this.elements[0].parentNode;
 for(var i=0;i<this.elements.length;i++){
 oParent.removeChild(this.elements[i]);
 }
 return this;
};
function $(arg){
 return new ZQuery(arg);
};
$.ajax = function(json){
 ajax(json);
};
$.jsonp = function(json){
 jsonp(json);
};
$.fn = ZQuery.prototype;
$.fn.extend = function(json){
 for(var name in json){
 ZQuery.prototype[name] = json[name];
 }
};
function json2url(json){
 var arr = [];
 for(var name in json){
 arr.push(name+'='+encodeURIComponent(json[name]));
 }
 return arr.join('&');
}
function ajax(json){
 json = json||{};
 if(!json.url)return;
 json.type = json.type||'get';
 json.timeout = json.timeout||15000;
 json.data = json.data||{};
 json.data.t = Math.random();
 if(window.XMLHttpRequest){
 var oAjax = new XMLHttpRequest();
 }else{
 var oAjax = new ActiveXObject('Microsoft.XMLHTTP');
 }
 switch(json.type.toLowerCase()){
 case 'get':
  oAjax.open('GET',json.url+'?'+json2url(json.data),true);
  oAjax.send();
  break;
 case 'post':
  oAjax.open('POST',json.url,true);
  oAjax.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
  oAjax.send(json2url(json.data));
  break;
 default:
  oAjax.open('GET',json.url+'?'+json2url(json.data),true);
  oAjax.send();
  break;
 }
 json.loading&&json.loading();
 json.timer = setTimeout(function(){
 oAjax.onreadystatechange = null;
 json.error&&json.error('网络超时。');
 },json.timeout);

 oAjax.onreadystatechange = function(){
 if(oAjax.readyState==4){
  clearTimeout(json.timer);
  if(oAjax.status>=200&&oAjax.status<300||oAjax.status==304){
  json.success&&json.success(oAjax.responseText);
  }else{
  json.error&&json.error(oAjax.status);
  }
 }
 };
}
function jsonp(json){
 json = json||{};
 if(!json.url)return;
 json.timeout = json.timeout||15000;
 json.cbName = json.cbName||'cb';
 json.data = json.data||{};
 json.data[json.cbName] = 'show'+Math.random();
 json.data[json.cbName] = json.data[json.cbName].replace('.','');
 json.timer = setTimeout(function(){
 window[json.data[json.cbName]] = function(res){
  oHead.removeChild(oS);
  json.error&&json.error('网络超时!');
 }
 },json.timeout);
 window[json.data[json.cbName]] = function(res){
 clearTimeout(json.timer);
 oHead.removeChild(oS);
 json.success&&json.success(res);
 }
 var oHead = document.getElementsByTagName('head')[0];
 var oS = document.createElement('script');
 oS.src = json.url+'?'+json2url(json.data);
 oHead.appendChild(oS);
}
function getStyle(obj,sName){
 return (obj.currentStyle||getComputedStyle(obj,false))[sName];
}
function addEvent(obj,sEv,fn){
 if(obj.addEventListener){
 obj.addEventListener(sEv,function(ev){
  var oEvent = ev||event;
  if(fn.call(obj,oEvent)==false){
  oEvent.cancelBubble = true;
  oEvent.preventDefault&&oEvent.preventDefault();
  }
 },false);
 }else{
 obj.attachEvent('on'+sEv,function(){
  var oEvent = ev||event;
  if(fn.call(obj,oEvent)==false){
  oEvent.cancelBubble = true;
  return false;
  }
 });
 }
}
function DOMReady(fn){
 if(document.addEventListener){
 addEvent(document,'DOMContentLoaded',function(){
  fn&&fn();
 });
 }else{
 addEvent(document,'onreadystatechange',function(){
  if(document.readyState=='complete'){
  fn&&fn();
  }
 });
 }
}
function getByClass(oParent,sClass){
 if(oParent.getElementsByClassName){
 return oParent.getElementsByClassName(sClass);
 }else{
 var aResult = [];
 var aEle = oParent.getElementsByTagName('*');
 var re = new RegExp('\\b'+sClass+'\\b','g');
 for(var i=0;i<aEle.length;i++){
  if(aEle[i].className.search(re)!=-1){
  aResult.push(aEle[i]);
  }
 }
 return aResult;
 }
}
function getByStr(aParent,str){
 var aChild = [];
 //遍历父级
 for(var i=0;i<aParent.length;i++){
 switch(str.charAt(0)){
  case '#':
  //#id
  aChild.push(document.getElementById(str.substring(1)));
  break;
  case '.':
  //.class
  var aEle = getByClass(aParent[i],str.substring(1));
  for(var j=0;j<aEle.length;j++){
   aChild.push(aEle[j]);
  }
  break;
  default:
  if(/^\w+\.\w+$/.test(str)){
   //筛选
   //li.on
   var arr = str.split('.');
   var re = new RegExp('\\b'+arr[1]+'\\b','g');
   var aEle = aParent[i].getElementsByTagName(arr[0]);
   for(var j=0;j<aEle.length;j++){
   if(aEle[j].className.search(re)!=-1){
    aChild.push(aEle[j]);
   }
   }
  }else if(/^\w+\[\w+\=\w+\]$/.test(str)){
   //属性
   var arr = str.split(/\[|\=|\]/);
   var aEle = aParent[i].getElementsByTagName(arr[0]);
   for(var j=0;j<aEle.length;j++){
   if(aEle[j].getAttribute(arr[1]) == arr[2]){
    aChild.push(aEle[j]);
   }
   }
  }else if(/^\w+\:\w+(\(\d+\))?$/.test(str)){
   var arr = str.split(/\:|\(|\)/);
   var aEle = aParent[i].getElementsByTagName(arr[0]);
   switch(arr[1]){
   case 'first':
    aChild.push(aEle[0]);
    break;
   case 'last':
    aChild.push(aEle[aEle.length-1]);
    break;
   case 'even':
    for(var j=0;j<aEle.length;j+=2){
    aChild.push(aEle[j]);
    }
    break;
   case 'odd':
    for(var j=1;j<aEle.length;j+=2){
    aChild.push(aEle[j]);
    }
    break;
   case 'eq':
    aChild.push(aEle[arr[2]]);
    break;
   case 'lt':
    for(var j=0;j<arr[2];j++){
    aChild.push(aEle[j]);
    }
    break;
   case 'gt':
    for(var j=parseInt(arr[2])+1;j<aEle.length;j++){
    aChild.push(aEle[j]);
    }
    break;
   }
  }else{
   //标签
   var aEle = aParent[i].getElementsByTagName(str);
   for(var j=0;j<aEle.length;j++){
   aChild.push(aEle[j]);
   }
  }
  break;
 }
 }
 return aChild;
}
function getEle(str){
 var arr = str.replace(/^\s+|\s+$/g,'').split(/\s+/);
 var aParent = [document];
 var aChild = [];
 for(var i=0;i<arr.length;i++){
 aChild = getByStr(aParent,arr[i]);
 //这一次获取到的子级,是下一次获取的父级
 aParent = aChild;
 }
 return aChild;
}
function move(obj,json,options){
 clearInterval(obj.timer); 
 options=options || {};
 options.easing=options.easing|| 'ease-out';
 options.duration=options.duration || 800;
 var count=Math.floor(options.duration/30);
 var start={};
 var dis={};
 for(var name in json){
 start[name]=parseFloat(getStyle(obj,name));
 dis[name]=json[name]-start[name];
 }
 var n=0;
 obj.timer=setInterval(function(){
 n++;
 for(var name in json){
  switch(options.easing){
  case 'linear':
   var a=n/count;
   var cur=start[name]+dis[name]*a;
   break;
  case 'ease-in':
   var a=n/count;
   var cur=start[name]+dis[name]*a*a*a;
   break;
  case 'ease-out':
   var a=1-n/count;
   var cur=start[name]+dis[name]*(1-a*a*a);
   break;
  }
  if(name=='opacity'){
  obj.style.opacity=cur;
  obj.style.filter='alpha(opacity:'+cur*100+')'; 
  }else{
  obj.style[name]=cur+'px';
  }
 }
 if(n==count){
  clearInterval(obj.timer);
  options.complete && options.complete(); 
 }
 },30);
}

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
JavaScript通过RegExp实现客户端验证处理程序
May 07 Javascript
基于jquery编写的横向自适应幻灯片切换特效的实例代码
Aug 06 Javascript
javascript实现自动输出文本(打字特效)
Aug 27 Javascript
有趣的bootstrap走动进度条
Dec 01 Javascript
详解Vue.js——60分钟组件快速入门(上篇)
Dec 05 Javascript
AngularJS框架中的双向数据绑定机制详解【减少需要重复的开发代码量】
Jan 19 Javascript
angular十大常见问题
Mar 07 Javascript
[js高手之路]设计模式系列课程-发布者,订阅者重构购物车的实例
Aug 29 Javascript
详解Vue文档中几个易忽视部分的剖析
Mar 24 Javascript
浅谈node.js 命令行工具(cli)
May 10 Javascript
vue路由事件beforeRouteLeave及组件内定时器的清除方法
Sep 29 Javascript
JS页面动态绘图工具SVG,Canvas,VML介简介
Oct 16 Javascript
vue数据双向绑定原理解析(get &amp; set)
Mar 08 #Javascript
footer定位页面底部(代码分享)
Mar 07 #Javascript
vue父子组件的数据传递示例
Mar 07 #Javascript
完美实现js焦点轮播效果(二)(图片可滚动)
Mar 07 #Javascript
完美实现js焦点轮播效果(一)
Mar 07 #Javascript
Vue2.0组件间数据传递示例
Mar 07 #Javascript
js实现网页定位导航功能
Mar 07 #Javascript
You might like
php取得字符串首字母的方法
2015/03/25 PHP
PHP如何读取由JavaScript设置的Cookie
2017/03/22 PHP
JQuery 学习笔记 选择器之四
2009/07/23 Javascript
javascript Keycode对照表
2009/10/24 Javascript
JavaScript中获取未知对象属性的代码
2011/04/27 Javascript
javascript利用控件对windows的操作实现原理与应用
2012/12/23 Javascript
jquery入门—编写一个导航条(可伸缩)
2013/01/07 Javascript
js在输入框屏蔽按键,只能键入数字的示例代码
2014/01/03 Javascript
javaScript中的this示例学习详解及工作原理
2014/01/13 Javascript
详解Bootstrap创建表单的三种格式(一)
2016/01/04 Javascript
ES2015 Symbol 一种绝不重复的值
2016/12/25 Javascript
NodeJs通过async/await处理异步的方法
2017/10/09 NodeJs
深入浅析vue组件间事件传递
2017/12/29 Javascript
对vue里函数的调用顺序介绍
2018/03/17 Javascript
vue 循环加载数据并获取第一条记录的方法
2018/09/26 Javascript
关于RxJS Subject的学习笔记
2018/12/05 Javascript
浅谈JavaScript 代码简洁之道
2019/01/09 Javascript
js单线程的本质 Event Loop解析
2019/10/29 Javascript
Python cookbook(数据结构与算法)通过公共键对字典列表排序算法示例
2018/03/15 Python
简单实现python数独游戏
2018/03/30 Python
Python二叉树的遍历操作示例【前序遍历,中序遍历,后序遍历,层序遍历】
2018/12/24 Python
python接口自动化(十六)--参数关联接口后传(详解)
2019/04/16 Python
Python urlencode和unquote函数使用实例解析
2020/03/31 Python
20行代码教你用python给证件照换底色的方法示例
2021/02/05 Python
canvas需要在标签里直接定义宽高
2014/12/17 HTML / CSS
英国领先的酒类网上商城:TheDrinkShop
2017/03/16 全球购物
美国球迷装备的第一来源:FOCO
2020/07/03 全球购物
担保书格式及范文
2014/04/01 职场文书
2015年元旦活动总结
2014/05/09 职场文书
演讲稿的写法
2014/05/19 职场文书
建设幸福中国演讲稿
2014/09/11 职场文书
营销计划书范文
2015/01/17 职场文书
施工员岗位职责
2015/02/10 职场文书
2015年库房工作总结
2015/04/30 职场文书
解决numpy和torch数据类型转化的问题
2021/05/23 Python
Redis实现订单过期删除的方法步骤
2022/06/05 Redis