• 关于js封装框架类库之选择器引擎(一)


    • 选择器模块之传统做法

            var tag = function (tag){
                return document.getElementsByTagName(tag);
            }
            var id = function (id){
                return document.getElementById(id);
            }
            var className = function (className){
                return document.getElementsByClassName(className);
            }    
    • 由浅入深之tag方法

     这是html部分代码

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8" />
            <title></title>
            <style type="text/css">
                div, p {
                     200px; 
                    height:50px; 
                    border:1px dashed red; 
                    margin: 10px 0;
                }
            </style>
        </head>
        <body>
            <div></div>
            <div></div>
            <p></p>
            <p></p>
        </body>
    View Code
    //例如给div盒子添加背景色我们可能会这么做
            var divs = tag('div');
            var each = function (arr){
                for(var i = 0;i< arr.length;i++){
                    arr[i].style.backgroundColor = 'pink';
                }
            }
            each(divs);
            //也可能会这么做
            var list = tag('div');
            var each = function (arr,fn){
                for(var i = 0;i<arr.length;i++){
                    if(fn.call(arr[i],i,arr[i]) === false ){//等于false时,终止循环
                        break;
                    }
                }
            }
            each(list,function(){
                this.style.backgroundColor = 'yellow';
            })
    //上式的fn.call(arr[i],i,arr[i]) === false,下面函数也用到这种调用方式,可以做下比较
            var arr = [ 1, 2, 3, 4, 3, 5];
            var each = function ( arr, fn ) {
                for ( var i = 0; i < arr.length; i++ ) {
                    if ( fn( i, arr[ i ] ) === false ) {
                        break;
                    }
                }
            };
            
            var index = -1;
            each( arr, function ( i, v ) {    
                if ( v === 3 ) {
                    index = i;
                    return false;//若是break 遍历不会终止 直到遍历完
                }
            } );
            console.log( index );//2
    View Code

    /*var tag = function (tag){
       return document.getElementsByTagName(tag);
      }*/
      //以上这种写法的缺点是每次获得元素后又要返回,以至于造成浏览器性能的损耗
      //为了简化开发,可以将获得的数组合并到一个数组中,这也是jq中所用到的

    var getTag = function ( tag, results ) {
                results = results || [];
                results.push.apply( results, document.getElementsByTagName( tag ) );
                return results;
            };
            var list = getTag('div');
                list = getTag('p',list);//如果再获得p标签,可以这么写
            var each = function (arr,fn){
                for(var i = 0;i<arr.length;i++){
                    if(fn.call(arr[i],i,arr[i]) === false ){//等于false时,终止循环
                        break;
                    }
                }
            }
            /*each(list,function(){
                this.style.backgroundColor = 'lightgreen';
            })*/
            each(getTag('p',getTag('div')),function(){
                this.style.backgroundColor = 'lightgreen';
            })
    • 进一步整合以上方法 上面方法也只能获得指定标签元素,需求是要兼顾获取标签、id和类名

    思路:单独写一个函数,如果再函数中想获得标签、id和类名,直接调用其方法即可

    在此用到的html和样式对以下操作的验证

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8" />
            <title></title>
            <style type="text/css">
                div, p {
                     200px; 
                    height:50px; 
                    border:1px dashed red; 
                    margin: 10px 0;
                }
            </style>
        </head>
        <body>
            <div id="id">id</div>
            <div class="class"></div>
            <p></p>
            <p></p>
        </body>
    View Code

    1、分别列出获取标签、id、类名对应的方法

    var getTag = function ( tag, results ) {
                results = results || [];
                results.push.apply( results, document.getElementsByTagName( tag ));
                return results;
            };
            
            var getId = function ( id, results ) {
                results = results || [];
                results.push( document.getElementById( id ) );//此处是单个数据,无须用apply方法
                return results;
            };
            
            var getClass = function ( className, results ) {
                results = results || [];
                results.push.apply( results, document.getElementsByClassName( className ) );
                return results;
            };

    2、书写get方法,判断调用以上哪一种方法

    var get = function ( selector, results ) {
                results = results || [];
                //                     1          2        3       4
                var rquickExpr = /^(?:#([w-]+)|.([w-]+)|([w]+)|(*))$/,//正则表达式
                    m = rquickExpr.exec( selector );//正则匹配
                if ( m ) {//判断是否匹配成功(此处if判断可以省略)
                    if ( m[ 1 ] ) {
                        results = getId( m[ 1 ], results );
                    } else if ( m[ 2 ] ) {
                        results = getClass( m[ 2 ], results );
                    } else if ( m[ 3 ] ) {
                        results = getTag( m[ 3 ], results );
                    } else if ( m[ 4 ] ) {
                        results = getTag( m[ 4 ], results );
                    }
                    
                    //因为标签元素选择器和通配符选择器所调用的方法一样,所以可以进行整合如下
                    /*if ( m[ 1 ] ) {
                        results = getId( m[ 1 ], results );
                    } else if ( m[ 2 ] ) {
                        results = getClass( m[ 2 ], results );
                    } else {
                        results = getTag( m[ 3 ] || "*", results )
                    }*/
                    
                }
                
                return results;//返回results
            };

    上面是用正则匹配字符串的,如果不用正则如何实现

    var get = function(selector, results) {
            results = results || [];
            if (selector === '*') {
                return results = getTag(selector, results);
            } else {
                var firstChar = selector.charAt(0);
                switch (firstChar) {
                    case '.':
                        results = getClass(selector.slice(1), results);
                        break;
                    case '#':
                        results = getId(selector.slice(1), results);
                        break;
                    default:
                        results = getTag(selector, results);
                        break;
                }
                return results;
            }
        }
    View Code

    3、书写each方法遍历所获得的元素数组

    var each = function ( arr, fn ) {
                for ( var i = 0; i < arr.length; i++ ) {
                    if ( fn.call( arr[ i ], i, arr[ i ] ) === false ) {
                        break;
                    }
                }
            };

    4、调用each方法,执行验证相关需求的操作

    each( get( "#id" ), function () {
                    
                    this.style.backgroundColor = 'lightgreen';    
                } );

    最后把以上方法整合在一起,如下

    // 注释: 对基本选择器方法的封装
    var getTag = function ( tag, results ) {
        results = results || [];
        results.push.apply( results, document.getElementsByTagName( tag ) );
        return results;
    };
    
    var getId = function ( id, results ) {
        results = results || [];
        results.push( document.getElementById( id ) );
        return results;
    };
    
    var getClass = function ( className, results ) {
        results = results || [];
        
        if ( document.getElementsByClassName ) {
            results.push.apply( results, document.getElementsByClassName( className ) );
        } else {
            each( getTag( '*' ), function ( i, v ) {
                if ( ( ' ' + v.className + ' ' )
                            .indexOf( ' ' + className + ' ' ) != -1 ) {
                    results.push( v );
                }
            } );
        }
        return results;
    };
    
    
    // 对each方法循环的封装
    var each = function ( arr, fn ) {
        for ( var i = 0; i < arr.length; i++ ) {
            if ( fn.call( arr[ i ], i, arr[ i ] ) === false ) {
                break;
            }
        }
    };
            
    
    // 通用的get方法
    var get = function ( selector, results ) {
        results = results || [];
        var rquickExpr = /^(?:#([w-]+)|.([w-]+)|([w]+)|(*))$/,
            m = rquickExpr.exec( selector );
        
        if ( m ) {
            
            if ( m[ 1 ] ) {
                results = getId( m[ 1 ], results );
            } else if ( m[ 2 ] ) {
                results = getClass( m[ 2 ], results );
            } else if ( m[ 3 ] ) {
                results = getTag( m[ 3 ], results );
            } else if ( m[ 4 ] ) {
                results = getTag( m[ 4 ], results );
            }
            
        }
    View Code

     


    以上便是自己的一些学习笔记,鄙人不才,些许浅显,希望大家批评指正

     

  • 相关阅读:
    H264源码分析(四)
    矩阵在编程中的一个小应用
    android listview 三种适配器设置
    Android SoundPool 的使用以及原理分析
    poj 2728 Desert King(最优比例生成树)
    MySQL 查询结果以百分比显示
    Android Application
    飘逸的python
    CSS教程:div垂直居中的N种方法[转]
    HQL: Hibernate查询语言
  • 原文地址:https://www.cnblogs.com/goweb/p/5373156.html
Copyright © 2020-2023  润新知