在前端开发的过程中,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. 一个由proguard与fastJson引起的血案

    更多内容在这里查看 https://ahangchen.gitbooks.io/windy-afternoon/content/ 更新微信sdk导致ComposeData中的内部类ComposeDat ...

  2. HTTP请求大全

    1xx - 信息提示这些状态代码表示临时的响应.客户端在收到常规响应之前,应准备接收一个或多个 1xx 响应.100 - 继续101 - 切换协议 2xx - 成功这类状态代码表明服务器成功地接受了客 ...

  3. delphi高手突破学习笔记之面向对象类和对象的本质

    知识点1:堆和栈 每个应用程序可以获得的内存空间分为两种:堆(heap)和栈(stack). 堆又称为“自由存储区”,其中的内存空间的分配与释放是必须由程序员来控制的.例如,用GetMem函数获取了一 ...

  4. CodeForces Round #179 (295A) - Greg and Array 一个线段树做两次用

    线段树的区间更新与区间求和...一颗这样的线段树用两次... 先扫描1~k...用线段树统计出每个操作执行的次数... 那么每个操作就变成了 op. l  , op.r , op.c= times* ...

  5. WINFORM中几句程序获取整个屏幕的图片及当前窗口的图片快照

    /// <summary> /// 获取整个屏幕的图片        /// </summary>        /// <returns></returns ...

  6. Web定时执行某个方法-网页获取

    实现该功能用到的是System.Timers.Timer 将定时的方法添加到Global.ascx.cs中 public class Global : System.Web.HttpApplicati ...

  7. 【转】SQL Server 2008 新类型介绍之Date和Time

     转自CSDN TJVictor专栏:http://blog.csdn.net/tjvictor/archive/2009/07/13/4344429.aspx   SQL Server 2008除了 ...

  8. insert into table1 (column1,column2) select column1,column2 from table2 where 条件

    sql 语句: insert into table1 (column1,column2) select column1,column2 from table2 where 条件 含义: 将table2 ...

  9. SQL类型转换以及自动在前面补0满足10位工号标示法

    1,自动在前面补0满足10位工号标示法 SELECT rtrim(ltrim(right(cast('00000000'+rtrim(CAST(数值 as int)) as varchar(20)), ...

  10. Hibernate学习之Hibernate流程

    Hibernate的核心组件 在基于MVC设计模式的JAVA WEB应用中,Hibernate可以作为模型层/数据访问层.它通过配置文件(hibernate.properties或hibernate. ...