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 相关文章推荐
让ie6也支持websocket采用flash封装实现
Feb 18 Javascript
JS+CSS实现实用的单击输入框弹出选择框的方法
Feb 28 Javascript
jQuery视差滚动效果网页实现方法经验总结
Sep 29 Javascript
javascript另类方法实现htmlencode()与htmldecode()函数实例分析
Nov 17 Javascript
详解从买域名到使用pm2部署node.js项目全过程
Mar 07 Javascript
使用vue2实现购物车和地址选配功能
Mar 29 Javascript
vue iview实现动态路由和权限验证功能
Apr 17 Javascript
vuejs实现ready函数加载完之后执行某个函数的方法
Aug 31 Javascript
angularJs自定义过滤器实现手机号信息隐藏的方法
Oct 08 Javascript
使用vue-cli3+typescript的项目模板创建工程的教程
Feb 28 Javascript
vue操作dom元素的3种方法示例
Sep 20 Javascript
vue实现一个矩形标记区域(rectangle marker)的方法
Oct 28 Javascript
集合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伪造referer突破网盘禁止外连的代码
2008/06/15 PHP
php数组函数序列之array_unique() - 去除数组中重复的元素值
2011/10/29 PHP
laravel5表单唯一验证的实例代码
2019/09/30 PHP
jquery 入门教程 [翻译] 推荐
2009/08/17 Javascript
JavaScript中使用构造器创建对象无需new的情况说明
2012/03/01 Javascript
JS弹出层单纯的绝对定位居中示例代码
2014/02/18 Javascript
JS实现判断滚动条滚到页面底部并执行事件的方法
2014/12/18 Javascript
js动态生成Html元素实现Post操作(createElement)
2015/09/14 Javascript
微信小程序 Video API实例详解
2016/10/02 Javascript
JavaScript基本类型值-Undefined、Null、Boolean
2017/02/23 Javascript
nodejs multer实现文件上传与下载
2017/05/10 NodeJs
浅谈Vue SSR 的 Cookies 问题
2017/11/20 Javascript
解决vue keep-alive 数据更新的问题
2018/09/21 Javascript
vue百度地图 + 定位的详解
2019/05/13 Javascript
JS实现网页时钟特效
2020/03/25 Javascript
JavaScript前端开发时数值运算的小技巧
2020/07/28 Javascript
如何在vue中使用百度地图添加自定义覆盖物(水波纹)
2020/11/03 Javascript
[24:42]VP vs TNC Supermajor小组赛B组 BO3 第三场 6.2
2018/06/03 DOTA
王纯业的Python学习笔记 下载
2007/02/10 Python
用python实现的去除win下文本文件头部BOM的代码
2013/02/10 Python
使用Python对SQLite数据库操作
2017/04/06 Python
使用Python监视指定目录下文件变更的方法
2018/10/15 Python
Django安装配置mysql的方法步骤
2018/10/15 Python
Python3模拟curl发送post请求操作示例
2019/05/03 Python
python使用sklearn实现决策树的方法示例
2019/09/12 Python
如何使用css3实现一个类在线直播的队列动画的示例代码
2020/06/17 HTML / CSS
Ann Taylor官方网站:美国最大的女性产品制造商之一
2016/09/14 全球购物
英国最大的纸工艺品商店:CraftStash
2018/12/01 全球购物
阿里巴巴的Oracle DBA笔试题答案-SQL tuning类
2016/04/03 面试题
自主招生自荐信指南
2014/02/04 职场文书
团日活动总结书格式
2014/05/08 职场文书
另类冲刺标语
2014/06/24 职场文书
大学生简历求职信
2014/06/24 职场文书
《巨人的花园》教学反思
2016/02/19 职场文书
感谢信的技巧及范例
2019/05/15 职场文书
Apache SkyWalking 监控 MySQL Server 实战解析
2022/09/23 Servers