angularjs利用directive实现移动端自定义软键盘的示例


Posted in Javascript onSeptember 20, 2017

最近公司项目的需求上要求我们iPad项目上一些需要输入数字的地方用我们自定义的软键盘而不是移动端设备自带的键盘,刚接到需求有点懵,因为之前没有做过,后来理了一下思路发现这东西也就那样。先看一下实现之后的效果:

angularjs利用directive实现移动端自定义软键盘的示例

实现的效果就是当点击页面中需要弹出软键盘的时候软键盘弹出,浮在页面的中间,和模态框一样的效果,可以在软键盘中输入任何数字,附带的功能有小数点、退格、清空、确定等功能。当在键盘上点击数字的时候页面中的表单中实时的添加对应的数字,上图中可以看到。

产品经理那边给的原因是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 class="ngcalculator_area"><div class="bg"></div>'
        +'<div class="calculator">'
        +'<div class="title close">'+attrs.title+'</div><div class="inputarea">'
        +'<input type="text" id="text" ng-tap="getInput()" class="'+attrs.class+'" ng-model="' +attrs.ngModel+'">'
        +'</div><div class="con">'
        +'<div class="left">';
      $.each(keylist,function(k,v){
        calculator += '<div class="keyboard num" value="'+v+'">'+v+'</div>';
      });

      calculator += '</div>'
        +'<div class="right">'
        +'<div class="keyboard blueIcon backstep"></div>'
        +'<div class="keyboard blueIcon cleanup">清空</div>'
        +'<div class="keyboard ensure ensure">确<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中对此做了处理:

angularjs利用directive实现移动端自定义软键盘的示例

即在获取到焦点的同事失去焦点,这样就能完美的避免设备自带的键盘。

2、数字键盘中的数据和页面的表单中的数据实时联动起来是通过ng-model实现的,在获取焦点的时候directive中会获取到ng-model的值并赋给页面中的表单,这样就能实现数据联动起来,让软键盘更加完美,可参考第一张图。

3、为了让软键盘点击的时候更加逼真,在自定义的directive中对按钮元素进行了处理,当点击按钮的时候给当前被点击的元素添加一个class,效果带阴影效果的按钮往下移动了几像素,看起来有点击的效果,产品和UI没有给我这个需求,是我自己自由发挥的,哈哈。

angularjs利用directive实现移动端自定义软键盘的示例

4、在项目中用到自定义的这个软键盘的时候有些需要在点击键盘的确定按钮之后需要进行一些数据处理,于是后来在directive的确定安妮中中加了一个回调,我们可以在点击确定之后调用这个回调,可以达到确定数字之后紧接着自动去执行需要执行的事件。只需要在dom中加上callback="functionItem()"即可。

angularjs利用directive实现移动端自定义软键盘的示例

当然如果是英文字母的话也可以用这种方法,只需要在初始的数组中写上英文字母布局排好即可,异曲同工而已。

以上是我写的简单的移动端数字键盘,希望对看到的人有所帮助。

如果有不足的地方还望指正大家相互交流,如果有更好的方法也请告诉我一下,作为一只程序猿,我要码无止境的优化我的代码。

以上这篇angularjs利用directive实现移动端自定义软键盘的示例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js实现C#的StringBuilder效果完整实例
Dec 22 Javascript
极力推荐一款小巧玲珑的可视化编辑器bootstrap-wysiwyg
May 27 Javascript
AngularJS基础 ng-model-options 指令简单示例
Aug 02 Javascript
easyui-combobox 实现简单的自动补全功能示例
Nov 08 Javascript
jQuery插件MovingBoxes实现左右滑动中间放大图片效果
Feb 28 Javascript
基于Jquery Ajax type的4种类型(详解)
Aug 02 jQuery
JS图片延迟加载插件LazyImgv1.0用法分析【附demo源码下载】
Sep 04 Javascript
redux-saga 初识和使用
Mar 10 Javascript
JS实现TITLE悬停长久显示效果完整示例
Feb 11 Javascript
详解JavaScript 的执行机制
Sep 18 Javascript
如何实现vue的tree组件
Dec 03 Vue.js
vuex的使用和简易实现
Jan 07 Vue.js
集合Bootstrap自定义confirm提示效果
Sep 19 #Javascript
微信小程序使用Socket的实例
Sep 19 #Javascript
vue基于Element构建自定义树的示例代码
Sep 19 #Javascript
Vue2.0父组件与子组件之间的事件发射与接收实例代码
Sep 19 #Javascript
详解ES6之async+await 同步/异步方案
Sep 19 #Javascript
jQuery实现倒计时功能 jQuery实现计时器功能
Sep 19 #jQuery
jquery实现倒计时小应用
Sep 19 #jQuery
You might like
PHP获取浏览器信息类和客户端地理位置的2个方法
2014/04/24 PHP
php操作xml入门之cdata区段
2015/01/23 PHP
WordPress中登陆后关闭登陆页面及设置用户不可见栏目
2015/12/31 PHP
PHP与Ajax相结合实现登录验证小Demo
2016/03/16 PHP
浅谈PHP表单提交(POST&amp;GET&amp;URL编/解码)
2017/04/03 PHP
ThinkPHP like模糊查询,like多匹配查询,between查询,in查询,一般查询书写方法
2018/09/26 PHP
用CSS+JS实现的进度条效果效果
2007/06/05 Javascript
深入理解JavaScript系列(43):设计模式之状态模式详解
2015/03/04 Javascript
jquery图片滚动放大代码分享(1)
2015/08/25 Javascript
Nodejs如何搭建Web服务器
2016/03/28 NodeJs
Node.js 应用跑得更快 10 个技巧
2016/04/03 Javascript
微信小程序 wxapp地图 map详解
2016/10/31 Javascript
jQuery实现Select下拉列表进行状态选择功能
2017/03/30 jQuery
Easyui使用Dialog行内按钮布局的实例
2017/07/27 Javascript
浅谈ES6新增的数组方法和对象
2017/08/08 Javascript
深入理解vue-router之keep-alive
2017/08/31 Javascript
React组件重构之嵌套+继承及高阶组件详解
2018/07/19 Javascript
vscode中vue-cli项目es-lint的配置方法
2018/07/30 Javascript
vuejs前后端数据交互之从后端请求数据的实例
2018/08/11 Javascript
JavaScript模拟实现自由落体效果
2018/08/28 Javascript
vue自定义switch开关组件,实现样式可自行更改
2019/11/01 Javascript
[48:38]DOTA2亚洲邀请赛 3.31 小组赛 B组 Mineski vs Secret
2018/03/31 DOTA
python递归计算N!的方法
2015/05/05 Python
在Python的Django框架中显示对象子集的方法
2015/07/21 Python
Python ftp上传文件
2016/02/13 Python
Linux中安装Python的交互式解释器IPython的教程
2016/06/13 Python
安装python时MySQLdb报错的问题描述及解决方法
2018/03/20 Python
Python3 批量扫描端口的例子
2019/07/25 Python
python微信公众号开发简单流程实现
2020/03/09 Python
《陈涉世家》教学反思
2014/04/12 职场文书
2014年科研工作总结
2014/12/03 职场文书
观后感格式
2015/06/19 职场文书
德能勤绩工作总结
2015/08/11 职场文书
高考要来啦!用Python爬取历年高考数据并分析
2021/06/03 Python
Java输出Hello World完美过程解析
2021/06/13 Java/Android
详细聊聊关于Mysql联合查询的那些事儿
2021/10/24 MySQL