关于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 );
    }

上面方法缺点:由于每次循环都使用 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 );

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

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 );

4、第四种方法

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

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 );

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);
                    }
                };
            };

  • 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 ) {
                    itcast.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 &&
                                              i2 == _this.elements.length - 1 ?
                                                this :
                                                this.cloneNode( true ) );
                            // 判断如果是最后一个就无须克隆
                        });
                    });
                }
            });
时间: 2024-08-05 23:41:08

关于js封装框架类库之DOM操作模块(一)的相关文章

关于js封装框架类库之DOM操作模块(二)

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

关于js封装框架类库之样式操作

在js中,对样式的操作我们并不感到陌生,在很多框架中都是用极少的代码,实现更强大的功能,在这做出一些的总结.存在不足还望指出! 1.封装一个添加css的方法(这篇引用了前面的框架结构) 在 js 中 获得样式, 默认只能获得行内样式, 类样式与外部样式无法获得, 可以使用计算样式来获得第一次的结果window.getComputedStyle  获得style对象 建议第一次用 注意: 如果是 低版本的 IE 浏览器, 需要使用 currentStyle YY.fn.extend({ css:

关于js封装框架类库之属性操作

在对DOM对象操作时,往往都要涉及到其属性的操作,为了提高开发效率,同时兼顾浏览器的性能,在这简单的封装了几个常见的属性.因为是模块化,在这只是引入了部分代码,其他代码在前几篇模块封装中有写.如有不足,万望提出,谢谢! 1.判断是否有属性,以及设置属性的操作 YY.fn.extend({ attr: function (attName,attValue){ //判断传入参数是否有属性值,没有直接返回属性名 if(arguments.length == 1){ return this[0].att

关于js封装框架类库之事件模块

在触发DOM上的某个事件时,会产生一个事件对象event.这个对象中包含着所有与事件有关的信息.包括导致事件的元素,事件的类型以及其他与特定事件相关的信息. 例如: 鼠标操作点击事件时,事件对象中会获得鼠标的按键信息等,会提示按的哪一个键 获得鼠标按键属性button和which 鼠标左中右按键分别对应:在谷歌浏览器中   button:左键 0 右键 2 中键 1  ,which:左键 1 右键 3 中键 2 ie8及以下:左键 1 右键 2 中键 4,which属性不存在 用户在操作键盘时,

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

在上篇介绍了选择器的获取标签.id.类名的方法,现在我们在上篇基础上继续升级 1.问题描述:上篇get('选择器')已经实现,如果get方法里是一个选择器的父元素,父元素是DOM对象,那么如何获取元素 思路:1.首先想到的是标签.id.类名的三个方法  2.假设是body节点,那么方法中的document改成body 3.传入的参数如何判断是否为DOM 注意:在获取id方法中全局也只有一个id,所以其中的doument无须修改 修改如下 // 注释: 对获取DOM对象方法的封装 var getT

关于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方法 这是ht

js的间隔延迟以及dom操作

JavaScript的间隔与延迟 间隔  setInterval(): setInterval("函数名",间隔时间) setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式. setInterval() 方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭.由 setInterval() 返回的 ID 值可用作 clearInterval() 方法的参数. clearInterval(间隔的变量名); 延迟 setTimeout(

JS中的BOM以及DOM操作

screen:对象 console.log(screen.width);//屏幕宽度   console.log(screen.availHeight);//可用高度=屏幕高度-底部任务栏   console.log(screen.height);//屏幕高度   console.log(screen.availWidth);//可用宽度 location对象    *     * 完整的URL路径:    * 协议://主机名(IP地址):端口号/文件路径?传递参数(name1=value1&

JS中的事件以及DOM 操作

[DOM树节点] DOM节点分为三大节点:元素节点,文本节点,属性节点. 文本节点,属性节点为元素节点的两个子节点通过getElment系列方法,可以去到元素节点 [查看节点] 1 document.getElementById("div1")  通过ID获取唯一的节点  多个同名ID只会取到第一个 2 getElmentsName   通过Name取到一个数组,包含1到多个节点   使用方式   通过循环,取到每一个节点  循环次数从0开始,<数组 length [查看和设置属