关于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元素 ...
随机推荐
- MVC+JSON 无限滚动翻页
public partial class News { public int ID{ get; set; } public int Title{ get; set; } } ) { Response. ...
- MVC自学第一课
了解传统的ASP.NET WebForm ASP.NET 在02年问世,给Web开发领域带来了巨大转变.下图描述了当时微软的技术堆栈. ASP.NET WebForm 技术堆栈 (注:此图的含义为,W ...
- hdu 1210_(逻辑训练)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1210 #include<stdio.h> int main() { int n,t,sum ...
- [Ext JS 4] Grid 实战之分页功能
前言 分页功能的实现有两种途径: 一种是服务端分页方式, 也就是web客户端传递页码参数给服务端,服务端根据页面参数返回指定条数的数据.也就是要多少取多少.这种方式比较适合Grid 的数据量很大,需 ...
- NSJSONSerialization(category)的一个扩展类
.h文件 // // NSJSONSerialization+Manage.h // SVPullToRefreshDemo // // Created by Fuer on 14-7-4. // C ...
- SAN实现
Linux 上主要有三个 iSCSI Target(基于internet scsi协议的target) 实现: Linux SCSI Target – STGT / tgt Linux-IO Targ ...
- asp.net 前台js和后台得到FormView中的控件,以TextBox为例
一.前台js获取FormView中的控件 js得到前端控件的ID,比如TextBox(这里设置其ID为TextBox1),大家都知道,是document.getElementById("&l ...
- image元素的src属性值与getAttribute('src')值
采集的时候,当采集到一些不可用的照片就将其剔除掉 我的解决思路是new一个img对象, 然后将采集过来的图片赋值给这个img, 然后分别处理img的onerror和 onload, 当在onerror ...
- history.js 一个无刷新就可改变浏览器栏地址的插件(不依赖jquery)
示例: http://browserstate.github.io/history.js/demo/ 简介 HTML4有一些对浏览历史的前进后退API的支持如: window.hist ...
- HiveQL与SQL区别
转自:http://www.aboutyun.com/thread-7327-1-1.html 1.Hive不支持等值连接 SQL中对两表内联可以写成:select * from dual a,dua ...