前言最近用Polymer封装了纯数字输入框。在开发过程中,发现不是坑,还有很多值得研究的地方。本系列将分为4篇来讲述这段史诗般的踩坑经历:[《动手写个数字输入框1:input[type=number]的遗憾》](http://www.cnblogs.com/fsjohn...《动手写个数字输入框2:起手式——拦截非法字符》《动手写个数字输入框3:痛点——输入法是个魔鬼》《动手写个数字输入框4:魔鬼在细节——打磨光标位置》IE的进阶性hardwork最后控制只能输入数字,但是只要用户启用了输入法,他就可以轻松突破我们的包围圈:-<心碎满地都是,这就是为什么我们会想有没有API可以禁用输入法?答案是肯定的,但奇怪的是,只有IE支持。value*normal:normalIMEstatus*active:激活本地语言输入法*inactive:激活非母语输入法*disabled:禁用IME*/ime-mode:disabled;}其他浏览器都是呵呵...没办法,只好补救~因为chrome、firefox等无法通过styleime-mode进行处理,所以想着照葫芦画瓢,同样在keydown事件中对具体的keyCode进行拦截过滤。谁知道在输入法中按下字符键时会发生keydown事件的keyCode始终为229,规则是:当按下字符键时,keydown中的keyCode始终为229,key为Undefined;并且在keyup中得到了正确的keyCode,key就是正确的字符。当按下enter和shift时只触发keydown不会触发keyup,keyCode为229。因此,我们能做的就是将keyup事件作为事后补救措施;在keydown中拦截输入法中输入的enter和shift键事件,然后触发keyup事件进行补救。废话少说,上代码!constkeyCode=anyPass(prop('keyCode'),prop('which'))constisBackspace=eq(8),isDelete=eq(46),isArrowLeft=eq(37),isArrowRight=eq(38)isArrowUp=eq(39)isArrowDown=eq(40)isTab=eq(9)isHome=eq(36)isEnd=eq(35)constisValidStr=precision=>a=>RegExp("^[+-]?[0-9]*"+(精度?"(\\.[0-9]{0,"+精度+"})?":"")+"$")。test(a)//获取min,max,precision值constlensTarget=lens(a=>a.target||a.srcElement),lensMin=lens(a=>Number(a.min)||Number(attr(a,'min'))||Number.MIN_SAFE_INTEGER),lensMax=lens(a=>Number(a.max)||Number(attr(a,'max'))||Number.MAX_SAFE_INTEGER),lensPrecision=lens(a=>Number(a.precision)||Number(attr(a,'precision'))||0),lensValue=lens(a=>a.value,(o,v)=>o.value=v),lensDataValue=镜头(a=>a&&a.getAttribute('数据值'),(a,v)=>a&&a.setAttribute('数据值',v))constlensTargetMin=lcomp(lensTarget,lensMin),lensTargetMax=lcomp(lensTarget,lensMax),lensTargetPrecision=lcomp(lensTarget,lensPrecision),lensTargetValue=lcomp(lensTarget,lensValue)constisIME=eq(229)constisValidChar=c=>/[-+0-9.]/.test(c)constinvalid2Empty=c=>isValidChar(c)?c:''constrecoverValue=v=>flatMap(CharSequence(v),invalid2Empty)//是否激活IMEconstisInIME=comp(isIME,keyCode)//是否为功能键,isFnKey=comp(anyPass(isArrowLeft),isArrowRight,isArrowUp,isArrowDown,isBackspace,isDelete,isHome,isEnd),keyCode)$('input[type=text]').addEventListener('keydown',e=>{varel=视图(lensTarget)(e),val=view(lensTargetValue)(e)//暂存value值,如果keyup有问题,可以恢复出厂设置set(lensDataValue)(el)(val)if(isInIME(e)){fireKeyup(el)}})$('输入[类型=文本]').addEventListener('keyup',e=>{if(isFnKey(e))returnvarel=view(lensTarget)(e),v=view(lensValue)(el),p=view(lensTargetPrecision)(e),isValid=isValidStr(p),max=view(lensMax)(el),min=view(lensMin)(el)varval=recoverValue(v)varsetVal=set(lensValue)(el)if(isValid(val)){if(val!==v){setVal(val)}else{varn=Number(v)if(!gte(max)(n)){setVal(max)}if(!lte(min)(n)){setVal(min)}}}else{setVal(attr(el,'data-value'))}})附录:工具函数//工具函数,请忽略我:Dconstcomp=(...fns)=>(...args)=>{让len=fns.长度while(len--){args=[fns[len].应用(null,args)]}返回参数。长度>1?参数:参数[0]}constisSome=x=>'undefined'!==typeofx&&x!==nullconstinvokerImpl=n=>o=>m=>(...args)=>{让args4m=args.splice(0,n),次=Number(args[0])||1、ret=[]while(times--){vartmpRettry{tmpRet=o[m].apply(o,args4m)}catch(e){tmpRet=void0}ret.push(tmpRet)}returnret.length>1?ret:ret[0]}constcurry2Partial=fn=>(...args)=>{让c=true,i=0,l=args.length,f=fn对于(;c&&i
