zoukankan      html  css  js  c++  java
  • angularjs 用directive做一个 类似于maxlength的属性,支持汉字作为3个长度

    index.html

    <!doctype html>
    <html lang="en" ng-app="phonecatApp">
      <head>
        <meta charset="utf-8">
        <title>Google Phone Gallery</title>
        <link rel="stylesheet" href="lib/bootstrap/dist/css/bootstrap.css" />
        <link rel="stylesheet" href="app.css" />
        <script src="lib/angular/angular.js"></script>
        <script src="app.js"></script>
      </head>
      <body ng-controller="PhoneListController">
    
        <ul>
          <li ng-repeat="phone in phones">
            <span>{{phone.name}}</span>
            <p>{{phone.snippet}}</p>
          </li>
        </ul>
    
        <input type="text" maxlength="5">
        <input type="text" maxlengthCn="10">
        <input type="text" inputCn="100">
        <div my-customer></div>
      </body>
    </html>
    

    app.js, 直接移步版本A++

    'use strict';
    
    // Define the `phonecatApp` module
    var phonecatApp = angular.module('phonecatApp', []);
    
    // Define the `PhoneListController` controller on the `phonecatApp` module
    phonecatApp.controller('PhoneListController', function PhoneListController($scope) {
    }).directive('maxlengthcnTest', function() {//版本A
      return {//控制中英文混合输入的长度(一个中文字符算作三个);实现:控制maxlength属性。
              //在有可能输入中文的时候,提前控制长度。中文输入时、ctrl v时
              //中文输入后按enter或shift时取消控制
        restrict: 'A',//只在作为属性时有效
        // template: 'Name: {{customer.name}} Address: {{customer.address}}',
        link: function (scope, element, attr) {
          console.log("cnLength: " + attr.maxlengthcn);
          var totalLength = parseInt(attr.maxlengthcn);
          var opElement = element[0];
          opElement.maxLength = totalLength;
          element.on('input', function () {
            if (opElement.comStart) return;
            // inputEvt(opElement);
            increaseLength(opElement);
          }).on('compositionstart', function () {//中文输入开始
            decreaseLength(opElement);//假设输入的都是中文,剩余长度除以3
            opElement.comStart = true;
            console.log("CN start");
          }).on('compositionupdate', function () {
            console.log("CN compositionupdate");
          }).on('compositionend', function () {//中文输入结束
            opElement.comStart = false;
            console.log("CN end");
            increaseLength(opElement);
          }).on('keyup', function (event) {
            if (event.which == 86)  {//ctrl v
              // inputEvt(opElement);
              console.log("ctrl v");
              // window.clipboardData.getData ("Text");
              return;
            }
            console.log(event.which);
            if (opElement.comStart) {//中文输入后按enter
              if (event.which == 13)  {
                increaseLength(opElement);
                console.log("enter");
              } else if (event.which == 16)  {//中文输入后按shift
                increaseLength(opElement);
                console.log("shift");
              }
            }
          });
    
          var inputEvt = function (element) {
            if (element.comStart) return;    // 中文输入过程中不截断
            console.log("length: " + element.maxLength);
            element.maxLength = 5;
            console.log("text: " + element.value);
          };
          //剩余长度除3
          var decreaseLength = function (opElement) {
            var valueLen = validateTextLength(opElement.value);
            opElement.maxLength = opElement.value.length + (totalLength - valueLen) / 3;
            console.log("len: " + opElement.maxLength);
          };
          //剩余长度恢复
          var increaseLength = function (opElement) {
            var valueLen = validateTextLength(opElement.value);
            opElement.maxLength = totalLength - valueLen + opElement.value.length;
            console.log("len: " + opElement.maxLength);
          };
    
          var validateTextLength = function (value) {
            // 中文、中文标点、全角字符按3长度,英文、英文符号、数字按1长度计算
            let cnReg = /([u4e00-u9fa5]|[u3000-u303F]|[uFF00-uFF60])/g
            let mat = value.match(cnReg)
            let length;
            if (mat) {
              length = (mat.length * 3 + (value.length - mat.length))
              return length;
            } else {
              return value.length;
            }
          };
        }
      };
    }).directive('inputcn', function() {//测试用
      return {
        restrict: 'A',//只在作为属性时有效
        // template: 'Name: {{customer.name}} Address: {{customer.address}}',
        link: function (scope, element, attr) {
          var opElement = element[0];
          let str = "123";
          element.on('input', function () {
            //IE浏览器
            if (document.selection) {
              opElement.focus();
              var sel = document.selection.createRange();
              sel.text = str;
              sel.select();
            }     //火狐/网景 浏览器
            else if (opElement.selectionStart || opElement.selectionStart == '0')
            {
              //得到光标前的位置
              var startPos = opElement.selectionStart;
              //得到光标后的位置
              var endPos = opElement.selectionEnd;
              // 在加入数据之前获得滚动条的高度
              var restoreTop = opElement.scrollTop;
              opElement.value = opElement.value.substring(0, startPos) + str + opElement.value.substring(endPos, opElement.value.length);
              //如果滚动条高度大于0
              if (restoreTop > 0) {
                // 返回
                opElement.scrollTop = restoreTop;
              }
              opElement.focus();
              opElement.selectionStart = startPos + str.length;
              opElement.selectionEnd = startPos + str.length;
            }
            else {
              opElement.value += str;
              opElement.focus();
            }
          });
          
        }
      };
    }).directive('maxlengthcnIE', function() {//版本A+   最终版    问题:chrome中使用超长时会出现覆盖掉后面的字符的问题
                                            //测试环境: ie11   chrome84
      return {//控制中英文混合输入的长度(一个中文字符算作三个);实现:控制maxlength属性,
              // 并且在有效输入(中、英、粘贴)后校验长度,并更正。
        restrict: 'A',//只在作为属性时有效
        link: function (scope, element, attr) {
          console.log("cnLength: " + attr.maxlengthcn);
          if (parseFloat(attr.maxlengthcn).toString() == "NaN") return;
          var totalLength = parseInt(attr.maxlengthcn);
          var opElement = element[0];
          opElement.maxLength = totalLength;
          element.on('input', function () {
            console.log("input: " + opElement.value);
            if (opElement.comStart) return;// 中文输入过程中不处理
            inputEvt(opElement);
          }).on('compositionstart', function () {//中文输入开始
            opElement.comStart = true;
            console.log("CN start");
          }).on('compositionend', function () {//中文输入结束
            opElement.comStart = false;
            console.log("CN end");
            inputEvt(opElement);//解决chrome执行顺序问题(compositionstart -- input -- compositionend)
          });
    
          var inputEvt = function (element) {
            var valueLen = validateTextLength(opElement.value);
            if (valueLen > totalLength) {
              console.log("too long");
              var diffLen = valueLen - totalLength;
              //得到光标的位置
              var startPos = opElement.selectionStart;
              console.log("cursor pos: " + startPos);
              var sumLen = 0;
              let i = startPos - 1;
              for (; i >= 0; i--) {
                sumLen += validateTextLength(opElement.value.charAt(i));
                if (sumLen >= diffLen) break;
              }
              console.log("last cursor pos: " + i);
              //剪去多的字符
              opElement.value = opElement.value.substring(0, i) + opElement.value.substring(startPos);
              opElement.focus();
              opElement.selectionStart = i;
              opElement.selectionEnd = i;
              valueLen -= sumLen;
            }
            if (totalLength >= valueLen) opElement.maxLength = totalLength - valueLen + opElement.value.length;
            console.log("length: " + element.maxLength);
          };
    
          //得到字符长度
          var validateTextLength = function (value) {
            // 中文、中文标点、全角字符按3长度,英文、英文符号、数字按1长度计算
            let cnReg = /([u4e00-u9fa5]|[u3000-u303F]|[uFF00-uFF60])/g
            let mat = value.match(cnReg)
            let length;
            if (mat) {
              length = (mat.length * 3 + (value.length - mat.length))
              return length;
            } else {
              return value.length;
            }
          };
        }
      };
    }).directive('maxlengthcn', function() {//版本A++   最终版    放弃使用maxlength, 直接判断长度,删除光标前边的字符
                                            //测试环境: ie11   chrome84
      return {//控制中英文混合输入的长度(一个中文字符算作三个);
        restrict: 'A',//只在作为属性时有效
        link: function (scope, element, attr) {
          console.log("cnLength: " + attr.maxlengthcn);
          if (parseFloat(attr.maxlengthcn).toString() == "NaN") return;
          var totalLength = parseInt(attr.maxlengthcn);
          var opElement = element[0];
          element.on('input', function () {
            console.log("input: " + opElement.value);
            if (opElement.comStart) return;// 中文输入过程中不处理
            inputEvt(opElement);
          }).on('compositionstart', function () {//中文输入开始
            opElement.comStart = true;
            console.log("CN start");
          }).on('compositionend', function () {//中文输入结束
            opElement.comStart = false;
            console.log("CN end");
            inputEvt(opElement);//解决chrome执行顺序问题(compositionstart -- input -- compositionend)
          });
    
          var inputEvt = function (element) {
            var valueLen = validateTextLength(opElement.value);
            if (valueLen > totalLength) {
              console.log("too long");
              var diffLen = valueLen - totalLength;
              //得到光标的位置
              var startPos = opElement.selectionStart;
              console.log("cursor pos: " + startPos);
              var sumLen = 0;
              let i = startPos - 1;
              for (; i >= 0; i--) {
                sumLen += validateTextLength(opElement.value.charAt(i));
                if (sumLen >= diffLen) break;
              }
              console.log("last cursor pos: " + i);
              //剪去多的字符
              opElement.value = opElement.value.substring(0, i) + opElement.value.substring(startPos);
              opElement.focus();
              opElement.selectionStart = i;
              opElement.selectionEnd = i;
              valueLen -= sumLen;
            }
          };
    
          //得到字符长度
          var validateTextLength = function (value) {
            // 中文、中文标点、全角字符按3长度,英文、英文符号、数字按1长度计算
            let cnReg = /([u4e00-u9fa5]|[u3000-u303F]|[uFF00-uFF60])/g
            let mat = value.match(cnReg)
            let length;
            if (mat) {
              length = (mat.length * 3 + (value.length - mat.length))
              return length;
            } else {
              return value.length;
            }
          };
        }
      };
    });
    
    
  • 相关阅读:
    RF简介
    ADB & FASTBOOT COMMAND ON WINDOWS
    通过Mac电脑安装apk 和 ipa到安卓和苹果手机
    Mac搭建移动端自动化环境遇到的node安装失败的坑与解决方法
    Git 连接pycharm
    Appium环境搭建和命令
    穿戴设备(智能手表)移动端测试浅谈1
    IOS UIImageView的contentMode属性
    IOS OC数据类型
    IOS textField(textview)字数判断
  • 原文地址:https://www.cnblogs.com/so-easy/p/13568917.html
Copyright © 2011-2022 走看看