欢迎来到 jackNEss'窝窝
I like simple mind

模拟滚动条

2011年11月06日

模拟滚动条

首先要说的是,给滚动条自定义样式,只有ie only,其他浏览器是没有这档事的,而且 ie的 滚动条自定义样式仅仅局限于 改颜色(高光边色,主体色,暗边色),水晶特效,外发光那些都是传说,单凭css是实现不了的。

自我认为window 自带的 滚动条样子还行,看久了挺有味道的,不过设计师们在页面设计的时候,有时候会根据网页风格,会给滚动条画得十分个性化,而从我们前端的角度来看…

“这个滚动条画得是挺好的,水晶特效,内阴影外发光全都做得很到位…但是,其实window默认的滚动条和你现在设计的页面风格也挺搭的,能用回默认的吗,亲?”

说到这个份上,有时候,设计师看了下,其实默认的也确实还行的话,设计师会让步让我们制作端轻松些,嘛当然有时候丢个默认上去确实,连路人甲走过都觉得不搭的话,那就只好我们通过其他方式模拟一个滚动条出来了。(这个控件是在整理 js控件库的时候整理出来的,今年5月份写的一个小功能,稍微更新下之后,果断拿出来分享下。)

功能分析

说到模拟滚动条,当然做出来的功能就得完全copy 原生滚动条的功能喇(在这里我把需进行滚动操作的模块称为目标对象),具体功能点有:

  • 模拟滚动条里面滑块的大小根据目标对象的大小而改变。
  • 滚动条操作为 onmousedown,onmouseup。
  • 滚动条滑块在滚动条的开始位置时,目标对象也在初始位置,滚动条滑块在滚动条的末端位置时,目标对象也在末端位置,即2者需要同步。

值得注意的是,ie浏览器页面刷新的时候,目标对象的 scrollTop 和 scrollLeft 会保留维持刷新前的数值,而其他浏览器不会,所以为了我们控件的统一性,建议是刷新的时候也一并初始化 目标对象 的 scrollLeft 和 scrollTop。

需思考问题:

为了保证控件的通用性,有些问题我们其实是需要想到的。

  • 若模拟滚动条中滑块不止是单一 tag标签的话该如何处理(最常见就是带圆角的,我们得切开3份,2边+中间)

JS源代码

功能分析完了,剩下就是针对功能来进行代码实现了。

演示地址: http://www.jackness.org/lab/analog_scroll/demo.html

// JavaScript Document
/* 模拟滚动条(
	使用条件:
	scrollElement.offsetWidth == scrollElement.style.width
	scrollElement.offsetHeight == scrollElement.style.height
	
	scrollbar里面只有1个childNode 而 
	childNode.offsetWidth == childNode.style.width, 
	childNode.offsetHeight == childNode.style.height,
	childNode.style.position == "absolute"
 )
 *
 * analogScroll(scrollElement,scrollbar,option)
 * -scrollElement:需要通过滚动条进行操作的主体
 * -scrollbar:滚动条对象
 * -option:{
	 	scrollElement:null,需要通过滚动条进行操作的主体
		scrollbar:null,滚动条对象
		scrollDirection:"y"	滚动方向
	}
 *
 * analogScroll.setOption();//属性设置
 * analogScroll.init(); //函数执行
 *
 * ----------------------------------------------------------
 * example:
	analogScroll("#list","#scroll_area2",{scrollDirection:"x"}).init();
 *
 * ----------------------------------------------------------
 *
 * power by jackness
 * date:2011-11-6
 * ver 1.1
 */
