jq框架封装学习笔记4-DOM操作模块

jquery - DOM操作

核心框架成员

核心成员

1> selector 用来存储该 itcast 对象的选择器
2> toArray 方法
3> get 方法
4> each 与 map 方法
5> eq 方法

selector 和 toArray

selector

凡是使用选择器获得元素来创建的 jq 对象都有 selector 属性
凡是使用 jq 对象创建 jq 对象都有 该属性
其实就是为了说明该元素是使用 指定的选择器获取到的.

我们只需要在使用选择器创建的对象时来添加即可
在 jq 中还使用 该属性来判断 对象是否为 jq 对象

我们实现对其简化:
1) 提供一个 selector 表示 选择器
2) 提供一个 type 属性, 存储 'jepson'. 用来表示对象是否为 jepson 类型

toArray

将 jq 对象中的每一个元素取出来组成一个数组返回
var res = [];
for ( ... ) {
    res.push( ... )
}
    jepson.fn = jepson.prototype = {
        constructor: jepson,
        length: 0,
        selector: '', // 表示使用了选择器
        type: 'jepson', // 标记对象类型
        init: function (html) {
            // 如果是空对象 或者 空字符串
            if (html == null || html == '') return; // 直接结束
            // 如果是函数
            if (typeof html == 'function') {
                // do something
            }
            // 如果是字符串
            if ( jepson.isString(html) ) {
                // 看是不是标签字符串
                if ( /^</.test( html ) ) {
                    // 是就转换成 dom 对象伪数组 分别 push 到 this 对象中
                    push.apply( this, parseHTML( html ) );
                } else {
                    // 不是就是选择器,选中页面中的 dom 对象伪数组 分别 push 到this对象中
                    push.apply( this, jepson.select( html ) );
                    // 是选择器,就给他加上 selector 属性
                    this.selector = html;
                }
            }
            // 如果是 jepson 对象
            if ( html && html.type === 'jepson' ) {
                // 是 jepson 对象
                // 将传入 的 jepson 对象所有的元素都 添加到 this 中
                push.apply( this, html );
                this.selector = html.selector;
            }
        },
        toArray: function () {
            var res = [];
            for ( var i = 0; i < this.length; i++ ) {
                res.push( this[ i ] );
            }
            return res;
        }
    }

get方法, 就是利用 toArray先转换成dom数组

    jepson.fn = jepson.prototype = {
        constructor: jepson,
        length: 0,
        selector: '', // 表示使用了选择器
        type: 'jepson', // 标记对象类型
        init: function (html) {
            ...
        },
        toArray: function () {
            var res = [];
            for ( var i = 0; i < this.length; i++ ) {
                res.push( this[ i ] );
            }
            return res;
        },
        get: function( index ) {
            if ( index === undefined ) {
                return this.toArray();
            }
            return this[ index ];
        }
    }

eq 方法, $.eq(num)

$.eq(num)

num >= 0 正向取
num < 0  倒着取, 使用 length + num 获得元素 返回 jquery 对象
没找到不传参返回空 jquery 对象
    jepson.fn = jepson.prototype = {
        constructor: jepson,
        length: 0,
        selector: '', // 表示使用了选择器
        type: 'jepson', // 标记对象类型
        init: function (html) {
            // 如果是空对象 或者 空字符串
            ...
            // 如果是字符串
            ...
            // 如果是 jepson 对象
            ...
            // 判断是不是一个 DOM 对象, DOM 对象 有 nodeType 属性
            if ( html.nodeType ) {
                this[ 0 ] = html;
            }
        },
        toArray: function () {      // 注意返回 dom 对象数组
            ...
        },
        get: function( index ) {    // 注意返回 dom 对象
            ...
        },
        eq: function ( num ) {
            var dom;
            // 这里要做判断 num >= 0 正向取  num < 0  倒着取
            if ( num >= 0 ) {
                dom = this.get( num );
            } else {
                dom = this.get( this.length + num );
            }
            // 这里要么是 undefined,要么就是 dom 对象, 调用自己的构造函数来构造
            return this.constructor( dom );
        }
    }

