大致介绍
学习了妙味,用原生的JavaScript实现jQuery中的某些部分功能
定义自己的函数库lQuery
$()选择器的实现
jQuery是面向对象的,所以自己编写的也要是面向对象的,看看基本的结构
// 定义lQuery对象
function lQuery(lArg){
}
function lQ(lArg){
 return new lQuery(lArg);
}
// css()方法
lQuery.prototype.css = function(){};
// html()方法
lQuery.prototype.html = function(){};
先来仿写jQuery中的$(函数)的方法
// 定义lQuery对象
function lQuery(lArg){
 // 用typeof判断参数的类型是 function 、
 switch( typeof lArg){
 case 'function':
  // 如果采用这种写法,给lQ绑定相同的函数,但是只会执行一次
  // window.onload = lArg;
  // break;
 }
}
如果写出这样的函数就会出现问题
lQ(function(){
  alert(1);
 });
 lQ(function(){
  alert(2);
 });
这样就只会弹出'2',但是在jQuery中都会弹出,所以上面的方法不对,我们采用事件绑定的形式来解决这个问题
// 绑定事件函数
function lQbind(obj,eventName,fn){
 // 标准浏览器
 if(obj.addEventListener){
 obj.addEventListener(eventName,fn,false);
 }else{
 // IE浏览器
 obj.attachEvent('on'+eventName,fn);
 }
}
可以使用这样调用
switch( typeof lArg){
 case 'function':
  // 如果采用这种写法,给lQ绑定相同的函数,但是只会执行一次
  // window.onload = lArg;
  // break;
  lQbind(window,'load',lArg);
  break;
 }
仿写jQuery中的$('.div')、$('#div')、$('div')三种方法
这三种方法的区别是第一个字符的不同,所以我们可以根据第一个字符的不同来进行区别对待
先来仿写$('.div')
// '.div' case '.': this.elements = getClass(document,lArg.substring(1)); break;
由于getElementsByClassName()是HTML5里的方法,像IE8以下不兼容所以我们自己写了一个简单的getClass方法
 // 获取class属性
function getClass(obj,name){
 var arr = [];
 var elems = obj.getElementsByTagName('*');
 for(var i=0;i<elems.length;i++){
 if(elems[i].className == name){
  arr.push(elems[i]);
 }
 }
 return arr;
}
仿写$('#div')
case '#': this.elements.push(document.getElementById(lArg.substring(1))); break; // '.div' case '.':
仿写$('div')
default: // getElementsByTagName返回的是一个类数组NodeList,为了防止以后出现麻烦,要把他转为一个 // 数组 this.elements = toArray(document.getElementsByTagName(lArg)); break;
由于getElementsByTagName返回的是一个类数组NodeList,为了防止以后出现麻烦,要把他转为一个数组,自定义了一个toArray方法
// 将一个类数组转为真正的数组
function toArray(lickArr){
 var arr = [];
 for(var i=0;i<lickArr.length;i++){
 arr.push(lickArr[i]);
 }
 return arr;
}
仿写$(对象)的方法
      // window  document
      case 'object':
          this.elements.push(lArg);
          break;
html()的实现
html()方法分为有参和无参
// html()方法
lQuery.prototype.html = function(str){
 if(str){ //设置
 for(var i=0;i<this.elements.length;i++){
  this.elements[i].innerHTML = str;
 }
 }else{
 return this.elements[0].innerHTML;
 }
 return this;
};
on()方法的实现
利用前面实现的绑定函数可以很容易的实现
 lQuery.prototype.on = function(eventName,fn){
     for(var i=0;i<this.elements.length;i++){
         lQbind(this.elements[i],eventName,fn);
     }
 }
click()和mouseover()方法的实现
利用on()方法可以容易的实现
// click()方法
lQuery.prototype.click = function(fn){
 this.on('click',fn);
 return this;
}
// mouseover()方法
lQuery.prototype.mouseover = function(fn){
 this.on('mouseover',fn);
 return this;
}
hide()和show()方法的实现
// hide()方法
lQuery.prototype.hide = function(){
 for(var i=0;i<this.elements.length;i++){
 this.elements[i].style.display = 'none';
 }
 return this;
}
// show()方法
lQuery.prototype.show = function(){
 for(var i=0;i<this.elements.length;i++){
 this.elements[i].style.display = 'block';
 }
 return this;
}
hover()方法的实现
 // hover()方法
 lQuery.prototype.hover = function(fnover,fnout){
 this.on('mouseover',fnover);
 this.on('mouseout',fnout);
 return this;
 }