var analogScroll = function(){
	
	// 用户设置 start
	var option ={
		scrollElement:null,
		scrollbar:null,
		scrollDirection:"y"	
	}
	// 用户设置 end	
	
	var _op;
	arguments[0]? option.scrollElement = easy_switch(arguments[0]):"";
	arguments[1]? option.scrollbar = easy_switch(arguments[1]):"";
	arguments[2]? _op = arguments[2]:"";
	
	//简易选择器
	function easy_switch(elm){
		if(typeof elm == "string"){
			var strs = elm.split(" ");
			var targetElements = [document.body];
			for(var i = 0; i < strs.length; i++){
				if(!targetElements){return false;}
				var flagGroups = new Array();
				
				for(var j = 0; j < targetElements.length; j++ ){
					
					var datasource = typeSwitcher(targetElements[j],strs[i]);
					if(!datasource){return false;}
					if(!datasource.length){
						if(datasource){
							flagGroups.push(datasource);
						}
					}
					else{
						
						for(var k = 0; k < datasource.length; k++){
							if(datasource[k]){
								flagGroups.push(datasource[k])
							}
						}	
					}
					
				}
				targetElements = flagGroups;
			}
			if(targetElements.length ==1){return targetElements[0]}
			else {return targetElements;}
		}
		else{
			return elm;	
		}
		function typeSwitcher(elm,str){
			
			if(str.substring(0,1) == "#"){
				return document.getElementById( str.substring(1,str.length) )	
			}
			else if(str.substring(0,1) == "."){
				var flag = elm.getElementsByTagName("*");
				var results = [];
				var classStr = str.substring(1,str.length);
				var classNames;
				for(var i = 0; i < flag.length; i++ ){
					classNames = flag[i].className.split(" ");
					
					for( var j = 0; j < classNames.length; j++ ){
						if( classStr == classNames[j] ){
							results.push(flag[i]);	
						}
					}
				}
				return results;
			}
			else{
				var result = elm.getElementsByTagName(str)	
				if(result.length >0){
					return result;	
				}
				else{
					return false;	
				}
			}
		}
	}
	
	function areaReset(){
		
		//滚动条 size 初始化
		var scale = 0;
		option.scrollbar.cell = option.scrollbar.children[0];
		if(option.scrollDirection == "y"){
			
			if(option.scrollElement.scrollHeight ==0){
				scale = 1;
			}
			else{
				scale = option.scrollElement.offsetHeight/option.scrollElement.scrollHeight;
				scale > 1?scale = 1:"";
			}
			option.scrollbar.cell.style.height = option.scrollbar.offsetHeight*scale + "px";
			option.scrollElement.scrollLeft = 0
		}
		else{
			
			if(option.scrollElement.scrollWidth ==0){
				scale = 1;
			}
			else{
				scale = option.scrollElement.offsetWidth/option.scrollElement.scrollWidth;
				scale > 1?scale = 1:"";
			}
			option.scrollbar.cell.style.width = option.scrollbar.offsetWidth*scale + "px";
			option.scrollElement.scrollTop = 0
		}
			
		//滚动条添加事件
		option.scrollbar.cell.onmousedown = function(e){
			
			e = e || window.event;
			var posX = e.clientX - this.offsetLeft;
			var posY = e.clientY - this.offsetTop;
			
			document.onselectstart = function(){return false;}
			window.getSelection?(
				window.getSelection().removeAllRanges()
			):(
				document.selection.empty()
			);
			
			document.onmousemove = function(e){
				e = e || window.event;
				var scale = 0;
				
				if(option.scrollDirection == "y"){
					var nowTop = e.clientY - posY;
					nowTop < 0? nowTop =0:"";
					nowTop > (option.scrollbar.offsetHeight - option.scrollbar.cell.offsetHeight)? nowTop = (option.scrollbar.offsetHeight - option.scrollbar.cell.offsetHeight):"";
					option.scrollbar.cell.style.top = nowTop + "px";
					
					scale = nowTop/(option.scrollbar.offsetHeight - option.scrollbar.cell.offsetHeight);
					option.scrollElement.scrollTop = (option.scrollElement.scrollHeight - option.scrollElement.offsetHeight)*scale;	
				}
				else{
					var nowLeft = e.clientX - posX;
					nowLeft < 0? nowLeft = 0:"";
					nowLeft > (option.scrollbar.offsetWidth - option.scrollbar.cell.offsetWidth)? nowLeft = (option.scrollbar.offsetWidth - option.scrollbar.cell.offsetWidth):"";
					option.scrollbar.cell.style.left = nowLeft + "px";
					
					scale = nowLeft/(option.scrollbar.offsetWidth - option.scrollbar.cell.offsetWidth);
					option.scrollElement.scrollLeft = (option.scrollElement.scrollWidth - option.scrollElement.offsetWidth)*scale;
				}
				
				document.onmouseup = function(){
					document.onselectstart = null;
					document.onmousemove = null;	
					document.onmouseup = null;
				}
				
				
			}	
		}
	}
	
	return{
		
		//属性设置
		setOption:function(op){
			op.scrollElement? option.scrollElement = easy_switch( op.scrollElement ):"";
			op.scrollbar? option.scrollbar = easy_switch( op.scrollbar ):"";
			op.scrollDirection? option.scrollDirection = op.scrollDirection:"";
			return this;	
		},
		
		//执行函数
		init:function(){
			if(_op){this.setOption(_op);}
			areaReset();
			
		}
	}
}	
分类javascript
阅读 2,121
  • 评论加载中...

标签云

分类目录

最新留言

  • 评论加载中...

与我联系

如有疑问or建议可通过以下方式跟我取得联系.

Q Q:373435871
Email:jackness1208@gmail.com
© Copyright 2011 - 2014 jackNEss.org All Rights Reserved 粤ICP备14065612号
首页 | 关于我 | 网站地图 | RSS