最近公司项目的需求上要求我们iPad项目上一些需要输入数字的地方用我们自定义的软键盘而不是移动端设备自带的键盘,刚接到需求有点懵,因为之前没有做过,后来理了一下思路发现这东西也就那样。先看一下实现之后的效果:
实现的效果就是当点击页面中需要弹出软键盘的时候软键盘弹出,浮在页面的中间,和模态框一样的效果,可以在软键盘中输入任何数字,附带的功能有小数点、退格、清空、确定等功能。当在键盘上点击数字的时候页面中的表单中实时的添加对应的数字,上图中可以看到。
产品经理那边给的原因是iPad屏幕本来就小,如果软键盘弹出的话会占用一半的屏幕,影响产品的美观,无奈只能想办法搞定。
自定义的软键盘使用angularJS的directive的自定义指令来做到的,angularJS的directive这里不做解释,如果不清楚的话可以去angular官网看看。用的是自定义一个属性(restrict:'A'),这样封装过之后在需要用到软键盘的时候只需要在<input>中加入自定义的属性即可调出软键盘,使用起来非常简单,自定义的directive如下:
angular.module('ng-calculator', []).directive('calculator', ['$compile',function($compile) { return { restrict : 'A', replace : true, transclude : true, template:'<input/>', link : function(scope, element, attrs) { var keylist=[1,2,3,4,5,6,7,8,9,0,'.']; var calculator = '<div><div></div>' +'<div>' +'<div>'+attrs.title+'</div><div>' +'<input type="text" ng-tap="getInput()" ng-model="' +attrs.ngModel+'">' +'</div><div>' +'<div>'; $.each(keylist,function(k,v){ calculator += '<div value="'+v+'">'+v+'</div>'; }); calculator += '</div>' +'<div>' +'<div></div>' +'<div>清空</div>' +'<div>确<br>定</div>' +'</div>' +'</div>' +'</div>' +'</div>'; calculator = $compile(calculator)(scope); element.bind('focus',function(){ document.body.appendChild(calculator[0]); document.activeElement.blur(); }); $(calculator[0]).find("input").focus(function(){ document.activeElement.blur(); }); //关闭模态框 $(calculator[0]).find(".close").click(function(){ calculator[0].remove(); var callback = attrs.callback; if(typeof callback!="undefined"){ scope[callback](); } }); $(calculator[0]).find(".bg").click(function(){ calculator[0].remove(); }); //退格 $(calculator[0]).find(".backstep").click(function(){ if(typeof $(calculator[0]).find("input").val()=="undefined"){ $(calculator[0]).find("input").val(""); } $(calculator[0]).find("input").val($(calculator[0]).find("input").val().substring(0,$(calculator[0]).find("input").val().length-1)).trigger('change'); }); //清空 $(calculator[0]).find(".cleanup").click(function(){ $(calculator[0]).find("input").val("").trigger('change'); }); //点击数字 $(calculator[0]).find(".num").click(function(){ var val = $(calculator[0]).find("input").val(); var filter = attrs.filter; if(typeof filter!="undefined"){ val = scope[filter](val,$(this).attr("value")); }else{ val = val+''+$(this).attr("value"); } $(calculator[0]).find("input").val(val).trigger('change'); }); //确认 $(calculator[0]).find(".ensure").click(function(){ calculator[0].remove(); var callback = attrs.callback; if(typeof callback!="undefined"){ scope[callback](); } }); //点击效果 $(calculator[0]).find(".keyboard").click(function(){ $(this).addClass("keydown"); var that = this; setTimeout(function(){ $(that).removeClass("keydown"); },100) }); var position = { startX:0, startY:0 }; calculator[0].getElementsByClassName("title")[0].addEventListener('touchstart', function(e) { e.preventDefault(); var transform = $(calculator[0]).find(".calculator").css("transform").match(/translate\((.*),(.*)\)/); if(transform==null){ position.startX = e.targetTouches[0].clientX; position.startY = e.targetTouches[0].clientY; }else{ position.startX = e.targetTouches[0].clientX-parseInt(transform[1]); position.startY = e.targetTouches[0].clientY-parseInt(transform[2]); } }, false); calculator[0].getElementsByClassName("title")[0].addEventListener('touchmove', function(e) { e.preventDefault(); var moveX = e.targetTouches[0].clientX-position.startX; var moveY = e.targetTouches[0].clientY-position.startY; $(calculator[0]).find(".calculator").css("transform","translate("+moveX+"px,"+moveY+"px)"); }, false); } }; }]);
dom中调用如下:
<input type="text" placeholder="按价格搜索" ng-model="spaAndHairSeaInPrice" title="按价格搜索" calculator>
可以看到只是定义了一个 calculator 属性,然后在dom中只需要加入 calculator 即可使用软键盘。
我的软键盘亮点:
1、calculator 调用的时候表单获取焦点,有人会问移动端设备在获取到焦点的时候会弹出软键盘,那岂不是会出来两个键盘呢?实际不然,directive中对此做了处理:
即在获取到焦点的同事失去焦点,这样就能完美的避免设备自带的键盘。