each 和 map 方法

    // 需要一些公共,共有方法,函数对象的方法,通过 extend 添加进来
    jepson.extend( {
        each: function ( arr, func ) {
            var i;
            // 在 ES5 中还引入了 Array.isArray 的方法专门来判断数组
            if ( arr instanceof Array || arr.length >= 0 ) {
                for ( i = 0; i < arr.length; i++ ) {
                    // 方法借调,让 arr[ i ] 成为宿主对象
                    func.call( arr[ i ], i, arr[ i ] );
                }
            } else {
                for ( i in arr ) {
                    func.call( arr[ i ], i, arr[ i ] );
                }
            }
            return arr;
        },
        map: function ( arr, func ) {
            var i, res = [], tmp;
            if ( arr instanceof Array || arr.length >= 0 ) {
                for ( i = 0; i < arr.length; i++ ) {
                    tmp = func( arr[i], i );
                    if ( tmp != null ) {
                        res.push( tmp );
                    }
                }
            } else {
                for ( i in arr ) {
                    tmp = func( arr[ i ], i );
                    if ( tmp != null ) {
                        res.push( tmp );
                    }
                }
            }
            return res;
        }
    });

利用给对象函数扩展的 map 和 each 的静态方法, 我们给实例对象添加原型方法

    jepson.fn = jepson.prototype = {
        constructor: jepson,
        length: 0,
        selector: '', // 表示使用了选择器
        type: 'jepson', // 标记对象类型
        init: ...,
        toArray: ...,
        get: ...,
        eq: ...,
        each: function ( func ) {
            // 将 this 中的每一个 dom 元素遍历一下
            return jepson.each( this, func );
        },
        map: function( func ) {
            return jepson.map( this, func );
        }
   }

使用 slice 对 toArray 进行优化

slice 方法

获得数组的子元素, 且不会改变原数组
arr.slice( startIndex );    // 从 startIndex 取到尾
arr.slice( startIndex, endIndex );
拷贝数据获得数组
arr.slice( 0 )
将伪数组转换成数组
[].slice.call( 伪数组, 0 );
不传参 从 0 开始, [].slice.call( 伪数组 );
    ...,
    toArray: function () {      // 注意返回 dom 对象数组
        // var res = [];
        // for ( var i = 0; i < this.length; i++ ) {
        //     res.push( this[ i ] );
        // }
        // return res;
        return slice.call( this );
    },
    ...

添加 DOM 操作方法

appendTo 和 append

        jepson.fn.extend({
            appendTo: function ( selector ) {
                var iObj = this.constructor( selector );
                // 用构造函数构造出一个新对象,用以存储所有的 克隆体 和 本体,用以链式调用
                var newObj = this.constructor();
                for ( var i = 0; i < this.length; i++ ) {
                    for ( var j = 0; j < iObj.length; j++ ) {
                        // 只要不是最后一个,就克隆,最后一个就用本体
                        var temp = (j == iObj.length - 1) ? this[ i ] : this[ i ].cloneNode( true );
                        [].push.call( newObj, temp );
                        iObj[ j ].appendChild( temp );
                    }
                }
                return newObj;
            },
            append: function ( selector ) {
                J( selector ).appendTo( this );
//                // 给 当前对象 添加元素
//              var iObj = this.constructor( selector );    // 要添加的元素
//                for ( var i = 0; i < this.length; i++ ) {   // 遍历当前对象
//                    for ( var j = 0; j < iObj.length; j++ ) {   // 遍历要添加的元素
//                        // 只要不是最后一个要添加的 对象,就要clone要添加的元素
//                        var temp = (i == this.length - 1) ? iObj[ j ] : iObj[ j ].cloneNode( true );
//                        this[ i ].appendChild( temp );
//                    }
//                }
                return this;
            }
        });

prependTo

jquery 中 的 prepend 方法

    <body>
        <div class="c">
            <div>111</div>
        </div>
        <div class="c">
            <div>222</div>
        </div>
    </body>
    <script src="../../../资料/jquery/jquery-1.12.0/jquery-1.12.0.js"></script>
    <script>
        var $1 = $( '<p>000</p>' );
        var $2 = $1.prependTo( '.c' );
    </script>
    ...,
    prependTo: function( selector ) {
        var iObj = this.constructor( selector );
        var newObj = this.constructor();
        for ( var i = 0; i < this.length; i++ ) {
            for ( var j = 0; j < iObj.length; j++ ) {
                var temp = ( j == iObj.length - 1 ) ? this[ i ] : this[ i ].cloneNode( true );
                [].push.call( newObj, temp );

            }
        }
    },
    ...

    /* 扩展 DOM 静态方法 */
    jepson.extend( {
        prependChild: function ( parent, element ) {
            // parent.insertBefore( 新元素, 旧元素 )
            var first = parent.firstChild;
            parent.insertBefore( element, first );
        }
    });
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值