关于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框架的基本实现
<!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操作模块(一)的更多相关文章
- 关于js封装框架类库之DOM操作模块(二)
上一篇基本实现了框架结构,但是与真正能用上的项目框架比较还是存在很多不足,在这又做了些加强与优化 (function ( window, undefined ) { var arr = [], pus ...
- 关于js封装框架类库之样式操作
在js中,对样式的操作我们并不感到陌生,在很多框架中都是用极少的代码,实现更强大的功能,在这做出一些的总结.存在不足还望指出! 1.封装一个添加css的方法(这篇引用了前面的框架结构) 在 js 中 ...
- 关于js封装框架类库之属性操作
在对DOM对象操作时,往往都要涉及到其属性的操作,为了提高开发效率,同时兼顾浏览器的性能,在这简单的封装了几个常见的属性.因为是模块化,在这只是引入了部分代码,其他代码在前几篇模块封装中有写.如有不足 ...
- 关于js封装框架类库之事件模块
在触发DOM上的某个事件时,会产生一个事件对象event.这个对象中包含着所有与事件有关的信息.包括导致事件的元素,事件的类型以及其他与特定事件相关的信息. 例如: 鼠标操作点击事件时,事件对象中会获 ...
- 关于js封装框架类库之选择器引擎(二)
在上篇介绍了选择器的获取标签.id.类名的方法,现在我们在上篇基础上继续升级 1.问题描述:上篇get('选择器')已经实现,如果get方法里是一个选择器的父元素,父元素是DOM对象,那么如何获取元素 ...
- 关于js封装框架类库之选择器引擎(一)
选择器模块之传统做法 var tag = function (tag){ return document.getElementsByTagName(tag); } var id = function ...
- JS/jQuery--iframe框架内外元素的操作(转)
JS/jQuery--iframe框架内外元素的操作 原创 2017年12月07日 14:23:09 标签: js / iframe 28 两个问题: 如何在父页面操作iframe框架内的元素? 如何 ...
- jQuery 源码分析(二十) DOM操作模块 插入元素 详解
jQuery的DOM操作模块封装了DOM模型的insertBefore().appendChild().removeChild().cloneNode().replaceChild()等原生方法.分为 ...
- jQuery 源码解析(二十四) DOM操作模块 包裹元素 详解
本节说一下DOM操作模块里的包裹元素子模块,该模块可将当前匹配的元素替换指定的DOM元素,有如下方法: wrap(html) ;在每个匹配元素的外层添加一层DOM元素 ...
随机推荐
- Python核心编程笔记---- print@2
print 的输出从定向问题 print 可以用’>>‘来重定向输出,下面是例子 f = open('D:/python.txt','w+') print >> f," ...
- [LeetCode][Python]18: 4Sum
# -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 18: 4Sumhttps://oj.leetcode.com/problem ...
- Effective Objective-C 读书笔记
一本不错的书,给出了52条建议来优化程序的性能,对初学者有不错的指导作用,但是对高级阶段的程序员可能帮助不是很大.这里贴出部分笔记: 第2条: 使用#improt导入头文件会把头文件的内容全部暴露到目 ...
- CString 与 std::string 相互转化
MFC中CString 与 std::string 相互转化 CString实际是CStringT, 也就是模板类, 在UNICODE环境下,实际是CStringW, 在多字符集环境下,实际是CStr ...
- FilenameUtils工具类
转载请出自出处:http://eksliang.iteye.com/blog/2217081 一.概述 这是一个Java操作文件的常用库,是Apache对java的IO包的封装,这里面有两个非常核心的 ...
- MySQL学习笔记(5)
子查询Subquery 出现在其他sql语句内的select子句. 子查询的外层查询可以是:SELECT,INSERT,UPDATE,SET或DO. 子查询可以返回标量,一行,一列或子查询. ①使用比 ...
- Memcached基础
1.实例化 MemcachedClient client = new XMemcachedClient(); public XMemcachedClient() public XMemcachedCl ...
- C - 下沙小面的(2)
C – 下沙小面的(2)Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64uSubmit StatusDes ...
- BZOJ 3870: Our happy ending( 状压dp )
dp(i, s)表示考虑了前i个数后, 能取到的数的集合为s时的方案数.对于1~min(L, K)枚举更新, 剩下的直接乘就好了. 复杂度O(T*K*2^N)...好像有点大, 但是可以AC.... ...
- 搭建单节点Hadoop应用环境
虚拟机: VirtualBox 5 Server操作系统: Ubuntu Server 14.04.3 LTS 如果对虚拟机空间和性能不做考虑, 且不习惯用Linux命令, 你也可以使用Ubuntu ...