表单元素之输入系
输入系的元素主要是说input[type=text],input[type=password],textarea这三种元素. 通常第一个输入用户名,第二个输入密码,第三个输入详细消息.
它们都表现为一个凹入的框框,里面可以让用户输入内容,不同的是输入域只能输入一条, 输入区可以输入多行,密码域使用圆点来遮掩用户的输入.
由于是一个框框,它就存在焦点获得与失去的时机, 还有输入法切换的时机, 于是衍生了一大堆事件.
首先是focus, blur事件, 其次是keydown, keyup, keypress事件, 然后是针对输入内容的监听事件, input是每添加或删除一个字符时触发, change是所有内容输入好,用户点击页面其他元素,让当前表单元素失去焦点时触发! 从IE9开始,添加了compositionstart,compositionupdate,compositionend用来监听用户切换输入法. 因此像中文,我们用五笔或拼音敲了好几下,才生成一个中文,没有这监听,我们恰恰好为元素添加了maxlength属性时,可能输入不了内容.
有关输入法监听事件的更详细的认识,可以看这篇文章《经验总结:应对中文输入法的字符串截断方案》
因此输入系表单元素主要纠缠在用什么事件上,前面几个事件还好办,难点是输入法监听事件,这个特别难兼容,目前我在facebook的react库中有发现兼容处理
但这个很难抽取出来,并且在各浏览器中的表现也不太好,详见这文章:
DOM COMPOSITION EVENTS COMPATIBILITY NOTES
那么剩下能处理的事件就是oninput。oninput也是IE9才支持的事件,在IE6-8中,拥有一个无敌能监听所有属性变动的事件onpropertychange事件。
if(!/null|function/(typeof el.oninput)){
el.attachEvent("onpropertychange", function(e){
if(e.propertyName === "value"){
//这里写input事件的罗辑
}
})
}
但这个也不完美,在avalon源码中,兼容input事件涉及更多东西, 大家可以用这个jquery插件实现相应的功能。
此外,输入系表单元素还有一个其他元素没有东西——光标
默认光标总在我们输入内容的后面,但等我们用程序直接对input.value赋值时,光标位置就会丢失。
function getCaret(ctrl) {
var start = NaN, end = NaN
if (ctrl.setSelectionRange) {
start = ctrl.selectionStart
end = ctrl.selectionEnd
} else if (document.selection && document.selection.createRange) {
var range = document.selection.createRange()
start = 0 - range.duplicate().moveStart('character', -100000)
end = start + range.text.length
}
return {
start: start,
end: end
}
}
function setCaret(ctrl, begin, end) {
if (!ctrl.value || ctrl.readOnly)
return
if (ctrl.createTextRange) {//IE6-8
var range = ctrl.createTextRange()
range.collapse(true)
range.moveStart("character", begin)
range.moveEnd('character', end - begin);
range.select()
} else {
ctrl.selectionStart = begin
ctrl.selectionEnd = Math.min(end, ctrl.value.length)
}
}
此外光标的高度可能也受字体影响,可以看这篇文章处理一下。
浙公网安备 33010602011771号