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 弹出框定位实现方法
Dec 02 Javascript
web的各种前端打印方法之jquery打印插件PrintArea实现网页打印
Jan 09 Javascript
js格式化时间和js格式化时间戳示例
Feb 10 Javascript
JavaScript实现自动消除按钮功能的方法
Aug 05 Javascript
Bootstrap每天必学之简单入门
Nov 19 Javascript
AngularJS教程之简单应用程序示例
Aug 16 Javascript
js转html实体的方法
Sep 27 Javascript
利用jquery实现实时更新歌词的方法
Jan 06 Javascript
vue实现动态数据绑定
Apr 28 Javascript
Angularjs实现下拉框联动的示例代码
Aug 22 Javascript
JavaScript如何处理移动端拍摄图片旋转问题
Nov 16 Javascript
node.js使用express-fileupload中间件实现文件上传
Jul 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
PHPExcel读取Excel文件的实现代码
2011/12/06 PHP
php使用mb_check_encoding检查字符串在指定的编码里是否有效
2013/11/07 PHP
ThinkPHP中U方法的使用浅析
2014/06/13 PHP
PHP入门教程之字符串处理技巧总结(转换,过滤,解析,查找,截取,替换等)
2016/09/11 PHP
ThinkPHP3.2框架使用addAll()批量插入数据的方法
2017/03/16 PHP
PHP实现按之字形顺序打印二叉树的方法
2018/01/16 PHP
一些有用的JavaScript和jQuery的片段分享
2011/08/23 Javascript
JS 获取滚动条高度示例代码
2013/10/24 Javascript
javascript中HTMLDOM操作详解
2014/12/11 Javascript
JavaScript常用的弹出广告及背投广告实现方法
2015/02/06 Javascript
jQuery横向擦除焦点图特效代码分享
2015/09/06 Javascript
防止重复发送 Ajax 请求
2017/02/15 Javascript
ES6生成器用法实例分析
2017/04/10 Javascript
JS实现数组按升序及降序排列的方法
2017/04/26 Javascript
JavaScript纯色二维码变成彩色二维码
2020/07/23 Javascript
vue 国际化 vue-i18n 双语言 语言包
2018/06/07 Javascript
如何利用 JS 脚本实现网页全自动秒杀抢购功能
2020/10/12 Javascript
Vue使用Proxy代理后仍无法生效的解决
2020/11/13 Javascript
Python Web框架Flask下网站开发入门实例
2015/02/08 Python
python使用datetime模块计算各种时间间隔的方法
2015/03/24 Python
Python实现基本线性数据结构
2016/08/22 Python
Python实现将数据框数据写入mongodb及mysql数据库的方法
2018/04/02 Python
使用python爬取B站千万级数据
2018/06/08 Python
Python读取英文文件并记录每个单词出现次数后降序输出示例
2018/06/28 Python
python随机在一张图像上截取任意大小图片的方法
2019/01/24 Python
Django model update的多种用法介绍
2020/03/28 Python
使用Django搭建web服务器的例子(最最正确的方式)
2019/08/29 Python
Python基于wordcloud及jieba实现中国地图词云图
2020/06/09 Python
墨尔本复古时尚品牌:Dangerfield
2018/12/12 全球购物
七夕情人节促销方案
2014/06/07 职场文书
民政局办理协议离婚(范本)
2014/10/25 职场文书
2015年企业工作总结范文
2015/04/28 职场文书
同意报考证明
2015/06/17 职场文书
小学毕业教师寄语
2019/06/21 职场文书
动画「半妖的夜叉姬」新BD特典图公开
2022/03/22 日漫
利用正则表达式匹配浮点型数据
2022/05/30 Java/Android