在前端开发的过程中,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. zookeeper 学习笔记 (C语言版本)

    1.zookeeper简介 zookeeper是Hadoop的子项目,在大型分布式系统中,zookeeper封装好了一些复杂易出错的服务,提供简单易用的接口,给使用者提供高效稳定的服务.这些服务包括配 ...

  2. SQL Server 完成性检查的顺序

    第一步: 默认值 第二步: 违反not null 限制 第三步: 判断check约束 第四步: 对引用表应用foreign key 检查 第五步: 对被引用表做 foreign key 检查 第六步: ...

  3. arcEngine添加标注(上)

    arcEngine添加标注有3个技术点:1,获得图层的属性字段:2,初始化符号显示控件:3,添加标注. 获得图层的属性字段:   //每个图层都是一个表的图形化显示,ILayer跟ITale可以互相转 ...

  4. Delphi中运行时改变panel的位置及大小(WM_SysCommand消息配合参数使用,很奇妙) good

    procedure TForm1.pnl1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Inte ...

  5. WEKA,一个开源java的数据挖掘工具

    开始研究WEKA,一个开源java的数据挖掘工具. HS沉寂这么多天,谁知道偏偏在我申请离职的时候给我安排了个任务,哎,无语. 于是,今天看了一天的Weka. 主要是看了HS提供的三个文章(E文,在g ...

  6. 在cmd中输入ls命令出现“ls不是内部或外部命令解决

    今天在学习sass查看目录遇到cmd输入ls提示不是内部命令 解决方法: 新建一个ls.bat文件 内容为: @echo off dir

  7. linux下Oracle11g RAC搭建(六)

    linux下Oracle11g RAC搭建(六) 五.校验安装前的环境 root身份下完毕解压grid.database安装包 [grid@node1 soft]$ su - Password: [r ...

  8. Android官方终于支持 Navigation Drawer(导航抽屉)模式

    在2013 google IO当天,Android团的更新了Support库,新版本(V13)的Support库中新加入了几个比较重要的功能. 添加 DrawerLayout 控件,支持创建  Nav ...

  9. xcode xib 加载 、注意点

    加载xib2中方式 NSArray *array = [[NSBundle mainBundle] loadNibNamed:@"xib名称" owner:nil options: ...

  10. phoenegap3.5 采坑

    上周5晚上在家看Node.js视频的时候,老大来一条短信让研究下 phoengap打包一个web网站. 遂 陷入了phonegap的深渊中. phoengap很早开始使用 cli模式安装开发环境 ,借 ...