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 相关文章推荐
OfflineSave离线保存代码再次发布使用说明
May 23 Javascript
jquery 年会抽奖程序
Dec 22 Javascript
JavaScript实现在标题栏上显示当前日期的方法
Mar 19 Javascript
JavaScript返回网页中锚点数目的方法
Apr 03 Javascript
浅谈Jquery为元素绑定事件
Apr 27 Javascript
js制作带有遮罩弹出层实现登录注册表单特效代码分享
Sep 05 Javascript
基于JavaScript实现单选框下拉菜单添加文件效果
Jun 26 Javascript
bootstrap使用validate实现简单校验功能
Dec 02 Javascript
基于jQuery Easyui实现登陆框界面
Jul 10 jQuery
vue+element项目中过滤输入框特殊字符小结
Aug 07 Javascript
JS动态显示倒计时效果
Dec 12 Javascript
在vue中动态修改css其中一个属性值操作
Dec 07 Vue.js
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获取客户端真实IP地址的5种情况分析和实现代码
2014/07/08 PHP
PHP中文乱码解决方案
2015/03/05 PHP
关于 Laravel Redis 多个进程同时取队列问题详解
2017/12/25 PHP
在TP5数据库中四个字段实现无限分类的示例
2019/10/18 PHP
基于JQuery的抓取博客园首页RSS的代码
2011/12/01 Javascript
关于锚点跳转及jQuery下相关操作与插件
2012/10/01 Javascript
JS中FRAME的操作问题实例分析
2014/10/21 Javascript
js点击选择文本的方法
2015/02/09 Javascript
学习JavaScript设计模式(代理模式)
2015/12/03 Javascript
学习jQuey中的return false
2015/12/18 Javascript
一篇文章掌握RequireJS常用知识
2016/01/26 Javascript
bootstrap导航、选项卡实现代码
2016/12/28 Javascript
JS实现的点击表头排序功能示例
2017/03/27 Javascript
详解angular 中的自定义指令之详解API
2017/06/20 Javascript
使用Vue中 v-for循环列表控制按钮隐藏显示功能
2019/04/23 Javascript
vue自定义js图片碎片轮播图切换效果的实现代码
2019/04/28 Javascript
Python使用ntplib库同步校准当地时间的方法
2016/07/02 Python
Python基于回溯法子集树模板解决马踏棋盘问题示例
2017/09/11 Python
python使用itchat库实现微信机器人(好友聊天、群聊天)
2018/01/04 Python
Python实现批量读取图片并存入mongodb数据库的方法示例
2018/04/02 Python
python增加矩阵维度的实例讲解
2018/04/04 Python
python实现requests发送/上传多个文件的示例
2018/06/04 Python
在python中实现对list求和及求积
2018/11/14 Python
python 自动重连wifi windows的方法
2018/12/18 Python
python3射线法判断点是否在多边形内
2019/06/28 Python
通过python实现随机交换礼物程序详解
2019/07/10 Python
PyTorch: 梯度下降及反向传播的实例详解
2019/08/20 Python
python 获取谷歌浏览器保存的密码
2021/01/06 Python
英国电视和家用电器购物网站:rlrdistribution.co.uk
2018/11/20 全球购物
汽车专业毕业生推荐信
2013/11/12 职场文书
学习雷锋精神心得体会范文
2014/03/12 职场文书
毕业生求职自荐书范文
2014/03/27 职场文书
群众路线个人对照检查材料2014
2014/09/26 职场文书
2014年机关后勤工作总结
2014/12/16 职场文书
漂亮妈妈观后感
2015/06/08 职场文书
浅析InnoDB索引结构
2021/04/05 MySQL