这里有新鲜出炉的 jQuery 示例,程序狗速度看过来!
jQuery 是一个兼容多浏览器的 javascript 框架,核心理念是 write less,do more(写得更少, 做得更多)。jQuery 在 2006 年 1 月由美国人 John Resig 在纽约的 barcamp 发布,吸引了来自世界各地的众多 JavaScript 高手加入,由 Dave Methvin 率领团队进行开发。
本篇文章主要对用原生 JavaScript 实现 jQuery 的某些简单功能进行详细全面的讲解,具有很好的参考价值,需要的朋友一起来看下吧
大致介绍
学习了妙味,用原生的 JavaScript 实现 jQuery 中的某些部分功能
定义自己的函数库 lQuery
$() 选择器的实现
jQuery 是面向对象的,所以自己编写的也要是面向对象的,看看基本的结构
先来仿写 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 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);
- };
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持 phperz!
来源: http://www.phperz.com/article/17/0503/329389.html