修复IE9下oninput事件(原生,jq)


IE9下虽然有oninput事件,但是这个input事件只是个半成品,它无法响应删除(Backspace,Del,右键菜单删除,右键菜单剪切)。

而且最奇葩的是 IE8下可以响应删除的propertychange事件,在IE9下也无法响应删除操作。

不过我们可以用onselectionchange这个事件来帮助修正这个BUG。

onselectionchange 触发的条件有很多,其中一个就是在可编辑的元素里使用删除命令时触发。

不过onselectionchange只能绑定在document上。

module.exports=function(node,callback){
	//先执行W3C
	if(document.addEventListener){
		node.addEventListener('input',callback,false)
		//IE9 使用 selectionchange fix
		if(document.documentMode==9){
			var selectionchange=function(){
				callback.call(node);
			}
			node.addEventListener('focus',function(){
				document.addEventListener('selectionchange',selectionchange,false);
			},false)
			node.addEventListener('blur',function(){
				document.removeEventListener('selectionchange',selectionchange,false);
			},false)
		}
	}
	//lte IE8
	else{
		node.attachEvent('onpropertychange',function(e){
			if(e.propertyName=='value'){
					callback.call(node);
			}
		})
	}
}
在页面中如下使用即可:

seajs.use('fix/input',function(oninput){
	var input =document.getElementById('input');
	oninput(input,function(){
		console.log(this.value);
	});
})


接下来,要在jquery中修正这个事件,以达到使用 .on('input',callback)  在IE8即以下下绑定propertychange事件,在IE9下修正input的BUG;

先上代码然后再解释~~。

var $=require('$');
var handle=(function(){
	if(!document.addEventListener){
		return function(e){
			if(e.originalEvent.propertyName=='value'){
				e.handleObj.handler.apply(this,arguments);
			}
		}
	}
})()
var bindType=(function(){
	if(window.addEventListener)return 'input';
	return 'propertychange';
})()
$.event.special['input']={
	bindType:bindType,
	setup:function(){
		if(document.documentMode==9){
			var input=this;
			$.event.add(this,'focus._input',function(){
				$.event.add(document,'selectionchange._input',function(){
					$.event.trigger('input','',input)
				});
			});
			$.event.add(this,'blur._input',function(){
				$.event.remove(document,'selectionchange._input');
			});
		}
		return false;
	},
	handle:handle
}
exports.inputFixed=true;
bindType接受一个字符串值,来决定真实绑定的事件名,这里使用一个立即执行的JS函数来根据浏览器返回input还是propertychange。

setup则是在事件绑定的时候触发,this指代当前元素,此处$.event.add换成$(this).on也是可以的。

handle则是在每次事件触发时都会执行的(前提handle是函数)。

这里并不知道handle要返回什么值才能让绑定的函数执行,所以使用了

e.handleObj.handler.apply(this,arguments);

使用时只需:

seajs.use(['fix/input-jq','$'],function(inputFix,$){
	$('#input').on('input',function(e){
		console.log(e)
	})
})



注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
  © 2014-2022 ITdaan.com 联系我们: