在前端开发的过程中,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框架的基本实现

 <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script>
// 构造函数
var YY = function ( selector ) {
return new YY.fn.init( selector );//返回init方法的一个实例对象,一个构造函数的原型属性上的函数init的原型链和YY原型链是不同的
};
//原型继承分别为
//YY->YY.prototype->object.prototype->null
//init->init.prototype->object.prototype->null
// 核心原型
YY.fn = YY.prototype = {
constructor: YY,
selector: null,
init: function ( selector ) {
// 字符串: 选择器, html
if ( typeof selector == 'string' ) {
if ( selector.charAt( 0 ) === '<' ) {
this.elements = parseHTML( selector );
} else {
this.elements = select( selector );
}
}
this.selector = selector;//可以判断出,只要有这个属性的对象,就是YY对象
}
};
YY.fn.init.prototype = YY.prototype; // 可扩展
YY.extend = YY.fn.extend = function ( obj ) {
// 将 obj 的成员加到 this 上
var k;
for ( k in obj ) {
this[ k ] = obj[ k ];
}
}; //选择器方法,暂时只考虑基本选择器
var select = function ( selector ) {
var first = selector.charAt( 0 ), arr = [];
if ( first === '#' ) {
arr.push.call( arr, document.getElementById( selector.slice( 1 ) ) )
} else if ( first === '.' ) {
arr.push.apply( arr, document.getElementsByClassName( selector.slice( 1 ) ) )
} else {
arr.push.apply( arr, document.getElementsByTagName( selector ) );
}
return arr;
}; var parseHTML = function ( html ) {
var div = document.createElement( 'div' ),
arr = [], i;
div.innerHTML = html;
for ( i = 0; i < div.childNodes.length; i++ ) {
arr.push( div.childNodes[ i ] );
}
return arr;
}; // 基本的工具方法
YY.extend({
each: function ( arr, fn ) {
var i, l = arr.length,
isArray = YY.isLikeArray( arr );//先判断是否为数组
if ( isArray ) {
// 数组
for ( i = 0; i < l; i++ ) {
if ( fn.call( arr[ i ], i, arr[ i ] ) === false ) {
break;
}
}
} else {
// 对象
for ( i in arr ) {
if ( fn.call( arr[ i ], i, arr[ i ] ) === false ) {
break;
}
}
}
return arr;
}
}); // 判断类型的方法
YY.extend({
isFunction: function ( obj ) {
return typeof obj === 'function';//判断是否为function
},
isString: function ( obj ) {
return typeof obj === 'string';//判断是否为字符串
},
isLikeArray: function ( obj ) {
return obj && obj.length && obj.length >= 0;//判断是否为数组
},
isYY: function ( obj ) {
return !!obj.selector;//判断是否为YY,给其原型属性加个属性,默认为空
},
isDOM: function ( obj ) {
return !!obj.nodeType;
}
}); // 基本的 DOM 操作,此处假设selector是DOM对象
YY.fn.extend({
appendTo: function ( selector ) {
// 将 this.elements 加入到 selector 中
YY.each( this.elements, function () {
selector.appendChild( this );
} );
}
}); </script> <script type="text/javascript">
onload = function () {
YY( '<div>1</div><div>2</div><div>3</div><div>4</div>' )
.appendTo( document.body );
}
</script>
</head>
<body>
</body>
</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 ) );
// 判断如果是最后一个就无须克隆
});
});
}
});

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

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

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

    上一篇基本实现了框架结构,但是与真正能用上的项目框架比较还是存在很多不足,在这又做了些加强与优化 (function ( window, undefined ) { var arr = [], pus ...

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

    在js中,对样式的操作我们并不感到陌生,在很多框架中都是用极少的代码,实现更强大的功能,在这做出一些的总结.存在不足还望指出! 1.封装一个添加css的方法(这篇引用了前面的框架结构) 在 js 中 ...

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

    在对DOM对象操作时,往往都要涉及到其属性的操作,为了提高开发效率,同时兼顾浏览器的性能,在这简单的封装了几个常见的属性.因为是模块化,在这只是引入了部分代码,其他代码在前几篇模块封装中有写.如有不足 ...

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

    在触发DOM上的某个事件时,会产生一个事件对象event.这个对象中包含着所有与事件有关的信息.包括导致事件的元素,事件的类型以及其他与特定事件相关的信息. 例如: 鼠标操作点击事件时,事件对象中会获 ...

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

    在上篇介绍了选择器的获取标签.id.类名的方法,现在我们在上篇基础上继续升级 1.问题描述:上篇get('选择器')已经实现,如果get方法里是一个选择器的父元素,父元素是DOM对象,那么如何获取元素 ...

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

    选择器模块之传统做法 var tag = function (tag){ return document.getElementsByTagName(tag); } var id = function ...

  7. JS/jQuery--iframe框架内外元素的操作(转)

    JS/jQuery--iframe框架内外元素的操作 原创 2017年12月07日 14:23:09 标签: js / iframe 28 两个问题: 如何在父页面操作iframe框架内的元素? 如何 ...

  8. jQuery 源码分析(二十) DOM操作模块 插入元素 详解

    jQuery的DOM操作模块封装了DOM模型的insertBefore().appendChild().removeChild().cloneNode().replaceChild()等原生方法.分为 ...

  9. jQuery 源码解析(二十四) DOM操作模块 包裹元素 详解

    本节说一下DOM操作模块里的包裹元素子模块,该模块可将当前匹配的元素替换指定的DOM元素,有如下方法: wrap(html)               ;在每个匹配元素的外层添加一层DOM元素   ...

随机推荐

  1. android process bar 几种style

    process bar 圆形style记录 1. style="?android:attr/progressBarStyleSmall" //根据主题变颜色 2. holo 主题下 ...

  2. css Block formatting context BFC

    w3c关于BFC解释: http://www.w3.org/TR/CSS21/visuren.html#block-formatting Mdn描述: A block formatting conte ...

  3. umount.nfs device busy day virsh extend diskSpace, attachDisk

    KVM中linux虚拟机的硬盘添加方法 最近虚拟机中运行的东西比较多,很多.而刚启动的时候虚拟机分配的磁盘比较少,随着日志还有平时的上传文件的积累,磁盘空间报警了.网上查了下资料,自己也做了下实验.总 ...

  4. Android UI学习组件概述

    Android的UI组件繁多,如果学习的时候不能自己总结和分类而是学一个记一个不去思考和学习他们内在的联系那真的是只有做Farmer的命了.为了向注定成为Farmer的命运抗争,在学习Android的 ...

  5. css学习笔记二

    下面来总结一下盒子模型,流式布局,浮动布局,层布局(定位布局). 1.盒子模型 有二种:IE盒子模型 和 标准w3c盒子模型 1)IE的盒子模型的content包含了padding和border 2) ...

  6. 君子性非异也,善假于物也 - Threejs 引入TrackballControls 查看场景

    君子性非异也,善假于物也 - Threejs 引入TrackballControls 查看场景 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循" ...

  7. 2014年辛星解读Javascript之DOM之冒泡和捕获

    上篇博客提到了Javascript事件绑定函数的三个參数.第一个是一个event.第二个是一个function.第三个是一个布尔变量.它用于指定事件传递的顺序,分为冒泡和捕获两种方式,接下来我们将揭开 ...

  8. docker private registry使用

    一.搭建harbor: 步骤:略 二.命令行操作: 登录:docker login docker01 tag image: tag 一个 image,名称一定要标准( registryAddress[ ...

  9. Archlinux 安装配置指导 2015-05-24

    因为用的Linode VPS的系统是Archlinux的,想在本地弄个系统做测试用,这样比较方便.然后发现自己在6年前做的一个Archlinux 安装配置Flash,好怀念的赶脚. 时过进迁,没想到A ...

  10. session.createQuery()不执行和java.lang.reflect.InvocationTargetException

    今天写SSH的工程的时候,执行到一个DAO中的Query query = session.createQuery(hql)的时候,没有成功执行,直接跳到了finally,然后前台报了500和java. ...