首页 > 技术文章 > 关于js封装框架类库之DOM操作模块(二)

goweb 2016-04-15 00:21 原文

上一篇基本实现了框架结构,但是与真正能用上的项目框架比较还是存在很多不足,在这又做了些加强与优化

  1 (function ( window, undefined ) {
  2     
  3     
  4 var arr = [],
  5     push = arr.push,
  6     slice = arr.slice,
  7     concat = arr.concat;
  8     
  9 // 构造函数
 10 var YY = function YY ( selector ) {
 11     return new YY.fn.init( selector );
 12 };
 13 // 核心原型
 14 YY.fn = YY.prototype = {
 15     constructor: YY,//让原型结构保持不变
 16     selector: null,//给其添加一个属性
 17     length: 0,//原型中提供的属性,原型中不改值得情况下是共享的,修改后自己再次创建一个
 18     // init 的参数可以有以下几种情况
 19     // 1> null, "", undefined
 20     // 2> fn
 21     // 3> string  (已经实现)
 22     // 4> DOM 数组
 23     // 5> DOM 对象
 24     // 6> YY 对象
 25     init: function ( selector ) {
 26         
 27         if ( !selector ) return this;
 28         
 29         // 兼容字符串: 选择器, html
 30         if ( YY.isString( selector ) ) {
 31             if ( selector.charAt( 0 ) === '<' ) {
 32                 // this.elements = parseHTML( selector );//在对象中直接绑定个属性,来储存数据,方法与其并列,方法与数据分离,维护简单,管理简单,但是在基于它的开发显得繁琐,简化elements:将数据直接储存在this中,即将YY当作伪数组
 33                 YY.push.apply( this, parseHTML( selector ) );
 34             } else {
 35                 // this.elements = select( selector );
 36                 YY.push.apply( this, select( selector ) );
 37                 this.selector = selector;//放在其他地方创建的对象没有此属性,那么可以去原型判断
 38             }
 39             //this.length = 0;//当没有搜索到元素时,无须给其添加length,直接共享原型中的属性,原型中添加length属性比较优,两者没有实质的差别
 40             return this;
 41         }
 42         
 43         // 兼容DOM 对象
 44         if ( YY.isDOM( selector ) ) {
 45             this[ 0 ] = selector;//当前对象的一个元素
 46             this.length = 1;
 47             return this;
 48         }
 49         
 50         // 兼容YY 对象
 51         if ( YY.isYY( selector ) ) {
 52             return selector;
 53         }
 54         
 55         // 兼容DOM 数组(最后判断)
 56         if ( YY.isLikeArray( selector ) ) {
 57             YY.push.apply( this, selector );//每个元素放在当前对象中
 58             
 59             return this;
 60         }
 61     },
 //each 方法
62 each: function (callback){ 63 YY.each(this,callback);//当前每个元素(dom对象)都被回调函数作用 64 return this; 65 } 66 67 }; 68 YY.fn.init.prototype = YY.prototype; 69 70 // 可扩展 71 YY.extend = YY.fn.extend = function ( obj ) { 72 // 将 obj 的成员加到 this 上 73 var k; 74 for ( k in obj ) { 75 this[ k ] = obj[ k ]; 76 } 77 }; 78 79 var select = function ( selector ) { 80 var first = selector.charAt( 0 ), arr = [],node; 81 if ( first === '#' ) {//如果没有搜索到元素,空也加进了数组,所以要对其进行判断 82 //arr.push.call( arr, document.getElementById( selector.slice( 1 ) ) ) 83 node = document.getElementById( selector.slice( 1 ) ); 84 if ( node ) { 85 arr.push.call( arr, node ); // [ null ] 86 } else { 87 return null; 88 } 89 } else if ( first === '.' ) { 90 arr.push.apply( arr, document.getElementsByClassName( selector.slice( 1 ) ) ) 91 } else { 92 arr.push.apply( arr, document.getElementsByTagName( selector ) ); 93 } 94 return arr; 95 }; 96 97 var parseHTML = function ( html ) { 98 var div = document.createElement( 'div' ), 99 arr = [], i; 100 div.innerHTML = html; 101 for ( i = 0; i < div.childNodes.length; i++ ) { 102 arr.push( div.childNodes[ i ] ); 103 } 104 return arr; 105 }; 106 107 // 基本的工具方法 108 YY.extend({ 109 each: function ( arr, fn ) { 110 var i, l = arr.length, 111 isArray = YY.isLikeArray( arr ); 112 if ( isArray ) { 113 // 数组 114 for ( i = 0; i < l; i++ ) { 115 if ( fn.call( arr[ i ], i, arr[ i ] ) === false ) { 116 break; 117 } 118 } 119 } else { 120 // 对象 121 for ( i in arr ) { 122 if ( fn.call( arr[ i ], i, arr[ i ] ) === false ) { 123 break; 124 } 125 } 126 } 127 return arr; 128 }, 129 push: push 130 }); 131 YY.extend({ 132 firstChild: function (dom){ 133 var node,i,l = dom.childNodes.length; 134 for(i = 0;i < 1;i++){ 135 node = dom.childNodes[i]; 136 if(node.nodeType === 1){ 137 return node; 138 } 139 } 140 } 141 }); 142 143 144 // 判断类型的方法 145 YY.extend({ 146 isFunction: function ( obj ) { 147 return typeof obj === 'function'; 148 }, 149 isString: function ( obj ) { 150 return typeof obj === 'string'; 151 }, 152 isLikeArray: function ( obj ) { 153 return obj && obj.length && obj.length >= 0; 154 }, 155 isYY: function ( obj ) { 156 return 'selector' in obj;//判断对象原型中有无此属性来判断是否为YY对象 157 // 'selector' in obj 158 // obj.hasOwnProperty( 'selector' ) 159 // return obj.constructor.name === 'YY'; 160 }, 161 isDOM: function ( obj ) { 162 return !!obj.nodeType; 163 } 164 }); 165 166 167 // 基本的 DOM 操作 168 YY.fn.extend({ 169 appendTo: function ( selector ) { 170 var objs = YY( selector ), 171 i, j, 172 len1 = objs.length, 173 len2 = this.length, 174 arr = [],node; 175 // 将 this 加到 objs 中 176 for ( i = 0; i < len1; i++ ) { 177 for ( j = 0; j < len2; j++ ) { 178 node = i === len1 - 1 ? 179 this[ j ] : 180 this[ j ].cloneNode( true ); 181 arr.push(node); 182 objs[ i ].appendChild( ); 183 } 184 } 185 return YY(arr);//注意返回的对象 186 }, 187 188 append: function (selector){ 189 YY(selector).appendTo(this); 190 return this; 191 }, 192 prependTo: function(selector){ 193 //insertBefore(新元素,参考元素) 194 195 var objs = YY(selector), 196 i,j, 197 len1 = this.length; 198 len2 = objs.lenght; 199 for(i = 0;i < len2;i++){ 200 for(j = 0;j < len1;j++){ 201 objs[i].insertBefore(i ===len2 - 1? 202 this[j]: 203 this[j].cloneNode(true), 204 YY.firstChild); 205 } 206 } 207 return this; 208 }, 209 remove: function(){} 210 }); 211 212 213 214 215 // 对外公开 216 window.I = window.YY = YY; 217 218 })( window );

对以上函数封装为dom.js文件

1、验证appendTo方法代码

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            #login {
                width: 540px;
                height: 340px;
                background-color: gray;
                margin: 80px auto;
                padding: 30px;
            }
        </style>
        <script src="dom.js"></script>
        <script>
        
            onload = function () {
                I( '#loginBtn' )[ 0 ].onclick = function ( e ) {
                    if ( I( '#login' ).length > 0 ) return;
                    
                    // alert( e );
                    // 弹出一个登录窗口
                    var ilogin = I( '<div id="login"></div>' );
                    ilogin.appendTo( 'body' );    
                    // 设计内部的结构
                    I( '<input type="text" id="uid"/><br />' +
                       '<input type="password" id="pwd"/><br />' +
                       '<input type="button" value="登 录" id="btn"/><br />' +
                       '<input type="button" value="取消" id="cancel"/>'
                    ).appendTo( ilogin );
                    
                    
                    I('#cancel')[ 0 ].onclick = function () {
                        var node = I( '#login' )[ 0 ];
                        node.parentNode.removeChild( node );
                    };
                };
            };
        </script>
    </head>
    <body>
        <input type="button" value="登录" id="loginBtn" />
    </body>
</html>
View Code

 

2、验证append方法代码

 

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            #login {
                width: 540px;
                height: 340px;
                background-color: gray;
                margin: 80px auto;
                padding: 30px;
            }
        
        </style>
        <script src="dom.js"></script>
        <script>
            onload = function () {
                I( '#loginBtn' )[ 0 ].onclick = function ( e ) {
                    if ( I( '#login' ).length > 0 ) return;
                    
                    // alert( e );
                    // 弹出一个登录窗口
                    var ilogin = I( '<div id="login"></div>' );
                    
                    I( 'body' ).append( ilogin );
                    // 设计内部的结构
                    ilogin.append( '<input type="text" id="uid"/><br />' +
                       '<input type="password" id="pwd"/><br />' +
                       '<input type="button" value="登 录" id="btn"/><br />' +
                       '<input type="button" value="取消" id="cancel"/>'
                    );
                        
                    I('#cancel')[ 0 ].onclick = function () {
                        var node = I( '#login' )[ 0 ];
                        node.parentNode.removeChild( node );
                    };
                };
            };
        </script>
    </head>
    <body>
        <input type="button" value="登录" id="loginBtn" />
    </body>
</html>
View Code

 

3、验证prependTo方法代码

 

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            #login {
                width: 540px;
                height: 340px;
                background-color: gray;
                margin: 80px auto;
                padding: 30px;
            }
        </style>
        <script src="dom.js"></script>
        <script>
            onload = function () {
                I( '<p>YY</p>' ).prependTo( 'div' );
            };
        </script>
    </head>
    <body>
        <div>
            <p>hellow world</p>
            <p>hellow YY</p>
        </div>
        <div>
            <p>hellow world</p>
            <p>hellow YY</p>
        </div>
    </body>
</html>
View Code


方法待续,感谢您的查阅

 

推荐阅读