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 相关文章推荐
jQuery EasyUI API 中文文档 - ComboGrid 组合表格
Oct 13 Javascript
ie6下png图片背景不透明的解决办法使用js实现
Jan 11 Javascript
jQuery选择器全面总结
Jan 06 Javascript
用js传递value默认值的示例代码
Sep 11 Javascript
jQuery解决input超多的表单提交
Aug 10 Javascript
jQuery EasyUI提交表单验证
Jul 19 Javascript
js改变html的原有内容实现方法
Oct 05 Javascript
基于vue实现swipe轮播组件实例代码
May 24 Javascript
详解React中setState回调函数
Jun 14 Javascript
Element InputNumber 计数器的实现示例
Aug 03 Javascript
vue-cli3项目配置eslint代码规范的完整步骤
Sep 10 Javascript
详解vue3.0 的 Composition API 的一种使用方法
Oct 26 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
Ajax+PHP 边学边练 之二 实例
2009/11/24 PHP
用mysql_fetch_array()获取当前行数据的方法详解
2013/06/05 PHP
php发送get、post请求的6种方法简明总结
2014/07/08 PHP
完美的2个php检测字符串是否是utf-8编码函数分享
2014/07/28 PHP
使用PHP实现阻止用户上传成人照片或者裸照
2014/12/25 PHP
PHP封装的MSSql操作类完整实例
2016/05/26 PHP
点击下载链接 弹出页面实现代码
2009/10/01 Javascript
url 特殊字符 传递参数解决方法
2010/01/01 Javascript
jquery中dom操作和事件的实例学习 下拉框应用
2011/12/01 Javascript
变量声明时命名与变量作为对象属性时命名的区别解析
2013/12/06 Javascript
JS+CSS实现的简单折叠展开多级菜单效果
2015/09/12 Javascript
Vue.js每天必学之构造器与生命周期
2016/09/05 Javascript
从零开始学习Node.js系列教程二:文本提交与显示方法
2017/04/13 Javascript
AngularJS中的promise用法分析
2017/05/19 Javascript
浅谈Angular4中常用管道
2017/09/27 Javascript
通过vue-router懒加载解决首次加载时资源过多导致的速度缓慢问题
2018/04/08 Javascript
WebPack配置vue多页面的技巧
2018/05/15 Javascript
Javascript实现异步编程的过程
2018/06/18 Javascript
JavaScript基于遍历操作实现对象深拷贝功能示例
2019/03/05 Javascript
layui的select联动实现代码
2019/09/28 Javascript
微信小程序获取当前位置和城市名
2019/11/13 Javascript
Vue.js原理分析之nextTick实现详解
2020/09/07 Javascript
Python实现抓取页面上链接的简单爬虫分享
2015/01/21 Python
Centos5.x下升级python到python2.7版本教程
2015/02/14 Python
python获取远程图片大小和尺寸的方法
2015/03/26 Python
Python实现比较两个文件夹中代码变化的方法
2015/07/10 Python
Python使用Beautiful Soup包编写爬虫时的一些关键点
2016/01/20 Python
tensorflow之并行读入数据详解
2020/02/05 Python
利用Python实现Json序列化库的方法步骤
2020/09/09 Python
伦敦高级内衣品牌:Agent Provocateur(大内密探)
2016/08/23 全球购物
Canon佳能美国官方商店:购买数码相机、数码单反相机、镜头和打印机
2016/11/15 全球购物
说一下Linux下有关用户和组管理的命令
2014/08/18 面试题
学校师德承诺书
2014/05/23 职场文书
公司年底活动方案
2014/08/17 职场文书
“九一八事变纪念日”国旗下讲话稿
2014/09/14 职场文书
win10安装配置nginx的过程
2021/03/31 Servers