首页logo
  •  

jonllen

金龙,目前就职于一家软件公司,从事Java和.Net信息安全开发设计。

个人档案

jonllen
心情闪存 | 给他留言
妮称:jonllen
来自:中国. 湖南. 湘潭
简述:金龙,目前就职于一家软件公司,从事Java和.Net信息安全开发设计。
博客日历

摆脱JQuery—之自定义Dom筛选器

分类:JavaScript

之所以说要摆脱jquery,并不是说jquery不好用,本人也是佩服jquery五体投地,在没有用上jquery的时候我还没认识到javascript如此强大的功能,好在jquery的脚本是全部开源的,在它的里面我们能够学到很多的东西。不过我看过它的源码,可能是由于本人的js水平有限还有很多地方看不是很明白,不过在使用的过程可以得知jquery之所以如此强大得意于的它封装的dom对象类,并且几乎提供一个几乎"万能"的筛选器,而封装类又提供很多方便常见的方法操作dom对象,最重要的一点是jquery帮我兼容搞定所有的浏览器,使得我们不需要再考虑为ff、opera或safari做单独的判断,所以jquery倍受程序员的青睐。jquery还能进行很好扩展,提供了很多丰富的插件,也有提供一整套UI解决方案,还算好用啦。不过可能是由于本人比较叛逆的性格,出与没事干找抽,呵呵,就是不想再用jquery,也没有啦,下面我来说一下我为什么不再想用jquery的原因:

  1. jquery脚本文件较庞大,1.2.6版没打包前有98kb,而打包后也占了31kb,但我们通常只用它其中的一个很小部分功能,感觉就有点浪费,所以没有必要把这么大的一个jquery脚本文件引用到页面;
  2. 本身的一些Bug,无论写什么东西都可能会有bug,虽然jquery是开源的,但是一般很少有人能真正看懂它里面的框架而进行修正。bug如放入了jquery脚本自定义的window的resize事件不能正确触发,UI里面的滚动页面后的拖拽bug(好象新版已修复),及和其他脚本库不能兼容等。
  3. 不能满足所有的需求,这点是必然的,jquery只能做到尽量通用。对于那些门户网站我想它一定不会要依赖jquery,而是会积累出来一套适合自己的脚本库,如ajax。我想要ajax在callback回调函数不止带responseText还需要自定义多传一个参数,jquery没有提供那只能自己写。
  4. 有时候直接操作dom对象会比jquery更直接方便,如document.getElementById('test').innerHTML += 'html'而jquery要使用$('#test').html( $('#test').html()+'html' ),有人会说那上面我写的代码还是比jquery的长,但是其实我们在js里面用到document.getElementById并不是很多,最重要的还是一些逻辑判断操作。这里再暴jquery一个小bug:不知它做了什么判断使用$("#test").html(0)后test的innerHTML被设成了''空而不是0,但使用最原始的东西当然是不会有错的。

说了这么多无非就是想不用jquery,那么我们应该使用什么东西来代替jquery里面的一些常见方法呢,还有什么?DIY(Do it yourself)自己来写呗~~

首先,我们需要的是一个类似于jquery的筛选器函数,并且返回的是数组,能像jquery一样批量的操作dom元素,这里我暂时不想用jquery那样自己做个对象来封装dom元素,先直接就用个Array好了,筛选器函数代码如下:

function $$(selector)
        {
            
if ( typeof(selector) != 'string' ) return selector;
            
var selectors = selector.trim().split(' '), list = new Array();
            list.push(document);
            
//debugger;
            for (var i=0; i<selectors.length; i++)
            {
                
var item = selectors[i];
                
if (item.trim()=='' ) continue;
                
//if (item.indexOf('#') > -1 )
                //{
                //    list.length = 1;
                //    var id = item.substring(1,item.search(/\.|\[/));
                //    if (id.trim()!='') list.push(document.getElementById(id));
                //}else
                //{
                
                
//上次列表
                var tmp = list.slice(0), doc = tmp.length > 0 ? tmp[0] : document;
                list.length 
= 0;//重置
                
                
//var tmpList = new Array();
                for(var j=0; j<tmp.length; j++)//循环上次列表
                {
                    
var tagName = item.search(/\.|\[/> -1 ? item.substring(0,item.search(/\.|\[/)) : item;
                    
if (tagName.trim()=='') tagName='*';
                    
                    
var tmpList = doc.getElementsByTagName( tagName );
                    
for(var tl=0; tl<tmpList.length; tl++ ) { list.push(tmpList[tl]); }
                    
                    
var className = item.indexOf('.'> -1 ? item.substring( item.indexOf('.'), item.indexOf('[') ) : '';
                    
var attrlist = item.match(/\[\S+=\S+\]/g);
                    
if (className.trim()!='' || attrlist!=null)
                    {
                        
for(var t=0; t<list.length; t++)
                        {
                            
if(className.trim()!='' && list[t].className!=className.trim()) list.splice(t,1);
                            
if (attrlist!=null && attrlist.length > 0)
                            {
                                
for(var a=0; a<attrlist.length; a++)
                                {
                                    
var attr = attrlist[a].trim().split('='), name = attr[0].substring(1), val = attr[1].substring(0,attr[1].length-1);
                                    
if (list[t].getAttribute && list[t].getAttribute(name) != val) list.splice(t,1);
                                }
                            }
                        }
                        
                    }
                    
//if (tmp.length > 0) list = list.concat( tmp );
                    doc = tmp[tmp.length>=2?j+1:j];
                }
                    
                
//}
                //if (i==selectors.length-1)
                //{
                //    list.shift();return list;
                //}
                //alert(item);
            }
            
//list.shift();
            return list;
        }
        String.prototype.trim
= function() { return this.replace(/(^\s*)|(\s*$)/g, ""); };

以上是实现类似jquery筛选的方法,还有为#id等的情况没有考虑,支持加tagName $$('div'),再加类筛选 $$('div.className'),加属性值$$('div[title=main]'),以空格间隔的dom层次$$('div p li')的筛选,返回为Array数组,那么我们操作筛选后的元素只需要扩展Array的prototype如下所示:

        Array.prototype.css = function (name,val){};
        Array.prototype.drag 
= function (){
            
for(var i=0; i<this.length;i++)
            {
                
function eDrag(target,e)
                {
                    target.style.position 
= 'absolute';
                    
var e = window.event || e;
                    
var _xy = parseInt(target.offsetTop) - e.clientY;
                    
var _xx = parseInt(target.offsetLeft) - e.clientX;
                    document.onmouseup 
= function(){
                        
this.onmousemove = null;
                    }
                    
if(e.preventDefault){
                        e.preventDefault();
                    }
                    document.onmousemove 
= function(e){
                        
var e = window.event || e;
                        target.style.top 
= _xy + e.clientY + "px";
                        target.style.left 
= _xx + e.clientX + "px";
                    }
                }
                
this[i].onmousedown = function (e){ eDrag(this,e);};
            }
        };

上面只对Array的css和drag进行扩展,我这里只是示范下,以后我们还可以从jquery那里偷过来一些方法到这里来进行扩展,我们先来试一下drag拖拽的功能。

$$('div.drag .item').drag();

html元素结构如下:

Item 1
Item 2
Item 3
 

今天就先写到这里,下次续。。。

标签:JavaScript
  • posted@ 2009-07-12 22:52
  • update@ 2009-07-17 13:56:25
  • 阅读(13194)
  • 评论(0)

相关文章

评论
暂无任何评论。
发表评论
*必填
回复通知我
*必填