星级评分的简化实现
2012-07-07 22:56
357 查看
星级评分是调查的一个常用功能,网上常见多是动态调用图片实现的,我结合 CSS 想出一种更简洁的方法。功能使用更方便,HTML页源代码和 JavaScript 语句更简洁,使用 CSS 排版进一步实现和内容与设计的分享。使用 CSS 用单个图片做背景,还有个额外带来的好处,即页面下载完后作为背景的那个图片就已经加载,再动态切换对象的样式类名时由于用的是同一个图片文件,所以显示效果没有延迟。传统的换用其它图片来显示不同状态的方法,在加载新图片时难免会有延迟,除非另用 JavaScript 事先把图片都下载下来。 基本思路: 星级评分区独立用一个 div 块,根据鼠标在此块内的横向位置,换算出所在位置和块宽度的比例,再折算成1-5的数值,如以下范例中块宽是 80 像素,当鼠标横坐标是27时,(27/80)*5,取上限,可以折算出评分为2分。 先做HTML页,最基本的内容是[html] view plaincopy<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>星级评分</title>
<link href="css.css" rel="stylesheet" type="text/css" />
<script language="JavaScript" src="star.js" type="text/JavaScript"></script>
</head>
<body>
星级评分。这里把 input 先做成 text 型的,实际方便调试,实际使用时变成 hidden 型即可。
<form name="qn" method="post" action="#">
<input type="text" name="field0" id="field0" />
<div class="ratingstar" id="field0_star"
onClick="page.starSet(this, 'field0');"
onmousemove="page.starHover(this);"
onmouseout="page.starOut(this, 'field0');">
<div id="field0_star_hover"></div></div>
</form>
</body>
</html>
调用的 css.css 文件中涉及到如下三个样式定义: .ratingstar,.ratingstar_hover, .ratingstar_set { height: 16px; width: 80px; cursor:pointer; /* border: solid 1px red; cursor: hand; 只有IE支持,pointer 是 FF 和 IE 都支持的手型鼠标*/ background-image: url(ratingstar.gif); background-repeat: repeat-x; position:relative; /*解决 Firefox 中获取鼠标位置不准确的问题*/ } .ratingstar_hover { background-position: 0 -32px; } .ratingstar_set { background-position: 0 -16px; }
其中 ratingstar.gif 这个图片是个宽16,高48的图片,竖排3个颜色不同的星星,CSS 中使用 background-repeat: repeat-x; 让它横向平铺,再结合整块宽度定义成 width: 80px; 就显示出5个星星了。即整块宽度一定要定义成图片宽度的5倍。 .ratingstar_hover 样式是在动态显示时用的,定义成 background-position: 0 -32px; 是把背景图片上移32像素,则只显示
ratingstar.gif 图片中最下面那个星。而用它的宽度是由 JavaScript 动态指定的,从而可以显示出指定个数的星星。
star.js:
[jscript] view
plaincopy
<font>function getEvent() //同时兼容ie和ff的写
{
if(document.all) return window.event;
func=getEvent.caller;
while(func!=null){
var arg0=func.arguments[0];
if(arg0)
{
if((arg0.constructor==Event || arg0.constructor ==MouseEvent) || (typeof(arg0)=="object" && arg0.preventDefault && arg0.stopPropagation))
{
return arg0;
}
}
func=func.caller;
}
return null;
}
function getMouseWithinX(){
e = getEvent();
var mouseX = 0;
var mouseY = 0;
//Firefox 虽然 layerY 还不准,但至少 layerX 准了,现在只用横轴的值就够
if(navigator.userAgent.indexOf("Firefox")!=-1){
return e.layerX;
}
//IE 用 offsetX, offsetY 表示鼠标相对所在元素的位置
else{
return e.offsetX;
}
}
var page=
{
$:function(el)
{
return document.getElementById(el);
},
starHover:function(obj)
{
var mousex = getMouseWithinX();
//当前对象的宽用 clientWidth
var intStar = Math.ceil(5 * (mousex / obj.clientWidth));
var widthStar = intStar * obj.clientWidth / 5;
var hover = obj.id+'_hover'; //由 HTML 固定写出显示星星的内部层了,其名字是外部层id加_hover
obj.title=intStar+'/5';
var objHover = this.$(hover);
objHover.className="ratingstar_hover";
objHover.style.width = widthStar+'px'; //动态设置宽度要加上 px 字样!
},
starOut:function(obj, container)
{
//鼠标移出时读一下表单项中设定的值,根据那值固定下星星显示的情况
if(this.$(container))
var intStar = this.$(container).value;
var widthStar = intStar * obj.clientWidth / 5;
var hover = obj.id+'_hover'; //由 HTML 固定写出显示星星的内部层了,其名字是外部层id加_hover
var objHover = this.$(hover);
objHover.className="ratingstar_set";
objHover.style.width = widthStar+'px'; //动态设置宽度要加上 px 字样!
},
starSet:function(obj, container)
{
var mousex = getMouseWithinX();
var intStar = Math.ceil(5 * (mousex / obj.clientWidth));
var widthStar = intStar * obj.clientWidth / 5;
var hover = obj.id+'_hover';
var objHover = this.$(hover);
objHover.className="ratingstar_set";
objHover.style.width = widthStar+'px'; //动态设置宽度要加上 px 字样!
if(this.$(container))
this.$(container).value=intStar;
}
}
</font><span style="font-family: Courier New;">
</span>前2个函数都是调用现成的库,只为得到鼠标在某个元素范围内的位置,核心算法就在 starHover 函数,思路已经在最前面介绍过了。其它细节说明都在函数中的注释。
前几天曾经想把页面的 HTML 做到最简化,即只保留 <div class="ratingstar" id="field0_star" onClick="page.starSet(this, 'field0');" onmousemove="page.starHover(this);" onmouseout="page.starOut(this, 'field0');"></div> 而内层的 <div id="field0_star_hover"></div>
由 JavaScript 动态生成,但是发生奇怪的问题:鼠标在 field0_star 范围内移动时貌似会不停触发 onmousemove 和 onmouseout 事件,从而使得两种样式不停切换,显示效果就是闪得厉害。所以暂定现在的方案。
现在的方案中也有遗留的小问题:CSS 中的 position:relative; 是为了解决 Firefox 中获取鼠标位置不准确的问题。如果不加这句,在 Firefox 中 getMouseWithinX() 得到鼠标位置貌似不是期望的相对 field0_star 的位置,而是相对页面的位置,所以值会过大,效果就是鼠标一移上去就会显示多于5个星星。要把这几个问题搞清,还需要进一步弄清楚IE和FF中事件与其元素及鼠标的关系。如果哪位同仁有所见解,欢迎留言交流。
相关文章推荐
- 星级评分的简化实现
- 原生js实现的星级评分效果
- 【JS】星级评分原理和实现( 下集第2章 第四种实现方式 )
- iOS 一个简单的实现星级评分的方法
- 使用jQuery实现星级评分代码分享
- jQuery动态星级评分效果实现方法
- jQuery+PHP实现星级评分
- jQuery+PHP星级评分实现方法
- JS实现星级评分
- jquery raty星级评分插件的具体使用(可以结合ajax和后台交互)以及点赞功能的实现
- JS实现带提示的星级评分效果完整实例
- jQuery动态星级评分效果实现方法
- 如何用纯代码实现评分星级显示?
- 很酷的星级评分系统原生JS实现
- vue---实现类似淘宝星级评分
- jQuery动态星级评分效果实现方法
- 【JS】星级评分原理和实现(下集 第3章 第五种实现方式-上 )
- CSS实现星级评分III
- jQuery实现星级评分
- 星级评分效果 -js实现