基于 SVG 的星级评分控件






4.68/5 (11投票s)
一个使用 SVG 而不是图像精灵的星级评分控件
引言
星级评分控件在当今的网站上非常常见且无处不在。您可以在 amazon.com、netflix.com 甚至 codeproject.com 等网站上找到它们。这些控件允许用户对亚马逊上的商品、Netflix 上的电影,或者在 codeproject 的情况下对您目前正在阅读的文章进行评分。您是否想过它们是如何工作的?它们大多数是基于图像精灵和一些 CSS 神技。在您喜欢的搜索引擎中搜索一下,您就会明白我的意思。我认为现在是时候转向使用 SVG 而不是图像精灵的控件了。如今大多数常用的浏览器都完全支持 SVG。如果您的浏览器不支持,那您还在用它吗?基于 SVG 的控件有什么优势?如本文所示,基于 SVG 的控件可以高度可配置。您想要 5 颗星还是 10 颗星?您想让星星显示为黄色还是红色?我将在本文中介绍的 SVG 控件允许您轻松配置这些设置,并根据您的需求自定义控件。
背景
读者最好对 JavaScript、HTML 和 SVG 有一些基本的了解。我已在 IE9 和 Chrome 上测试了示例。
Using the Code
我们直接开始吧。下载 star_rating_demo.zip 并解压缩,您应该会在解压缩的文件夹中看到四个文件:star_rating.js、demo.html、demo2.html、demo3.html。
控件的所有代码都在一个文件 star_rating.js
中。我将通过 3 个示例来说明如何使用该控件。
示例 #1 demo.html
此示例的所有代码都在文件 demo.html
中,并在此处复制
<!doctype html>
<html>
<head>
</head>
<body>
<div id="my_widget"
class="rating_widget"
number_of_stars="5"
initial_value="0"
default_color="#ccc"
initial_value_color="#ff0"
final_value_color="#f00"
captions="Poor, Didn't like it, OK, Good, Excellent!"
onclick="clickHandler"
></div>
<script src="star_rating.js">
</script>
<script>
function clickHandler(sender, args)
{
alert('your rating: ' + args);
}
</script>
</body>
</html>
由于技术限制,本文无法展示可运行的示例。将提供截图。要查看可运行的示例,只需访问 此页面。
在网页浏览器中查看 demo.html
的截图
要查看完整的可运行示例及其功能,请在网页浏览器中打开 demo.html
。您将看到 5 颗灰色星星(请查找上面的代码中的 default_color="#ccc"
)。当您将鼠标悬停在星星上时,它们会变成红色(请查找上面的代码中的 final_value_color="#f00"
),并且还会显示相应的文本(差、不喜欢、一般、好、优秀!)。如果您单击,控件将冻结,并且 clickHandler
函数将被调用。评分将作为 args
参数传递给函数。查找应用于 div 的 class="rating_widget"
- 这将导致控件出现在 div 中。
示例 #2 demo2.html
在此示例中,我们希望控件最初显示 10 颗星,并且初始评分为 7。此外,我将展示创建控件的另一种方法(这次是在 JavaScript 中,而不是像示例 #1 那样在标记中)
<!doctype html>
<html>
<head>
</head>
<body>
<script src="star_rating.js">
</script>
<script>
var widget = new rating_widget(
{
number_of_stars: 10, // the total number of stars in the control
initial_value: 7, // initial rating
default_color: 'rgb(200,200,200)', // the grey stars
initial_value_color: 'rgb(255,255,0)', // the yellow stars
final_value_color: 'rgb(255,0,0)', // the red stars
captions: '1,2,3,4,5,6,7,8,9,10', // text to display to provide feedback to user
parentNode: document.body, // parent node of the control
onclick: function(sender, args) // function to execute on mouse click
{
alert('your rating: ' + args);
}
});
</script>
</body>
</html>
在网页浏览器中查看 demo2.html
的截图
通过更改 rating_widget
构造函数的输入参数值,您可以根据您的需求配置控件 - 轻松更改颜色、星星数量和标题。
示例 #3 demo 3.html
在最后一个示例中,我们将显示一个静态控件 - 一个不允许用户更改评分的控件
<!doctype html>
<html>
<head>
</head>
<body>
<div id="my_widget"
class="rating_widget"
number_of_stars="5"
initial_value="3.5"
default_color="#ccc"
initial_value_color="#ff0"
final_value_color="#f00"
disabled="true"
></div>
<script src="star_rating.js">
</script>
</body>
</html>
在网页浏览器中查看 demo3.html
的截图
将 disabled="true"
设置为 true
可以禁用控件,使其无法更改评分。
工作原理
现在让我们了解控件的内部工作原理。让我们从 star_rating.js
中的这段代码开始
document.body.onload = function()
{
var array = document.getElementsByClassName('rating_widget');
for(var i = 0; i < array.length; i++)
{
var e = array[i];
var widget = new rating_widget(
{
number_of_stars: e.getAttribute('number_of_stars') ? e.getAttribute('number_of_stars') : 5,
initial_value: e.getAttribute('initial_value') ? e.getAttribute('initial_value') : 0,
default_color: parseColor(e.getAttribute('default_color'), 'rgb(200,200,200)'),
initial_value_color: parseColor(e.getAttribute('initial_value_color'), 'rgb(255,255,0)'),
final_value_color: parseColor(e.getAttribute('final_value_color'), 'rgb(255,0,0)'),
captions: e.getAttribute('captions'),
captions_class_name: e.getAttribute('captions_class_name'),
onclick: e.getAttribute('onclick'),
disabled: e.getAttribute('disabled'),
parentNode: e
});
}
};
上面的函数将在 html 文档的 body 加载时执行。我们获取 html 文档中所有应用了 rating_widget
类的元素,并将它们存储在变量 array
中。然后我们遍历这些元素,并为每个元素创建一个星级评分控件。星星的数量默认为 5,除非元素上存在 number_of_stars
属性来定义您想要的控件中的星星数量。initial_value
是您想应用于控件的初始评分。对于从未评级过的项目,这将是 0,但对于反映过去的评级,则可以是非零值。与控件交互以了解 default_color
、initial_value_color
和 final_value_color
的含义。captions
是与不同评分对应的字符串数组。您可以通过 CSS 样式化字幕的外观,并在变量 captions_class_name
中传入 CSS 类名。onclick
定义了用户单击控件时要调用的函数。如果将 disabled
设置为 true
,则控件将被禁用,意味着它会失去交互性并冻结。这在您想使用控件显示评分但又不允许用户更改评分时很有用 - 例如,如果用户未登录。控件的父节点通过 parentNode: e
指定。
现在让我们深入研究 rating_widget
函数。有趣的部分在 rating_widget
中的以下代码
for(var i = 0; i < n; i++)
{
var star = document.createElementNS(svgns, "path");
star.setAttributeNS(null, "d", coordinates);
star.setAttributeNS(null, "transform", transform(0.3947432, 0, 0, 0.414816, 20*i, 1.159472));
star.setAttributeNS(null, "style", style);
svg_root.appendChild(star);
var box = bbox(star);
if (!disabled)
{
if (box) { attachEventHandlers(box, boxes); }
else { attachEventHandlers(star, stars); }
}
stars.push(star);
boxes.push(box);
}
initial_state();
n
是我们要显示的星星数量。绘制一颗星的 SVG 路径存储在变量 coordinates
中。要绘制多颗星,我们重复使用相同的 coordinates
,但对其应用转换。20*i
是转换的 x 分量,是关键部分。线粗、线型 - 是实线还是虚线等 - 在变量 style
中定义。bbox
函数计算星星的边界框。如果计算成功,我们会将鼠标事件处理程序附加到星星的边界框上,否则我们将处理程序附加到星星本身。有关更多详细信息,请参阅 此帖子。鼠标事件处理程序为控件提供了交互性。initial_state
函数使用构造函数中传入的 initial_value
初始化控件。
在调试器中逐步执行代码,以更深入地了解其工作原理。
结论
在本文中,我介绍了一个使用 SVG 而非图像精灵和 CSS 的星级评分控件。该控件高度可配置,可以轻松更改星星的数量、颜色和标题文本。控件可以嵌入到 HTML 标记中(示例 #1 和 #3),或者可以通过 JavaScript 动态实例化(示例 #2)。希望对某些人有所帮助。
历史
- 2012/4/20 - 初始帖子。