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

模拟title属性提示框

2011年11月02日

模拟title属性提示框

当我们鼠标指向一个a标签,或一个带有title属性的元素时,会弹出一个小提示框来解释当前元素具体内容或者扩展说明,不过有没有这样一个需求:我要那个提示信息里面的“xxx”字 要重点突出下,给个橙色加粗吧,这样才大气!在我们瀑布汗and耐心解释这个是系统默认的,字不能加粗颜色也变不了的时候,结果就是“那就用js模拟一个吧”,所以就有以下这段代码的诞生了。

下面给大家分享的是一个 模拟title属性的提示框。

功能

在做每一个组件,都要想清楚,这个组件是要实现什么功能的,然后就是围绕着这些功能来进行实现。下面我就分析下这个需求的功能点

  • 文字能变色加粗(其实就是能支持自定义标签,模拟的东西本来就支持 无视)
  • 鼠标进过 提示框显示到鼠标当前位置的下方,鼠标离开对象提示框消失

思考

功能点就这2个,然后进一步分析得考虑到的问题:

  • 如果对象来有title,当鼠标移上去会在出现提示框的同时,也会出现title原来的提示框,该如何处理?
  • 要跟随鼠标移动吗?有特殊的情况是不跟随鼠标移动的吗?(原生title标签的那个提示框是不跟随鼠标的,只会在刚触发的时候出现,然后一直保持在那个位置,然后鼠标离开之后就会慢慢消失)
  • 用什么来储存要显示的内容?
  • 当提示框超出当前浏览器 screen高度 和宽度的时候如何处理?
  • 当内容为空的时候该如何处理?
  • 如果当前内容就那么一丁点,需要考虑宽度自适应吗?同理,要考虑给定义最大宽度吗?
  • 怎么处理层级深度 z-index?
  • 支持自定义标签的时候,如果自定义标签结构比较复杂的话,该如何处理?
  • 函数提供接口的各种数据类型匹配 和数值匹配。
  • 是否需要提供默认样式?

然后,就是分析这些问题的解决方案,判断是否考虑过多,or考虑欠周全,然后编码。

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

源代码

/* simulateTips(targets,option) 模拟title信息提示框
 * targets:应用此api的对象集合
 * option:{
	className:提示标签 class
	zIndex:提示框深度
	maxWidth:提示框最大宽度
	excursion_x:提示标签距离鼠标 x轴方向距离
	excursion_y: 提示标签距离鼠标 y轴方向距离
	content_before:提示标签以内,提示信息以上的内容代码
	content_after: 提示标签以内,提示信息以下的内容代码
	autoExchange: 提示信息是否支持title特性:水平方向保持不超出浏览器2侧,垂直方向如大于 网页内容的话,翻转至鼠标上方(具体参考 普通 title标签的提示效果)
	autoWidth: 宽度自适应
	mouseFollow:是否设置 标签跟随鼠标移动
	id:提示标签id
 }
 * simulateTips.setOption(option):属性设置
 * -option:属性
 * simulate.init()函数执行
 * -------------------------------------------------------
 * sample
	完整版:
	simulateTips("a",{
		className:"jsTips",
		zIndex:999,
		maxWidth:200,
		excursion_x:10,
		excursion_y:10,
		content_before:"<span class='orange'>",
		content_after:"</span>",
		autoExchange:true,
		autoWidth:true,
		mouseFollow:true,
		id:jacknessTips
	}).init();
	
	简单版:
	simulateTips("a",{className:"jsTips"}).init();
	
	最简约版:(使用本api自带样式)
	simulateTips("a").init();
 * -------------------------------------------------------
 * prower by jackNEss
 * date:2011-11-2(世界完全對稱日)
 * ver:1.0
 */

