lenorewei
12/16/2017 - 12:07 PM

dom常用函数

export function addClass(ele,className){
	 let currClass = ele.getAttribute('class'),
	 	 classArr = currClass?currClass.split(' '):[],
		 index = classArr.indexOf(className);
	 if(index === -1){
		 classArr.push(className)
	 }
	 let newClass = classArr.join(' ');
	 ele.setAttribute('class',newClass);
 };

export function removeClass(ele,className){
	let currClass = ele.getAttribute('class'),
		classArr = currClass?currClass.split(' '):[],
		index = classArr.indexOf(className);
	if(index > -1){
		classArr.splice(index,1);
	}
	let newClass = classArr.join(' ');
	ele.setAttribute('class',newClass);
};

export function hasClass(ele,className){
	let classArr = ele.classList||[];
	return classArr.length ? classArr.contains(className):false
};
// 移除兄弟元素的className,并给自己加上className
export function removeSiblingsClass(ele,className){
	let parentNode = ele.parentNode;
	let arr = parentNode.children;
	for(let i=0,len=arr.length;i<len;i++){
		removeClass(arr[i],className)
	}
	addClass(ele,className);
};

export function isClickInner(ele,parentEle){
	let node = ele.parentNode;
	while(node !== null){
		if(node == parentEle){
			return true
		}
		node = node.parentNode
	}
	return false
}

export function getCSSAttr(ele,attr){
	if(ele.currentStyle) {
		return ele.currentStyle[attr]
	}else{
		return document.defaultView.getComputedStyle(ele,null)[attr]
	}
}


export function getText(ele){
	return (typeof ele.textContent == "string") ? ele.textContent : ele.innerText;
}
export function setText(ele,text){
	if(ele.textContent) {
		ele.textContent = text;
	}else{
		ele.innerText = text;
	}
}

/**
 * 获取制定元素左上角距离window左侧的距离
 * @param elem
 * @returns {*}
 */
export function getpageX (elem) {
    //检查我们是否已经到了根元素
    return elem.offsetParent ?
        //如果我们还能往上,则将当前偏移与向上递归的值相加
    elem.offsetLeft + getpageX( elem.offsetParent ) :
        //否则,取当前偏移
        elem.offsetLeft;
};
/**
 * 获取制定元素左上角距离window顶部的距离
 * @param elem
 * @returns {*}
 */
//计算元素的Y(垂直,顶)位置
export function getpageY (elem) {
    //检查我们是否已经到了根元素
    return elem.offsetParent ?
        //如果我们还能往上,则将当前偏移与向上递归的值相加
    elem.offsetTop + getpageY( elem.offsetParent ) :
        //否则,取当前偏移
        elem.offsetTop;
}

/**
 * 频率控制 返回函数连续调用时,func 执行频率限定为 次 / wait
 * 
 * @param  {function}   func      传入函数
 * @param  {number}     wait      表示时间窗口的间隔
 * @param  {object}     options   如果想忽略开始边界上的调用,传入{leading: false}。
 *                                如果想忽略结尾边界上的调用,传入{trailing: false}
 * @return {function}             返回客户调用函数   
 */
export function throttle (func, wait, options) {
	var context, args, result;
	var timeout = null;
	// 上次执行时间点
	var previous = 0;
	if (!options) options = {};
	// 延迟执行函数
	var later = function() {
		// 若设定了开始边界不执行选项,上次执行时间始终为0
		previous = options.leading === false ? 0 : new Date().getTime();
		timeout = null;
		result = func.apply(context, args);
		if (!timeout) context = args = null;
	};
	return function() {
		var now = new Date().getTime();
		// 首次执行时,如果设定了开始边界不执行选项,将上次执行时间设定为当前时间。
		if (!previous && options.leading === false) previous = now;
		// 延迟执行时间间隔
		var remaining = wait - (now - previous);
		context = this;
		args = arguments;
		// 延迟时间间隔remaining小于等于0,表示上次执行至此所间隔时间已经超过一个时间窗口
		// remaining大于时间窗口wait,表示客户端系统时间被调整过
		if (remaining <= 0 || remaining > wait) {
			clearTimeout(timeout);
			timeout = null;
			previous = now;
			result = func.apply(context, args);
			if (!timeout) context = args = null;
			//如果延迟执行不存在,且没有设定结尾边界不执行选项
		} else if (!timeout && options.trailing !== false) {
			timeout = setTimeout(later, remaining);
		}
		return result;
	}
}

/**
 * 空闲控制 返回函数连续调用时,空闲时间必须大于或等于 wait,func 才会执行
 *
 * @param  {function} func        传入函数
 * @param  {number}   wait        表示时间窗口的间隔
 * @param  {boolean}  immediate   设置为ture时,调用触发于开始边界而不是结束边界
 * @return {function}             返回客户调用函数
 */
export function debounce(func, wait, immediate) {
	var timeout, args, context, timestamp, result;

	var later = function() {
		// 据上一次触发时间间隔
		var last = new Date().getTime() - timestamp;

		// 上次被包装函数被调用时间间隔last小于设定时间间隔wait
		if (last < wait && last > 0) {
			timeout = setTimeout(later, wait - last);
		} else {
			timeout = null;
			// 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
			if (!immediate) {
				result = func.apply(context, args);
				if (!timeout) context = args = null;
			}
		}
	};

	return function() {
		context = this;
		args = arguments;
		timestamp = new Date().getTime();
		var callNow = immediate && !timeout;
		// 如果延时不存在,重新设定延时
		if (!timeout) timeout = setTimeout(later, wait);
		if (callNow) {
			result = func.apply(context, args);
			context = args = null;
		}
		return result;
	}
}