`
axl234
  • 浏览: 268808 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

用JavaScript实现自己的DOM选择器

 
阅读更多

解释器模式(Interpreter):定义一种语法格式,通过程序解释执行它并完成相应的任务。在前端编程场景中可以应用解释器模式来解释CSS选择符实现DOM元素的选择。

 

开放封闭原则:面向对象中的开放封闭原则是类或模块应该对扩展开放对修改封闭,在这个dom选择器中实现id选择器,元素选择器,类选择器,如果以后需要属性选择器的话定义一个属性选择器实现相应的方法,同时在简单工厂中增加相应的创建属性选择器对象分支即可。

 

匹配原理:浏览器在匹配CSS选择符时是按照从右到左匹配的,所以实现自己的DOM选择器时匹配行为也应该和浏览原生匹配行为一致。

 

代码:

 

(function (ns) {

    /*

        //tagName

        console.log(dom.get("p"));

         

        //#id

        console.log(dom.get("#div"));

         

        //.class

        console.log(dom.get(".span", document.body));

         

        //tag.class

        console.log(dom.get("div.span"));

         

        //#id .class

        console.log(dom.get("#div .span"));

     

        //.class .class

        console.log(dom.get(".ul .li-test"));

    */

     

    var doc = document;

    var simple = /^(?:#|\.)?([\w-_]+)/;

     

    function api(query, context) {

 

        context = context || doc;

         

        //调用原生选择器

        if(!simple.test(query) && context.querySelectorAll){

            return context.querySelectorAll(query);

        }else {

            //调用自定义选择器

            return interpret(query, context);

        }

         

    }

     

    //解释执行dom选择符

    function interpret(query, context){

        var parts = query.replace(/\s+/, " ").split(" ");

        var part = parts.pop();

        var selector = Factory.create(part);

        var ret = selector.find(context);

         

        return (parts[0] && ret[0]) ? filter(parts, ret) : ret;

    }

     

    //ID选择器

    function IDSelector(id) {

        this.id = id.substring(1);

    }

    IDSelector.prototype = {

         

        find: function (context) {

            return document.getElementById(this.id);

        },

         

        match: function(element){

            return element.id == this.id;

        }

     

    };

    IDSelector.test = function (selector) {

         

       var regex = /^#([\w\-_]+)/;   

        

       return regex.test(selector);

        

    };

     

    //元素选择器

    function TagSelector(tagName) {

        this.tagName = tagName.toUpperCase();

    }

    TagSelector.prototype = {

         

        find: function (context) {

            return context.getElementsByTagName(this.tagName);

             

        },

         

        match: function(element){

            return this.tagName == element.tagName.toUpperCase() || this.tagName === "*";

        }

    };

    TagSelector.test = function (selector) {

        var regex = /^([\w\*\-_]+)/;

        return regex.test(selector);

    };

     

    //类选择器

    function ClassSelector(className) {

        var splits = className.split('.');

         

        this.tagName = splits[0] || undefined ;

        this.className = splits[1];

    }

    ClassSelector.prototype = {

         

        find: function (context) {

            var elements;

            var ret = [];

            var tagName = this.tagName;

            var className = this.className;

            var selector = new TagSelector((tagName || "*"));

             

            //支持原生getElementsByClassName

            if (context.getElementsByClassName) {

                elements = context.getElementsByClassName(className);

                if(!tagName){

                    return elements;

                }

                for(var i=0,n=elements.length; i<n; i++){

                    if( selector.match(elements[i]) ){

                        ret.push(elements[i]);

                    } 

                }

 

            } else {

                elements = selector.find(context);

                for(var i=0, n=elements.length; i<n; i++){

                    if( this.match(elements[i]) ) {

                        ret.push(elements[i]);

                    }

                }

          }

           

          return ret;

             

        },

         

        match: function(element){

            var className = this.className;

            var regex = new RegExp("^|\\s" + className + "$|\\s");

            return regex.test(element.className);

        }

     

    };

    ClassSelector.test = function (selector) {

        var regex = /^([\w\-_]+)?\.([\w\-_]+)/;

         

        return regex.test(selector);

    };

     

    //TODO:属性选择器

    function AttributeSelector(attr){

         

        this.find = function(context){

         

        };

         

        this.match = function(element){

         

        };

         

    }

     

    AttributeSelector.test = function (selector){

        var regex = /\[([\w\-_]+)(?:=([\w\-_]+))?\]/;

        return regex.test(selector);    

    };

     

    //根据父级元素过滤

    function filter(parts, nodeList){

        var part = parts.pop();

        var selector = Factory.create(part);

        var ret = [];

        var parent;

         

        for(var i=0, n=nodeList.length; i<n; i++){

            parent = nodeList[i].parentNode;

            while(parent && parent !== doc){    

                if(selector.match(parent)){

                    ret.push(nodeList[i]);

                    break;

                }

                parent = parent.parentNode;

            }

        }

         

        return parts[0] && ret[0] ? filter(parts, ret) : ret;

    }

     

    //根据查询选择符创建相应选择器对象

    var Factory = {

         

        create: function (query) {

             

            if (IDSelector.test(query)) {

                return new IDSelector(query);

            } else if (ClassSelector.test(query)) {

                return new ClassSelector(query);

            } else {

                return new TagSelector(query);

            }

        }

    };

     

    ns.dom || (ns.dom = {}); 

    ns.dom.get = api;

}(this));

分享到:
评论

相关推荐

    JavaScript实现DOM对象选择器

    本文详细介绍了如何使用JavaScript实现对DOM对象的选择器功能。DOM(文档对象模型)是处理HTML和XML文档的编程接口,它为文档提供了一个逻辑树结构,树中每个节点都是文档的一个部分。JavaScript通过DOM接口可以访问...

    javascript实现的日期选择器

    这个压缩包可能包含了一个自定义的JavaScript日期选择器实现。 `THUMBS.DB` 是一个图片预览数据库文件,通常在Windows系统中用于存储文件夹中的缩略图,可能与日期选择器的界面设计有关,包含了图标或示例图像。 `...

    JavaScript_DOM编程艺术第二版(中文)

    理解DOM节点、属性、事件和选择器是创建动态网页的关键,这使得开发者能够动态加载内容、更新UI、实现表单验证等功能。 书中还深入讨论了CSS选择器的使用,这是JavaScript与样式关联时的重要工具。通过掌握CSS选择...

    纯javascript实现的日期选择器

    在日期选择器的实现中,我们将主要利用JavaScript的Date对象以及DOM操作来完成。 1. **Date对象**:JavaScript的Date对象是处理日期和时间的核心,我们可以用它来创建新的日期实例、获取和设置日期的各个部分(如年...

    javascript_DOM操作

    7. **DOM选择器**: 除了 `querySelector()` 和 `querySelectorAll()`,还可以使用 `getElementsByClassName()`, `getElementsByTagName()`, `getElementsByName()` 等方法来选择特定类型的元素。 8. **DOM变更事件*...

    JavaScript实现自己的DOM选择器原理及代码

    解释器模式(Interpreter):定义一种语法格式,...匹配原理:浏览器在匹配CSS选择符时是按照从右到左匹配的,所以实现自己的DOM选择器时匹配行为也应该和浏览原生匹配行为一致。 代码: 代码如下: (function (ns) { /*

    原生的强大DOM选择器querySelector.pdf

    这两个方法的引入,使得开发者可以如同使用CSS选择器一样方便地定位和操作DOM元素,尤其在处理复杂的DOM结构时,效率提升明显。 **querySelector** `querySelector`方法允许你根据传入的CSS选择器,查找文档或指定...

    JavaScriptDOM编程艺术(第2版)PDF版本下载.txt

    《JavaScript DOM编程艺术(第2版)》这本书详细介绍了如何使用JavaScript来操纵DOM,实现网页的动态交互效果。通过深入学习本书中的内容,开发者可以更好地理解和掌握JavaScript与DOM的结合方式,提高Web开发的能力...

    经典之作javascript dom编程艺术源码

    `getElementById`通过ID查找,`getElementsByTagName`按标签名查找,`querySelector`返回匹配CSS选择器的第一个元素,`querySelectorAll`返回所有匹配元素的NodeList。 2. **创建元素**:使用`document....

    随书光盘+PDF JavaScript DOM编程艺术(第2版)-源代码2.5MB PDF114MB .zip

    在书中,作者会详细介绍如何利用JavaScript与DOM进行交互,这包括选取元素(如通过选择器API或XPath),修改元素属性,以及处理事件。还会探讨如何使用CSS样式和JavaScript结合来实现动态布局和视觉效果。此外,书中...

    JavaScript.DOM编程艺术(第2版)附录及源码.rar

    6. **DOM遍历与选择**:学会使用`getElementById`、`getElementsByClassName`、`getElementsByTagName`等方法,以及更高效的`querySelector`和`querySelectorAll`选择器,是高效操作DOM的关键。 7. **DOM操作**:...

    javascriptDOM

    4. **选择器API**:学习使用`querySelector()`和`querySelectorAll()`,它们支持CSS选择器,可以更灵活地选取元素。 5. **元素操作**:改变元素的内容、样式、属性等。例如,`element.innerHTML`用于设置或获取元素...

    原生的强大DOM选择器querySelector介绍.docx

    DOM 选择器 querySelector 是一种原生的 JavaScript 方法,用于快速查找和选择 DOM 元素。它的出现解决了传统 JavaScript 开发中查找 DOM 的问题,使得开发者可以快速地查找到需要的节点。 querySelector 的优点是...

    JavaScriptDOM编程艺术

    通过学习《JavaScript DOM编程艺术》,读者将掌握如何利用JavaScript与DOM进行高效的网页动态编程,实现丰富的用户界面和交互体验。这本书不仅涵盖了DOM的基本概念,还深入讲解了实践中的技巧和最佳实践,对于前端...

    javascript_DOM操作.rar

    JavaScript通过DOM提供的接口,可以查找、遍历、修改甚至创建新的元素,实现网页的动态效果。 1. **选择元素**:JavaScript提供了多种方法来选择页面上的元素,如`getElementById()`、`getElementsByClassName()`、...

    javascript+dom书籍

    在实际开发中,JavaScript 和 DOM 结合使用可以实现各种网页交互功能,如表单验证、动画效果、Ajax异步通信等。例如,你可以使用DOM操作动态加载数据,然后用JavaScript处理响应,更新页面内容,无需刷新页面。 在...

    JS原生的强大DOM选择器querySelector.pdf

    `querySelector` 和 `querySelectorAll` 是JavaScript中用于DOM操作的两个强大方法,它们允许开发者使用CSS选择器的方式来选取DOM元素,极大地提高了代码的可读性和效率。这两个方法在现代浏览器中得到了广泛支持,...

Global site tag (gtag.js) - Google Analytics