HTMLElement.EventsHTMLElement.prototypePublicUtils_HTMLElement.EventsProperties“HTMLElement.Events” MethodsdataChange()事件 : 标签数据(data)变更触发
// HTML:
<hello-world id="hello-world" text="hello"></hello-world>
// JS:
var helloWorld = document.getElementById('hello-world');
// 注册事件方法:
helloWorld.on('dataChange',function(ev,changes){
console.log(changes);
});
// 改变 "hello-text" 属性:
helloWorld['hello-text'] = 'world';
// 输出结果为:
{
'hello-text' : {
mode: "change",
value: "world",
oldValue: "hello"
}
}
find()事件 : 元素被第一次找到时候触发
(生命周期处于init事件前,但是已经合并完成默认数据、准备好了非依赖数据、以及注册好元素基本的Setter/Getter)
var helloWorld = document.getElementById('hello-world');
// 注册事件方法:
helloWorld.on('find',function(){
helloWorld['require'] = 'world';
});
// helloWorld.require 返回 world
init()事件 : 初始化完成触发
// HTML:
<hello-world id="hello-world" text="hello"></hello-world>
// JS:
var helloWorld = document.getElementById('hello-world');
// 注册事件方法:
helloWorld.on('init',function(ev,args){
console.log(args);
});
remove()事件 : 标签被移除前触发
(同时清理此DOM的attributesChange、styleReady事件)
var helloWorld = document.getElementById('hello-world');
// 注册事件方法:
helloWorld.on('remove', function (e,o) {
// 移除时候触发
console.log('[侦测到标签被移除]', o.dom.tagName, o.dom.attributes);
});
show()事件 : 标签显示时触发
(配合styleReady使用可参照showStyleReady语法糖)
// HTML:
<hello-world></hello-world>
// JS:
var helloWorld = document.getElementById('hello-world');
// 注册事件方法:
helloWorld.on('show',function(ev,args){
console.log(args);
});
styleReady事件 : 标签样式加载完成触发
(配合styleReady使用可参照showStyleReady语法糖)
// 需要在自定义标签控件CSS中加入以下片段用于触发,通常直接使用 `showStyleReady` 组合函数来控制显示及得到回调:
// tag-name[style-ready-trigger]{animation-duration:1ms;-webkit-animation-duration:1ms;animation-name:style-ready-trigger;-webkit-animation-name:style-ready-trigger;}
// (之所以要加入style-ready-trigger属性是因为不能够直接复写标签的动画标识,否则_tiggerTagInsert会因为样式动画名称被改写而失效。)
var helloWorld = document.getElementById('hello-world');
// 注册事件方法:
helloWorld.on('styleReady', function () {
// 样式加载完成后触发
});
“HTMLElement.prototype” MethodsaddEventListener(event, listener, capture)为原生DOM元素扩展绑定事件方法
为了兼容主流框架写法,listener 回调函数额外开放第二个参数为回传参数
on
dom.addEventListener('init',function(e,args){
console.info(e,args);
});
// 正常的获取trigger的回调参数推荐使用e.detail,如果需要使zepto等框架的on方法可以通过第二个参数正常获取回调参数,则可参考如下代码做兼容:
handler.proxy = function(e){
e = compatible(e)
if (e.isImmediatePropagationStopped()) return
e.data = data
// >> event.detail / e.detail compatibly
if(e._args == undefined && e.detail != undefined){
e._args = e.detail;
}
// << event.detail / e.detail compatibly
var result = callback.apply(element, e._args == undefined ? [e] : [e].concat(e._args))
if (result === false) e.preventDefault(), e.stopPropagation()
return result
}
default(defines)在DOM上定义默认数据,不具有覆写权限
<xxx id="test" foo="0"></xxx>
// 定义默认数据
var data = document.getElementById('target').default({
foo:1,
bar:2
});
// 输出结果为
data : { foo : 0, bar : 2 }
gets(keys)在DOM上批量获取数据
<xxx id="test" foo="1" bar="2"></xxx>
// 单个获取
var data = document.getElementById('target').gets('foo');
// 输出结果为
data : { foo : '1' }
// 强制定义模式
var data = document.getElementById('target').gets(['foo','bar']);
// 输出结果为
data : { foo : '1', bar : '2' }
observer(name, callback)扩展DOM侦测指定数据方法
<xxx id="test" foo="1" bar="2"></xxx>
var target = document.getElementById('target');
target.observer('foo',function(change){
console.log(change);
});
target['foo'] = 2;
register(aiTags)在某个元素中注册AI标签(如document.body)
var scope1 = document.getElementById('scope-1');
scope1.register({
'hello-world': {
js: 'examples/tags/hello-world.js'
}
});
var scope2 = document.getElementById('scope-2').register({
'hello-world': {
js: 'examples/tags/in-hello-world.js'
}
});
removeEventListener为原生DOM元素扩展移除绑定事件方法
off
dom.removeEventListener('init',function(e){
console.info(e);
});
sets(defines)在DOM上批量定义数据,具有覆写权限
<xxx id="test" foo="0"></xxx>
// 批量定义
var data = document.getElementById('target').sets({
foo:1,
bar:2
});
// 输出结果为
data : { foo : 1, bar : 2 }
“Public” Methodsradio(name, data)广播获取到的数据
HTML:
<hello-world require-data="::flag-value">...wait init...</hello-world>
JS:
require(['ai'], function (AI) {
AI.radio('::flag-value', {
data : {
foo : 'bar'
}
});
});
“Utils” Methods“_HTMLElement.Events” MethodsattributesChange()事件 : 标签属性变更触发
(此为私有事件,不建议监听,请使用change)
var helloWorld = document.getElementById('hello-world');
// 注册事件方法:
helloWorld.on('attributesChange', function (e, data) {
console.info(data);
});
// 改变class属性:
helloWorld.class = 'hello-new-world';
// 输出结果为:
{
'class' : {
mode: "change",
newValue: "hello-new-world",
oldValue: "hello-world"
}
}
// [!] 注意: 为了节省资源,如果不需要侦听属性变更请使用removeListener或off将其移除。
helloWorld.off('attributesChange');
Methods_defineGetterAndSetter(name)设置标签参数的 Getter / Setter thanks: http://robertnyman.com/javascript/javascript-getters-setters.html
_setCssObserver(args, args.key, args.callback, [args.selectors])[核心实现] 设置 CSS Observer 侦听机制
// 无论有无selectors,以下JS都将生成以下CSS片段并插入头部 :
// @keyframes style-ready-trigger {from{opacity:0;}to{opacity:0;}}
// @-webkit-keyframes style-ready-trigger {from{opacity:0;}to{opacity:0;}}
// 当以下样式开始对某个标签生效的时候,即会开始触发你绑定的callback方法,并能够在其中获取到当前正在作用的DOM。
// tag-name{
// animation-duration:1ms;
// -webkit-animation-duration:1ms;
// animation-name:style-ready-trigger;
// -webkit-animation-name:style-ready-trigger;
// }
//(适用于标签节点已存在于HTML,手动作用样式于标签,如在标签对应的CSS样式文件中携带该CSS,这里用于侦测styleReady的实现)
// 这里因为有传导 selectors 参数,所以额外将以下CSS也自动插入头部。
// hello-world,in-hello-world{animation-duration:1ms;-webkit-animation-duration:1ms;animation-name:style-ready;-webkit-animation-name:style-ready;}
//(适用于标签节点不存在于HTML,预先准备好样式等待标签进入自动触发回调,这里用于侦测tagInsert - auto init的实现)
_setCssObserver({
key : 'style-ready-trigger',
callback : function(args){
// 获取作用标签DOM
var dom = args.target;
// 触发自定义事件
dom.trigger('__your_custom_event');
},
selectors : 'hello-world,in-hello-world'
});
// 检查兼容性:
// http://caniuse.com/#feat=css-animation
// 感谢:
// http://davidwalsh.name/detect-node-insertion
// http://jsperf.com/css-nodeinserted-vs-mutation-nodeinserted
// http://pymaster.logdown.com/post/230263-simple-and-crude-detecting-elements-for-establishing