本文介绍如何利用HTML5的data-*属性与jQuery的data()方法,简化JS组件的初始化过程。通过封装jQuery插件,在页面加载时自动读取DOM元素上的自定义属性并传递给组件构造函数,从而避免重复编写初始化代码,实现声明式配置。
引言与背景
前言:近期在使用Bootstrap组件时,发现一个易用性痛点:许多简单组件的初始化需要在JavaScript中编写大量代码。例如,一个简单的select标签,若需从后台获取数据填充option,就必须通过JS初始化来请求数据。这导致页面初始化时JS代码中充斥着大量重复逻辑,显得冗余且难以维护。由此想到Bootstrap Table中使用的data属性机制,如果能在HTML中直接通过data-*形式初始化简单组件,将极大提升开发效率。我们先参考Bootstrap Table的文档:

从文档中可见,Bootstrap Table中几乎所有属性和事件均支持通过data-*形式配置,这种设计十分便捷。接下来我们将深入探讨其实现原理。data-*机制源自何处?
jQuery data()方法初探
一、jQuery data()方法初探
经过查阅资料,发现data-*机制源于jQuery和HTML5标准,这是一个非常实用的功能。首先回顾jQuery的API文档:
其原始用法如下:

该方法的用途明确,即为元素添加属性与数据,或读取这些值。
接下来探讨data()方法与HTML5 data-*属性的结合应用。

这一机制非常实用,通过HTML5的data-*设置的值,可以直接被jQuery的data()方法读取。其具体规则如下:
1)所有data属性必须以“data-”作为前缀;
2)属性名中的连字符“-”用于分隔单词;
3)在jQuery中获取属性值时,需去掉“data”前缀及连字符“-”。
基于此基础,我们明确了在标签中设置属性并在JS中读取对应值的方法。下面结合之前封装的combobox组件示例进行说明。
利用jQuery data()实现data-*初始化组件
二、利用jQuery data()实现data-*初始化组件
回顾之前“JS组件系列——封装自己的JS组件,你也可以”一文中封装的combobox组件,该组件支持通过url从后台获取数据。在此基础上,我们对其进行改造,实现在select标签中直接添加data-*属性来初始化下拉框组件。
1、JS组件封装代码
(function ($) {
//1.定义jquery的扩展方法combobox
$.fn.combobox = function (options, param) {
if (typeof options == 'string') {
return $.fn.combobox.methods[options](this, param);
}
//2.将调用时候传过来的参数和default参数合并
options = $.extend({}, $.fn.combobox.defaults, options || {});
//3.添加默认值
var target = $(this);
target.attr('valuefield', options.valueField);
target.attr('textfield', options.textField);
target.empty();
var option = $('<option></option>');
option.attr('value', '');
option.text(options.placeholder);
target.append(option);
//4.判断用户传过来的参数列表里面是否包含数据data数据集,如果包含,不用发ajax从后台取,否则否送ajax从后台取数据
if (options.data) {
init(target, options.data);
}
else {
//var param = {};
options.onBeforeLoad.call(target, options.param);
if (!options.url) return;
if (typeof options.param == "string"){
options.param = JSON.parse(options.param);
}
$.getJSON(options.url, options.param, function (data) {
init(target, data);
});
}
function init(target, data) {
$.each(data, function (i, item) {
var option = $('<option></option>');
option.attr('value', item[options.valueField]);
option.text(item[options.textField]);
target.append(option);
});
options.onLoadSuccess.call(target);
}
target.unbind("change");
target.on("change", function (e) {
if (options.onChange)
return options.onChange(target.val());
});
}
//5.如果传过来的是字符串,代表调用方法。
$.fn.combobox.methods = {
getValue: function (jq) {
return jq.val();
},
setValue: function (jq, param) {
jq.val(param);
},
load: function (jq, url) {
$.getJSON(url, function (data) {
jq.empty();
var option = $('<option></option>');
option.attr('value', '');
option.text('请选择');
jq.append(option);
$.each(data, function (i, item) {
var option = $('<option></option>');
option.attr('value', item[jq.attr('valuefield')]);
option.text(item[jq.attr('textfield')]);
jq.append(option);
});
});
}
};
//6.默认参数列表
$.fn.combobox.defaults = {
url: null,
param: null,
data: null,
valueField: 'value',
textField: 'text',
placeholder: '请选择',
onBeforeLoad: function (param) { },
onLoadSuccess: function () { },
onChange: function (value) { }
};
//这一段是新加的,在页面初始化完成之后调用初始化方法
$(document).ready(function () {
$('.combobox').each(function () {
var $combobox = $(this);
$.fn.combobox.call($combobox, $combobox.data());
})
});
})(jQuery);
大部分代码与上次无异,重点观察底部新增的代码段:
//这一段是新加的,在页面初始化完成之后调用初始化方法
$(document).ready(function () {
$('.combobox').each(function () {
var $combobox = $(this);
$.fn.combobox.call($combobox, $combobox.data());
})
});
显然,这是在页面初始化完成后,通过样式选择器来自动初始化组件。代码使用了each遍历,若存在多个.combobox样式的元素,将依次对每个元素进行初始化。通过$.fn.combobox.call($combobox, $combobox.data())调用call方法执行combobox的初始化逻辑,call方法的两个参数分别对应:
1)当前正在初始化的jQuery对象;
2)参数列表。此处通过$combobox.data()获取所有HTML中的data-*属性,并将这些属性作为参数传入combobox的初始化方法中。
2、在HTML中通过data-*进行初始化
<select id="Search_"
name="Search_province"
class="form-control combobox"
data-url="/Home/GetProvince"
data-param='{"type":"0"}'
data-text-field="Name"
data-value-field="Id">
</select>
指定data-*属性。由前述可知,初始化是通过样式选择器.combobox触发的,因此,若希望使用data-*进行组件初始化,必须为标签设置class="combobox",以便后台能识别需要初始化的标签。
3、后台C#方法
public class HomeController : Controller
{
public List<string> lstProvince = new List<string>() { "北京市", "天津市", "重庆市", "上海市", "河北省", "山西省", "辽宁省", "吉林省", "黑龙江省", "江苏省", "浙江省", "安徽省", "福建省", "江西省", "山东省", "河南省", "湖北省", "湖南省", "广东省", "海南省", "四川省", "贵州省", "云南省", "陕西省", "甘肃省", "青海省", "台湾省", "内蒙古自治区", "广西壮族自治区", "西藏自治区", "宁夏回族自治区", "新疆维吾尔自治区", "香港特别行政区", "澳门特别行政区" };
public JsonResult GetProvince(string type)
{
var lstRes = new List<Province>();
for (var i = 0; i < 10; i++)
{
var oModel = new Province();
oModel.Id = i;
oModel.Name = lstProvince[i];
lstRes.Add(oModel);
}
return Json(lstRes, JsonRequestBehavior.AllowGet);
}
}
public class Province
{
public int Id { get; set; }
public string Name { get; set; }
}
测试代码,此处无需过多解释。
4、调试效果展示


最终实现的效果如下:

至此,基本完成了通过data-*属性初始化组件的功能。
总结
三、总结
上述内容简要演示了jQuery data()方法结合HTML5 data-*属性的应用。这基本满足了博主的需求:无需额外编写JS代码即可直接初始化标签。使用时仅需引用jquery.js和jquery.extension.js文件即可。但需注意,既然这是HTML5的特性,对浏览器版本有一定要求。此外,该用法功能较为初级,但对于简单组件的初始化已足够使用。
文中若有理解不当之处,欢迎指正,博主将不胜感激。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。