css()方法的实现
实现$('div').css('width')和$('div').css('width','200px')
lQuery.prototype.css = function(attr,value){
 if(arguments.length == 2){
 for(var i=0;i<this.elements.length;i++){
  this.elements[i].attr = value;
 }
 }
 if(arguments.length == 1){
 return getStyle(this.elements[0],attr);
 }
}
定义了getStyle()方法是为了能找到行内样式以外的样式
// 获取属性
function getStyle(obj,attr){
 if(obj.currentStyle[attr]){
 obj.currentStyle[attr];
 }else{
 obj.getComputedStyle(obj,false)[attr];
 }
}
attr()方法的实现
用了和css()不同的方法
// attr()方法
lquery.prototype.attr = function(attr,value){
 if(arguments.length == 2){ //设置
 for(var i=0;i<this.elements.length;i++){
  this.elements[i].setAttribute(attr,value);
 }
 }
 else if(arguments.length == 1){ //获取
 return this.elements[0].getAttribute(attr);
 }
 return this;
};
eq()方法的实现
实现$('div').eq(1)
由于eq()方法返回的对象要操作许多lQuery的方法,所以返回的对象必须是lQuery对象
 lQuery.prototype.eq = function(num){
  return lQ(this.elements[num]);
 };
index()方法的实现
实现$('div').index() 返回这个元素在同辈元素中的位置
lQuery.prototype.index = function(){
 var elems = this.elements[0].parentNode.children;
 for(var i=0;i<elems.length;i++){
  if( elems[i] == this.elements[0] ){
  return i;
  }
 }
 };
阻止默认事件和阻止事件冒泡
在jQuery中 return false 是阻止默认事件和事件冒泡,所以我们要对lQbind函数进行修改,通过判断绑定的函数的返回值是否为false来判断是否要进行阻止默认事件和阻止事件冒泡
function lQbind(obj,events,fn){
  if(obj.addEventListener){
  obj.addEventListener(events,function(ev){ 
   if( fn() == false ){
   ev.preventDefault();
   ev.cancelBubble = true;
   }
  },false);
  }
  else{
  obj.attachEvent('on'+events,function(){
   if( fn() == false ){
   window.event.cancelBubble = true;
   return false;
   }
  });
  }
 }
find()方法的实现
仿写$('div').find('.box')和$('div').find('#box')方法
这里涉及到通过判断find()参数第一个字符的方法来进行不同的操作和$()方法差不多,在循环时要使用concat()方法来连接数组,最后返回一个lQuery对象
lQuery.prototype.find = function(sel){
  var arr = [];
  if( sel.charAt(0) == '.' ){ 
  for(var i=0;i<this.elements.length;i++){ 
   arr = arr.concat(getClass( this.elements[i] , sel.substring(1) ));
  }
  }
  else{ 
  for(var i=0;i<this.elements.length;i++){ 
   arr = arr.concat(toArray(this.elements[i].getElementsByTagName(sel)));
  }
  }
  return lQ(arr); 
 };
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!
原生js,jQuery
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新动态
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
 - 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
 - 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
 - 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
 - 群星《2024好听新歌42》AI调整音效【WAV分轨】
 - 王思雨-《思念陪着鸿雁飞》WAV
 - 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
 - 李健《无时无刻》[WAV+CUE][590M]
 - 陈奕迅《酝酿》[WAV分轨][502M]
 - 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
 - 群星《吉他王(黑胶CD)》[WAV+CUE]
 - 齐秦《穿乐(穿越)》[WAV+CUE]
 - 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
 - 邝美云《邝美云精装歌集》[DSF][1.6G]
 - 吕方《爱一回伤一回》[WAV+CUE][454M]