当原生DOM事件无法满足开发需要时,可以通过jQuery的事件扩展机制来满足我们的需要。在jQuery.event.special域下添加自定义事件。
以textchange事件为例。该事件的定义为,在文本框中输入时,文本真正变化实时的获取文本改变的信号textchange。
先看实现代码:
///
(function(){
if(!jQuery || !$){
return;
}
var maybeTrigger = function($e){
if(!$e.data("ime")){
var value = ($e[0].contentEditable === "true"? $e.html(): $e.val());
if(value !== $e.data("lastValue")){
$e.trigger("textchange", [$e.data("lastValue")]);
$e.data("lastValue", value);
}
}
}
var imeStart = function(){
$(this).data("ime", true);
}
var imeEnd = function(){
$(this).data("ime", false);
}
var handler = function(){
maybeTrigger($(this));
}
var delayHandle = function(){
var $e = $(this);
setTimeout(function(){maybeTrigger($e)}, 25);
}
jQuery.event.special.textchange={
setup:function(data,namespace, eventHandle){
var $target = $(this);
$target.data("ime",false);
$target.data("lastValue",this.contentEditable==="true"? $target.html(): $target.val());
$target.bind("compositionstart.textchange", imeStart);
$target.bind("compositionend.textchange", imeEnd);
$target.bind("keyup.textchange", handler);
$target.bind("cut.textchange paste.textchange input.textchange", delayHandle);
},
teardown:function(namespaces){
$(this).unbind(".textchange");
}
}
})();
自定义事件处理整个过程分为两个步骤:
1.setup事件安装。明确一点,任何自定义事件都是通过组合原生的DOM事件和自定义数据得来。针对textchange事件:
a.数据上
a.1需要为其添加一个被比较的值lastvalue,用于和当前值进行比较,以确定是否触发信号;
a.2 需要一个监听输入法是否正处于输入状态的标记;
b.事件上,只要涉及到文本化的事件都要考虑进来
b.1 输入法开发,compositionstart
b.2 输入法结束,compositionend
b.3 按键弹起,keyup
b.4 剪切,cut
b.5 粘贴,paste
b.6 发生输入时,input
c 处理原则
c.1 处于输入法输入过程中,不触发
c.2 否则检查当前值和lastvalue,不一致时触发事件
2.teardown事件卸载。当该事件从DOM节点上卸载时,原生支撑它的那些事件应该移除。
注意一个小细节:compositionstart.textchange,jQuery的bind函数参数中,如果带”.”,则表示点后面为命名空间,当你把某些事件归为一类放到同一个命名空间,那么可以通过命名空间将该空间下所有的事件一次性卸载掉。
从互联网获取了太多东西,希望通过博客分享自己的东西,回馈互联网。如果有一天大家能都互相开源,互相分享经验,世界的发展将会加速多少,互联网的世界该是多么的美好啊。
PS:如果你发现我分享的东西存在错误,请一定留言告诉我,大家共同进步!