var simulateTips = function(){
	
	var option = {
		
		//提示标签 class
		className:"",
		
		//提示框深度
		zIndex:999,
		
		//提示框最大宽度
		maxWidth:200,
		
		//提示标签距离鼠标 x轴方向距离
		excursion_x:10,
		
		//提示标签距离鼠标 y轴方向距离
		excursion_y:10,
		
		//提示标签以内,提示信息以上的内容代码
		content_before:"",
		
		//提示标签以内,提示信息以下的内容代码
		content_after:"",
		
		//提示信息是否支持title特性:水平方向保持不超出浏览器2侧,垂直方向如大于 网页内容的话,翻转至鼠标上方(具体参考 普通 title标签的提示效果)
		autoExchange:true,
		
		//宽度自适应
		autoWidth:true,
		
		//是否设置 标签跟随鼠标移动
		mouseFollow:true,
		
		//提示信息内容从哪个属性中提取
		replaceAttribute:"title",
		
		//提示标签id
		id:"jackNEssTips" + Math.round(Math.random()*100)
	}
	
	var _targets,_op;
	var _tips;
	var _mouseKey;
	
	arguments[0]? _targets = easy_switch(arguments[0]):"";
	arguments[1]? _op = arguments[1]:"";
	
	function addEvent(elm,type,func){
		if(elm.attachEvent){
			elm.attachEvent("on" + type,_addEvent);
		}
		else if(elm.addEventListener){
			elm.addEventListener(type,_addEvent,false);
		}
		
		function _addEvent(e){
			func.call(elm,e);
		}
		
		return _addEvent;
	}
	
	function removeEvent(elm,type,func){
		if(elm.detachEvent){
			elm.detachEvent("on" + type,func);
		}
		else if(elm.removeEventListener){
			elm.removeEventListener(type,func,false);
		}
	}
	
	
	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(){
		
		//tips reset
		_tips = document.createElement("tips");
		_tips.className = option.className;
		
		//默认样式
		if(_tips.className ==""){
			_tips.style.cssText = "position:absolute; padding:3px; border:1px solid #767676; font-size:12px; color:#575757; line-height:1.5; background:#fff; background:-webkit-gradient(‘linear’,0 0,0 100%,from(#fff),to(#e4e5f0)); background:-moz-linear-gradient(top,#fff,#e4e5f0); -moz-box-shadow:2px 2px 2px #8e8e8e; -webkit-box-shadow:2px 2px 2px #8e8e8e; box-shadow:2px 2px 2px #8e8e8e; -moz-border-radius:3px; -webkit-border-radius:3px; border-radius:3px;"
		}
		_tips.style.display = "none";
		_tips.style.zIndex = option.zIndex;
		_tips.id = option.id;
		_tips.style.top = 0;
		_tips.style.left = 0;
		
		option.autoWidth?_tips.style.width = "auto":"";
		
		document.body.appendChild(_tips);
		
		//targets reset
		if(typeof _targets.length == "undefined"){
			_targets = [_targets];
		}
		
		for( var i = 0; i < _targets.length; i++){
			_targets[i].setAttribute("simulate_tips",_targets[i][option.replaceAttribute]||"");
			_targets[i].title = "";
			tipsEvent.call(_targets[i]);
		}
		
	}
	
	function tipsEvent(e){
		var _this = this;
		//mouseover事件
		addEvent(_this,"mouseover",function(e){
			e = e || window.event;
			if(this.getAttribute("simulate_tips") ==""){return;}
			_tips.innerHTML = option.content_before + this.getAttribute("simulate_tips") + option.content_after;
			_tips.style.display = "block";
			tipsPositionFix(e);
			if(option.mouseFollow){
				_mouseKey = addEvent(_this,"mousemove",function(e){
					mousemoveEvent.call(_this,e);
				})
			}
			
		});
		
		//mouseout事件
		addEvent(_this,"mouseout",function(e){
			_tips.style.display = "none";
			if(option.mouseFollow){
				removeEvent(_this,"mousemove",_mouseKey);
			}
		});
		
		
		function mousemoveEvent(e){
			tipsPositionFix(e);
		}

		
		function tipsPositionFix(e){
			e = e || window.event;
			
			var tipsTop,tipsLeft,tipsWidth,tipsHeight;
			
			option.autoWidth?(
				_tips.style.width="auto",
				_tips.offsetWidth > option.maxWidth? _tips.style.width = option.maxWidth + "px":""
			):"";
			
			tipsHeight = _tips.offsetHeight;
			tipsWidth = _tips.offsetWidth;
			tipsLeft = e.clientX + (document.body.scrollLeft||document.documentElement.scrollLeft||0) + option.excursion_x;
			tipsTop = e.clientY + (document.body.scrollTop||document.documentElement.scrollTop||0) + option.excursion_y;
			
			screenMaxLeft = (document.body.scrollLeft||document.documentElement.scrollLeft||0) + document.documentElement.clientWidth;
			screenMaxTop = (document.body.scrollTop||document.documentElement.scrollTop||0) + document.documentElement.clientHeight;
			
			if(option.autoExchange){
				tipsLeft > screenMaxLeft - tipsWidth? tipsLeft = screenMaxLeft - tipsWidth:"";
				tipsTop > screenMaxTop - tipsHeight - option.excursion_y? tipsTop = tipsTop - tipsHeight - 2*option.excursion_y:"";
				
				tipsLeft < 0 ? tipsLeft = 0:"";
				tipsTop < 0? tipsTop = 0:"";
			}
			
			_tips.style.top = tipsTop + "px";
			_tips.style.left = tipsLeft + "px";
		}
	}
	
	return{
		setOption:function(op){
			op.className? option.className = op.className:"";
			op.excursion_x?option.excursion_x = parseInt(op.excursion_x):"";
			op.excursion_y?option.excursion_y = parseInt(op.excursion_y):"";
			op.content_before?option.content_before = op.content_before:"";
			op.content_after?option.content_after = op.content_after:"";
			
			typeof op.autoExchange == "boolean"? option.autoExchange = op.autoExchange:"";
			typeof op.mouseFollow == "boolean"? option.mouseFollow = op.mouseFollow:"";
			typeof op.autoWidth == "boolean"? option.autoWidth = op.autoWidth:"";
			op.replaceAttribute? option.replaceAttribute = op.replaceAttribute:"";
			op.id?option.id = op.id:"";
			
			op.zIndex?option.zIndex = parseInt(op.zIndex):"";
			op.maxWidth?option.maxWidth = parseInt(op.maxWidth):"";
			
			
			return this;
		},
		init:function(){
			if(!_targets){return;}
			if(_op){this.setOption(_op);}
			areaReset();
		}
		
	}
	
}	
分类javascript
阅读 3,499
  • 评论加载中...

标签云

分类目录

最新留言

  • 评论加载中...

与我联系

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

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