zoukankan      html  css  js  c++  java
  • 关于js封装框架类库之DOM操作模块(一)

    在前端开发的过程中,javascript极为重要的一个功能就是对DOM对象的操作,而对其封装就是为了更好地进行DOM操作,提高浏览器的支持效率

    • 现在给出一个案例:页面创建三个div,然后给其添加样式

    1、第一种方法

    //第一种方法
        var i, node;
        for ( i = 0; i < 3; i++ ) {
            node = document.createElement( 'div' );
            node.setAttribute( 'class', 'c' );
            //node.className = 'c';
            document.body.appendChild( node );
        }
    View Code

     上面方法缺点:由于每次循环都使用 document.body.appenChild 因此会导致每次 for 都要刷新页面结构,影响浏览器性能,应该采用一个临时的数据
     存储这些 dom 对象, 在全部创建完成以后再加入

    2、第二种方法

    var i, node, container = document.createElement( 'div' );
            for ( i = 0; i < 3; i++ ) {
                node = document.createElement( 'div' );
                // node.setAttribute( 'class', 'c' );
                node.className = 'c';
                container.appendChild( node );
            }
            document.body.appendChild( container );
    View Code

    这种方法同样能实现,但是改变了页面结构

    3、第三种方法

    //这里的DocumentFragment是文档片段(nodeType 11) 用于缓存的DOM对象,页面结构不会影响
                /*var i, node, 
                container = document.createDocumentFragment();
            for ( i = 0; i < 3; i++ ) {
                node = document.createElement( 'div' );
                node.setAttribute( 'class', 'c' );
                //node.className = 'c';
                container.appendChild( node );
            }
            document.body.appendChild( container );
    View Code

    4、第四种方法

    var i, s = "";
                for ( i = 0; i < 3; i++ ) {
                    s += '<div> ' + ' </div>';
                }
                document.body.innerHTML = s;
    //在这只实现了添加标签
    View Code

    5、在实际框架中创建html中的方法

    //在实际框架中创建html中的方法
               var parseDom = function (html){
               var docfrag = document.createDocumentFragment();
               var div = document.createElement('div');//必须创建一个真正的div
               div.innerHTML = html;
               // 在 DOM 元素中默认有一个特征, 即元素只允许有一个 父节点
            // 如果添加元素到另一个节点中, 该元素会自动的离开原来的父节点
               while(div.firstChild){
                   docfrag.appendChild(div.firstChild);
               }
               return docfrag;
           };
            var dom = parseDom( '<span>hello word</span></br>'
                                +'<span>hello word</span>'    );
            document.body.appendChild( dom );
    View Code

    6、 假如传入的是dom对象,要给其添加一个appenTo方法,现在问题来了,在哪个原型中添加该方法,并且不能影响其他内置对象成员。

    思路:给dom对象提供一个包装对象,在这个返回的包装对象中提供一个自定义appendTo方法

            var parseDom = function (html){
                    var docfrag = document.createDocumentFragment();
                    var div = document.createElement('div');
                    div.innerHTML = html;
                    while(div.firstChild){
                        docfrag.appendChild(div.firstChild);
                    }
                    return {
                        element: docfrag,
                        appendTo: function(dom){
                            dom.appendChild(this.element);
                        }
                    };
                };
    View Code
    • DOM框架的基本实现

      1 <!DOCTYPE html>
      2 <html>
      3     <head>
      4         <meta charset="UTF-8">
      5         <title></title>
      6         <script>
      7             // 构造函数
      8             var YY = function ( selector ) {
      9                 return new YY.fn.init( selector );//返回init方法的一个实例对象,一个构造函数的原型属性上的函数init的原型链和YY原型链是不同的
     10             };
     11             //原型继承分别为
     12             //YY->YY.prototype->object.prototype->null
     13             //init->init.prototype->object.prototype->null
     14             // 核心原型
     15             YY.fn = YY.prototype = {
     16                 constructor: YY,
     17                 selector: null,
     18                 init: function ( selector ) {
     19                     // 字符串: 选择器, html
     20                     if ( typeof selector == 'string' ) {
     21                         if ( selector.charAt( 0 ) === '<' ) {
     22                             this.elements = parseHTML( selector );
     23                         } else {
     24                             this.elements = select( selector );
     25                         }
     26                     }
     27                     this.selector = selector;//可以判断出,只要有这个属性的对象,就是YY对象
     28                 }
     29             };
     30             YY.fn.init.prototype = YY.prototype;
     31             
     32             // 可扩展
     33             YY.extend = YY.fn.extend = function ( obj ) {
     34                 // 将 obj 的成员加到 this 上
     35                 var k;
     36                 for ( k in obj ) {
     37                     this[ k ] = obj[ k ];
     38                 }
     39             };
     40             
     41             //选择器方法,暂时只考虑基本选择器
     42             var select = function ( selector ) {
     43                 var first = selector.charAt( 0 ), arr = [];
     44                 if ( first === '#' ) {
     45                     arr.push.call( arr, document.getElementById( selector.slice( 1 ) ) )
     46                 } else if ( first === '.' ) {
     47                     arr.push.apply( arr, document.getElementsByClassName( selector.slice( 1 ) ) )
     48                 } else {
     49                     arr.push.apply( arr, document.getElementsByTagName( selector ) );
     50                 }
     51                 return arr;
     52             };
     53             
     54             var parseHTML = function ( html ) {
     55                 var div = document.createElement( 'div' ),
     56                     arr = [], i;
     57                 div.innerHTML = html;
     58                 for ( i = 0; i < div.childNodes.length; i++ ) {
     59                     arr.push( div.childNodes[ i ] );
     60                 }
     61                 return arr;
     62             };
     63             
     64             // 基本的工具方法
     65             YY.extend({
     66                 each: function ( arr, fn ) {
     67                     var i, l = arr.length, 
     68                         isArray = YY.isLikeArray( arr );//先判断是否为数组
     69                     if ( isArray ) {
     70                         // 数组
     71                         for ( i = 0; i < l; i++ ) {
     72                             if ( fn.call( arr[ i ], i, arr[ i ] ) === false ) {
     73                                 break;
     74                             }
     75                         }
     76                     } else {
     77                         // 对象
     78                         for ( i in arr ) {
     79                             if ( fn.call( arr[ i ], i, arr[ i ] ) === false ) {
     80                                 break;
     81                             }
     82                         }
     83                     }
     84                     return arr;
     85                 }
     86             });
     87             
     88             // 判断类型的方法
     89             YY.extend({
     90                 isFunction: function ( obj ) {
     91                     return typeof obj === 'function';//判断是否为function
     92                 },
     93                 isString: function ( obj ) {
     94                     return typeof obj === 'string';//判断是否为字符串
     95                 },
     96                 isLikeArray: function ( obj ) {
     97                     return obj && obj.length && obj.length >= 0;//判断是否为数组
     98                 },
     99                 isYY: function ( obj ) {
    100                     return !!obj.selector;//判断是否为YY,给其原型属性加个属性,默认为空
    101                 },
    102                 isDOM: function ( obj ) {
    103                     return !!obj.nodeType;
    104                 }
    105             });
    106             
    107             
    108             // 基本的 DOM 操作,此处假设selector是DOM对象
    109             YY.fn.extend({
    110                 appendTo: function ( selector ) {
    111                     // 将 this.elements 加入到 selector 中
    112                     YY.each( this.elements, function () {
    113                         selector.appendChild( this );
    114                     } );
    115                 }
    116             });
    117             
    118             
    119         </script>
    120         
    121         <script type="text/javascript">
    122             onload = function () {
    123                 YY( '<div>1</div><div>2</div><div>3</div><div>4</div>' )
    124                     .appendTo( document.body );
    125             }
    126         </script>
    127     </head>
    128     <body>
    129     </body>
    130 </html>

    假如selector是id选择器,那么如何实现appendTo方法呢

    //YY( selector )返回结果为对象,YY( selector ).elements是一个数组
                YY.fn.extend({
                    appendTo: function ( selector ) {                    
                        YY.each( this.elements, function () {
                            YY( selector ).elements[ 0 ].appendChild( this );
                        } );
                    }
                });

    假如selector是标签选择器,那么如何实现appendTo方法呢

    YY.fn.extend({
                    appendTo: function ( selector ) {    
                        var _this = this;
                        var objs = YY( selector ).elements;
                        YY.each( objs, function ( i1, v1 ) {
                            var that = this;
                            YY.each( _this.elements, function ( i2, v2 ) {
                                // this 当前元素, 要加到 that 上
                                that.appendChild( i1 == objs.length - 1?
                                                    this :
                                                    this.cloneNode( true ) );
                                // 判断如果是最后一个就无须克隆
                            });
                        });
                    }
                });


     本人文笔有限,才疏学浅,文中若有不正之处,万望告知,不胜感激!

  • 相关阅读:
    高级选择器
    CSS的选择器
    HTML——标签
    HTML
    并发编程——协程
    并发编程——线程(二)
    并发编程——线程
    4.栈
    3.链表
    2.顺序表
  • 原文地址:https://www.cnblogs.com/goweb/p/DOM.html
Copyright © 2011-2022 走看看