打造自己的js库1 -- dom操作的封装

打造自己的js1.1

 

前言:

当前已经有许多非常成熟的js框架,如jquery,prototype,yui等等,他们各有特色,但也有许多相同的特性,他们都是由许多基础的js函数组建而成。而js库不同于框架,我们在这里只是把常用的js操作制作成函数然后整合为自己的一个js库,当然,当这些操作积累到一定程度,也通过使用一些设计模式,分类而演变成属于自己的一个mini js框架。好了,我们从基础的部分开始吧。

 

Js最常用的操作就是对dom的操作,所以我们的封装也从对dom的操作开始。

 

1.得到dom元素

得到dom元素的方法有很多种,当然也多强大的框架提供了dom元素获取的方法,比如jquery sizzle就是一个纯jsCSS 选择器引擎,在这里我们做不到这么复杂,只是应对常用的选择操作。


var Choose = function(selector, context){
	context = context || document;

	var result = [],
		idElem = new RegExp("^#[a-zA-Z0-9\\-]*"),
		classElem = new RegExp("^\\.{1}[a-zA-Z0-9\\-]*"),
		tagElem = new RegExp("^[a-zA-Z0-9\\-]*$");
		_selector = selector.substring(1,selector.length);

	var hasClass = function(element,className){
		var reg = new RegExp("\\s|<span style="font-family: Arial, Helvetica, sans-serif;">^</span><span style="font-family: Arial, Helvetica, sans-serif;">" + className +"\\s|$");</span>
		return reg.test(element.className);
	},
	getByClass = function(className){
		var result = [],
			nodes = context.getElementsByTagName("*");
		for(var i = 0;i < nodes.length;i++){
			if( hasClass(nodes[i],className) ){
				result[result.length] = nodes[i];
			}
		}
		return result;
	};

	//如果不是dom元素,nodeType == 9 为document ==3 为普通的dom
	if (!context.nodeType || (context.nodeType != 9 && context.nodeType != 1)){
		return result;
	}

	//是id选择器
	if (selector.match(idElem) && selector.match(idElem)[0].length == selector.length){
		result[result.length] = context.getElementById(_selector);
		return result;
	} else if (selector.match(classElem) && selector.match(classElem)[0].length == selector.length){
		//如果是类选择器
		if(document.getElementsByClassName)
			return context.getElementsByClassName(_selector);
		return getByClass(_selector);
	} else if (selector.match(tagElem) && selector.match(tagElem)[0].length == selector.length){
		//如果是名称选择器
		return context.getElementsByTagName(selector);
	} else {
		//其他选择器 兼容ie8+
		if(document.querySelectorAll)
			return context.querySelectorAll(selector);
		return [];
	}


};

上述代码对应了4种情况的选择,分别是 id class tagName 和通过css选择,不过最后一种方法只支持IE8+浏览器。


2.子元素遍历,该函数通过递归遍历子元素,用户可以指定一个filter来过滤不需要的dom


var nodeIntor = function(){
	var 
	//保存this指针
	_this,
	//保存所有符合条件的node
	nodes = [],
	//加入符合条件的函数
	callback = function(node) {
		//过滤text
		if(_this.filter(node) && node.nodeType == 1) {
			nodes[nodes.length] = node;
		}
	},
	//遍历node
	processElements = function(node, isOuter) {
		var children = node.hasChildNodes()?node.childNodes:[];
		for(var i = 0;i < children.length;i++) {
			//递归遍历
			if( children[i].hasChildNodes() ) {
				processElements(children[i]);
			}
			callback.call( this, children[i] );
		}
		if(isOuter)
			callback.call( this, node );
	},
	//初始化函数
	init = function(selector, filter){
		this.root = Choose(selector)[0];  // || document
		this.filter = filter;
		_this = this;
		processElements(this.root,true);
	};
	return {
		traverse : init,
		nodes : nodes
	}
}();

3.属性设置/获取

var attr = function(selector, key, value){
	var node = Choose(selector)[0];
	if(value){
		node.setAttribute(key, value);
	}
	return node.getAttribute(key);
};

4.设置/获取元素的css属性

var css = function(){
	var pfx = function(style){
		//得到符合的前缀
		var s = "Webkit,Moz,O,ms,Khtml",
			pre = s.split(","),
			tNode = document.createElement("div");
		for(var i = 0;i < pre.length;i ++) {
			//重新组装style
			var reStyle = pre[i] + style.charAt(0).toUpperCase() + style.substr(1);

			if( tNode.style[reStyle] != undefined){
				return reStyle;
			}
		}
		return style;
	},
	setCss = function(node, styles){
		if (typeof styles === 'object'){
			for (var i in styles){
				node.style[pfx(i)] = styles[i];
			}
		}
	},
	getCss = function(node, style){
		//兼容ie ff
		var styles = window.getComputedStyle ? window.getComputedStyle(node,null) : obj.currentStyle;
		return styles [pfx(style)];
	}

	return {
		setCss : setCss,
		getCss : getCss
	}
}();


以上内容均为本人原创,转载请注明出处,欢迎大家批评指正。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值