先看下 Layui 文档的描述,比如监听选项卡切换这一节:
Tab 选项卡点击切换时触发,回调函数返回一个 object 参数,携带两个成员:
element.on('tab(filter)', function(data){
console.log(this); //当前 Tab 标题所在的原始 DOM 元素
console.log(data.index); //得到当前 Tab 的所在下标
console.log(data.elem); //得到当前的 Tab 大容器
});
疑问在于:
如果我们用比较原始的方法来监听 Tab 选项卡点击切换时触发,可能是这样写:
eleTab.addEventListener("click", function(event) {
// 点击 Tab 选项卡时触发该函数
})
可以看到与 Layui 的写法从外观形式上就有很大的差别。
Layui 做了哪些封装呢?Layui 上面的写法并没有看到它监听 click 事件啊,为啥在点击 Tab 选项卡时会触发?
我觉得可能是与以下源码有关,但看不出重点。
element.js
https://github.com/sentsin/layui/blob/master/src/lay/modules/element.js#L29
Element.prototype.on = function(events, callback){
return layui.onevent.call(this, MOD_NAME, events, callback);
};
layui.js https://github.com/sentsin/layui/blob/743d498816651899a339d6e88210f6513f2b61d1/src/layui.js#L563
//自定义模块事件
Layui.prototype.onevent = function(modName, events, callback){
if(typeof modName !== 'string'
|| typeof callback !== 'function') return this;
return Layui.event(modName, events, null, callback);
};
//执行自定义模块事件
Layui.prototype.event = Layui.event = function(modName, events, params, fn){
var that = this
,result = null
,filter = (events || '').match(/\((.*)\)$/)||[] //提取事件过滤器字符结构,如:select(xxx)
,eventName = (modName + '.'+ events).replace(filter[0], '') //获取事件名称,如:form.select
,filterName = filter[1] || '' //获取过滤器名称,,如:xxx
,callback = function(_, item){
var res = item && item.call(that, params);
res === false && result === null && (result = false);
};
//如果参数传入特定字符,则执行移除事件
if(params === 'LAYUI-EVENT-REMOVE'){
delete (that.cache.event[eventName] || {})[filterName];
return that;
}
//添加事件
if(fn){
config.event[eventName] = config.event[eventName] || {};
//这里不再对多次事件监听做支持,避免更多麻烦
//config.event[eventName][filterName] ? config.event[eventName][filterName].push(fn) :
config.event[eventName][filterName] = [fn];
return this;
}
//执行事件回调
layui.each(config.event[eventName], function(key, item){
//执行当前模块的全部事件
if(filterName === '{*}'){
layui.each(item, callback);
return;
}
//执行指定事件
key === '' && layui.each(item, callback);
(filterName && key === filterName) && layui.each(item, callback);
});
return result;
};
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.