在做前端开发的时候,你是否有过想定制一些select选择列表的内容格式,今天介绍一个小插件tzSelect,可以自定义select选择列表的样式。由于该插件不支持最新的jQuery,天屹做了一些改进使其兼容最新的jQuery版本,并会详细的介绍这个插件的实现方法。
HTML结构
tzSelect是通过使用div和ul来替换默认的select来实现为select添加个性化样式的。所以在使用tzSelect的时候,需要用一些格式来使其正确的工作。
整个结构就是一个普通的select结构,需要注意的是option中的data-*属性,data-*是HTML5的新属性。
data-*为前端开发者提供自定义的属性,这些属性集可以通过对象的dataset属性获取,不支持该属性的浏览器可以通过getAttribute方法 获取。ppk提到过使用rel属性,lightbox库推广了rel属性,HTML5提供了data-做替代,这样可以更好地使用自定义的属性。需要注意的是,data-之后的以连字符分割的多个单词组成的属性,获取的时候使用驼峰风格。
点击查看HTML5 data-*属性介绍。得益于jQuery我们可以直接使用.data()方法来访问data-*属性,点击查看.data()使用方法。
- <!-- 我们将使用jQuery和CSS3创建新的div结构来替换下面的select结构-->
- <select class="customizedSelect">
- <!-- 定义 HTML5 data 属性 -->
- <option value="0" selected="selected" data-skip="1">选择产品</option>
- <option value="1" data-icon="img/products/iphone.png" data-html-text="iPhone 4<i>有货</i>">iPhone 4</option>
- <option value="2" data-icon="img/products/ipod.png" data-html-text="iPod <i>有货</i>">iPod</option>
- <option value="3" data-icon="img/products/air.png" data-html-text="MacBook Air<i>缺货</i>">MacBook Air</option>
- <option value="4" data-icon="img/products/imac.png" data-html-text="iMac Station<i>有货</i>">iMac Station</option>
- </select>
我们看一下第一个option项,data-skip=”1″表示不显示这个option到select的下拉列表里面,使这个option作为一个默认值显示。data-skip的值无关紧要只要有这个属性就ok了。剩下的其他的含有data-icon和data-html-text是用来提供新”option”需要的信息,文章js部分会介绍如何使用这些data-*属性。
CSS样式
CSS3支持为同一元素使用多个背景的功能,这样可以省去多个元素来定义背景,只是用一个div就达到我们想要的效果。
jQuery代码
插件实现思想,就是使用div和ul代替原有的select,首先找到原有的select,然后循环遍历option,用li替代。请看下面代码中的具体注释:
- (function ($) {
- $.fn.tzSelect = function (options) {
- options = $.extend({
- render: function (option) {
- return $('<li>'+option.text()+'</li>');
- },
- className: ''
- }, options);
- return this.each(function () {
- //将被替换的select
- var select = $(this);
- //新的div容器,用来显示被替换的select
- //<div class='selectBox'></div>用来存储当前选中的option值
- var selectBoxContainer = $("<div class='tzSelect'><div class='selectBox'></div></div>");
- selectBoxContainer.css({ width: select.width() });
- //用来存储原select中各个option选项
- var dropDown = $("<ul class='dropDown'></ul>");
- var selectBox = selectBoxContainer.find(".selectBox");
- //循环select中的内容,并用新的li替换以前的option
- if (options.className) {
- dropDown.addClass(options.className);
- }
- select.find("option").each(function (index, item) {
- var option = $(item);
- if (index == select.find(":selected").index()) {
- selectBox.html(option.text());
- }
- //使用data访问HTML5 data-*属性
- if (option.data("skip")) {
- return true;
- }
- // 使用li替换option
- // 读取data-icon 和 data-html-text HTML5 属性的值
- var li = options.render(option);
- li.click(function () {
- selectBox.html(option.text());
- dropDown.trigger("hide");
- //设定选中的值到<div class='selectBox'></div>
- select.val(option.val());
- return false;
- });
- dropDown.append(li);
- });
- selectBoxContainer.append(dropDown.hide());
- select.hide().after(selectBoxContainer);
- //绑定show,hide事件
- dropDown.bind("show", function () {
- if (dropDown.is(":animated")) {
- return false;
- }
- selectBox.addClass("expanded");
- dropDown.slideDown();
- }).bind("hide", function () {
- if (dropDown.is(":animated")) {
- return false;
- }
- selectBox.removeClass("expanded");
- dropDown.slideUp();
- }).bind("toggle", function () {
- if (selectBox.hasClass("expanded")) {
- dropDown.trigger("hide");
- }
- else dropDown.trigger("show");
- });
- selectBox.click(function () {
- dropDown.trigger("toggle");
- return false;
- });
- //当点击页面其他的地方,隐藏选择列表
- $(document).click(function () {
- dropDown.trigger("hide");
- });
- });
- }
- })(jQuery);