html-使用mas实现输入

我想为接受日期的文本/字段实现掩码。 被屏蔽的值应直接显示在-的内部。

像这样:

<input type='text' value='____/__/__'>

在该示例中,我将掩码写为值,但我的意图是允许人们写日期而不用键入/-来分隔月份,年份和日期。 用户应该能够在显示的字段中输入数字,而掩码会在用户键入时自动强制采用格式。

我已经在其他站点上看到了这种行为,但是我不知道它是如何工作的或者如何自己实现。

9个解决方案
37 votes

可以结合使用ISO Date: <input type="text" value="____-__-__" data-mask="____-__-__"/><br/> Telephone: <input type="text" value="(___) ___-____" data-mask="(___) ___-____"/><br/>事件和ISO Date: <input type="text" value="____-__-__" data-mask="____-__-__"/><br/> Telephone: <input type="text" value="(___) ___-____" data-mask="(___) ___-____"/><br/> ISO Date: <input type="text" value="____-__-__" data-mask="____-__-__"/><br/> Telephone: <input type="text" value="(___) ___-____" data-mask="(___) ___-____"/><br/>selectionStartselectionEnd属性来实现输入掩码。 这是一个非常简单的实现,可以完成您想要的一些事情。 它当然不是完美的,但是可以很好地演示该原理:

ISO Date: <input type="text" value="____-__-__" data-mask="____-__-__"/><br/>
Telephone: <input type="text" value="(___) ___-____" data-mask="(___) ___-____"/><br/>
ISO Date: <input type="text" value="____-__-__" data-mask="____-__-__"/><br/>
Telephone: <input type="text" value="(___) ___-____" data-mask="(___) ___-____"/><br/>

(在JSFiddle中查看)

还有许多执行此功能的库。 一些示例包括:

  • jquery.inputmask
  • 蒙版输入插件
  • 礼貌空间(表示输入蒙版的替代方法)
Ajedi32 answered 2020-02-14T09:24:14Z
20 votes

阅读所有文章后,我做了自己的实现,希望对某人有所帮助:

这个想法是

  1. 只允许输入数字。 (按键事件)
  2. 获取数组中的所有数字
  3. 将掩码中的每个“ _”字符替换为     循环数组

欢迎改进。

/**
 * charCode [48,57] 	Numbers 0 to 9
 * keyCode 46  			"delete"
 * keyCode 9  			"tab"
 * keyCode 13  			"enter"
 * keyCode 116 			"F5"
 * keyCode 8  			"backscape"
 * keyCode 37,38,39,40	Arrows
 * keyCode 10			(LF)
 */
function validate_int(myEvento) {
  if ((myEvento.charCode >= 48 && myEvento.charCode <= 57) || myEvento.keyCode == 9 || myEvento.keyCode == 10 || myEvento.keyCode == 13 || myEvento.keyCode == 8 || myEvento.keyCode == 116 || myEvento.keyCode == 46 || (myEvento.keyCode <= 40 && myEvento.keyCode >= 37)) {
    dato = true;
  } else {
    dato = false;
  }
  return dato;
}

function phone_number_mask() {
  var myMask = "(___) ___-____";
  var myCaja = document.getElementById("phone");
  var myText = "";
  var myNumbers = [];
  var myOutPut = ""
  var theLastPos = 1;
  myText = myCaja.value;
  //get numbers
  for (var i = 0; i < myText.length; i++) {
    if (!isNaN(myText.charAt(i)) && myText.charAt(i) != " ") {
      myNumbers.push(myText.charAt(i));
    }
  }
  //write over mask
  for (var j = 0; j < myMask.length; j++) {
    if (myMask.charAt(j) == "_") { //replace "_" by a number 
      if (myNumbers.length == 0)
        myOutPut = myOutPut + myMask.charAt(j);
      else {
        myOutPut = myOutPut + myNumbers.shift();
        theLastPos = j + 1; //set caret position
      }
    } else {
      myOutPut = myOutPut + myMask.charAt(j);
    }
  }
  document.getElementById("phone").value = myOutPut;
  document.getElementById("phone").setSelectionRange(theLastPos, theLastPos);
}

document.getElementById("phone").onkeypress = validate_int;
document.getElementById("phone").onkeyup = phone_number_mask;
<input type="text" name="phone" id="phone" placeholder="(123) 456-7890" required="required" title="e.g (123) 456-7890" pattern="^\([0-9]{3}\)\s[0-9]{3}-[0-9]{4}$">

Rodney Salcedo answered 2020-02-14T09:25:05Z
10 votes

您也可以使用JavaScript的本机方法来实现。 它非常简单,不需要导入任何额外的库。

<input type="text" name="date" placeholder="yyyy-mm-dd" onkeyup="
  var date = this.value;
  if (date.match(/^\d{4}$/) !== null) {
     this.value = date + '-';
  } else if (date.match(/^\d{4}\-\d{2}$/) !== null) {
     this.value = date + '-';
  }" maxlength="10">
shubhamkes answered 2020-02-14T09:25:26Z
4 votes

您也可以尝试我的实现,该实现在键入内容时每次按键后都没有延迟,并且完全支持退格和删除。

您可以在线尝试:[https://jsfiddle.net/qmyo6a1h/1/]

    <html>
    <style>
    input{
      font-family:'monospace';
    }
    </style>
    <body>
      <input type="text" id="phone" placeholder="123-5678-1234" title="123-5678-1234" input-mask="___-____-____">
      <input type="button" onClick="showValue_phone()" value="Show Value" />
      <input type="text" id="console_phone" />
      <script>
        function InputMask(element) {
          var self = this;

          self.element = element;

          self.mask = element.attributes["input-mask"].nodeValue;

          self.inputBuffer = "";

          self.cursorPosition = 0;

          self.bufferCursorPosition = 0;

          self.dataLength = getDataLength();

          function getDataLength() {
            var ret = 0;

            for (var i = 0; i < self.mask.length; i++) {
              if (self.mask.charAt(i) == "_") {
                ret++;
              }
            }

            return ret;
          }

          self.keyEventHandler = function (obj) {
            obj.preventDefault();

            self.updateBuffer(obj);
            self.manageCursor(obj);
            self.render();
            self.moveCursor();
          }

          self.updateBufferPosition = function () {
            var selectionStart = self.element.selectionStart;
            self.bufferCursorPosition = self.displayPosToBufferPos(selectionStart);
            console.log("self.bufferCursorPosition==" + self.bufferCursorPosition);
          }

          self.onClick = function () {
            self.updateBufferPosition();
          }

          self.updateBuffer = function (obj) {
            if (obj.keyCode == 8) {
              self.inputBuffer = self.inputBuffer.substring(0, self.bufferCursorPosition - 1) + self.inputBuffer.substring(self.bufferCursorPosition);
            }
            else if (obj.keyCode == 46) {
              self.inputBuffer = self.inputBuffer.substring(0, self.bufferCursorPosition) + self.inputBuffer.substring(self.bufferCursorPosition + 1);
            }
            else if (obj.keyCode >= 37 && obj.keyCode <= 40) {
              //do nothing on cursor keys.
            }
            else {
              var selectionStart = self.element.selectionStart;
              var bufferCursorPosition = self.displayPosToBufferPos(selectionStart);
              self.inputBuffer = self.inputBuffer.substring(0, bufferCursorPosition) + String.fromCharCode(obj.which) + self.inputBuffer.substring(bufferCursorPosition);
              if (self.inputBuffer.length > self.dataLength) {
                self.inputBuffer = self.inputBuffer.substring(0, self.dataLength);
              }
            }
          }

          self.manageCursor = function (obj) {
            console.log(obj.keyCode);
            if (obj.keyCode == 8) {
              self.bufferCursorPosition--;
            }
            else if (obj.keyCode == 46) {
              //do nothing on delete key.
            }
            else if (obj.keyCode >= 37 && obj.keyCode <= 40) {
              if (obj.keyCode == 37) {
                self.bufferCursorPosition--;
              }
              else if (obj.keyCode == 39) {
                self.bufferCursorPosition++;
              }
            }
            else {
              var bufferCursorPosition = self.displayPosToBufferPos(self.element.selectionStart);
              self.bufferCursorPosition = bufferCursorPosition + 1;
            }
          }

          self.setCursorByBuffer = function (bufferCursorPosition) {
            var displayCursorPos = self.bufferPosToDisplayPos(bufferCursorPosition);
            self.element.setSelectionRange(displayCursorPos, displayCursorPos);
          }

          self.moveCursor = function () {
            self.setCursorByBuffer(self.bufferCursorPosition);
          }

          self.render = function () {
            var bufferCopy = self.inputBuffer;
            var ret = {
              muskifiedValue: ""
            };

            var lastChar = 0;

            for (var i = 0; i < self.mask.length; i++) {
              if (self.mask.charAt(i) == "_" &&
                bufferCopy) {
                ret.muskifiedValue += bufferCopy.charAt(0);
                bufferCopy = bufferCopy.substr(1);
                lastChar = i;
              }
              else {
                ret.muskifiedValue += self.mask.charAt(i);
              }
            }

            self.element.value = ret.muskifiedValue;

          }

          self.preceedingMaskCharCount = function (displayCursorPos) {
            var lastCharIndex = 0;
            var ret = 0;

            for (var i = 0; i < self.element.value.length; i++) {
              if (self.element.value.charAt(i) == "_"
                || i > displayCursorPos - 1) {
                lastCharIndex = i;
                break;
              }
            }

            if (self.mask.charAt(lastCharIndex - 1) != "_") {
              var i = lastCharIndex - 1;
              while (self.mask.charAt(i) != "_") {
                i--;
                if (i < 0) break;
                ret++;
              }
            }

            return ret;
          }

          self.leadingMaskCharCount = function (displayIndex) {
            var ret = 0;

            for (var i = displayIndex; i >= 0; i--) {
              if (i >= self.mask.length) {
                continue;
              }
              if (self.mask.charAt(i) != "_") {
                ret++;
              }
            }

            return ret;
          }

          self.bufferPosToDisplayPos = function (bufferIndex) {
            var offset = 0;
            var indexInBuffer = 0;

            for (var i = 0; i < self.mask.length; i++) {
              if (indexInBuffer > bufferIndex) {
                break;
              }

              if (self.mask.charAt(i) != "_") {
                offset++;
                continue;
              }

              indexInBuffer++;
            }
            var ret = bufferIndex + offset;

            return ret;
          }

          self.displayPosToBufferPos = function (displayIndex) {
            var offset = 0;
            var indexInBuffer = 0;

            for (var i = 0; i < self.mask.length && i <= displayIndex; i++) {
              if (indexInBuffer >= self.inputBuffer.length) {
                break;
              }

              if (self.mask.charAt(i) != "_") {
                offset++;
                continue;
              }

              indexInBuffer++;
            }

            return displayIndex - offset;
          }

          self.getValue = function () {
            return this.inputBuffer;
          }
          self.element.onkeypress = self.keyEventHandler;
          self.element.onclick = self.onClick;
        }

        function InputMaskManager() {
          var self = this;

          self.instances = {};

          self.add = function (id) {
            var elem = document.getElementById(id);
            var maskInstance = new InputMask(elem);
            self.instances[id] = maskInstance;
          }

          self.getValue = function (id) {
            return self.instances[id].getValue();
          }

          document.onkeydown = function (obj) {
            if (obj.target.attributes["input-mask"]) {
              if (obj.keyCode == 8 ||
                obj.keyCode == 46 ||
                (obj.keyCode >= 37 && obj.keyCode <= 40)) {

                if (obj.keyCode == 8 || obj.keyCode == 46) {
                  obj.preventDefault();
                }

                //needs to broadcast to all instances here:
                var keys = Object.keys(self.instances);
                for (var i = 0; i < keys.length; i++) {
                  if (self.instances[keys[i]].element.id == obj.target.id) {
                    self.instances[keys[i]].keyEventHandler(obj);
                  }
                }
              }
            }
          }
        }

        //Initialize an instance of InputMaskManager and
        //add masker instances by passing in the DOM ids
        //of each HTML counterpart.
        var maskMgr = new InputMaskManager();
        maskMgr.add("phone");

        function showValue_phone() {
          //-------------------------------------------------------__Value_Here_____
          document.getElementById("console_phone").value = maskMgr.getValue("phone");
        }
      </script>
    </body>

    </html>
Cecilk Cao answered 2020-02-14T09:25:51Z
4 votes

一种响应<label>Date time: <input placeholder="dd/mm/yyyy hh:mm" data-slots="dmyh"> </label><br> <label>Telephone: <input placeholder="+1 (___) ___-____" data-slots="_"> </label><br> <label>MAC Address: <input placeholder="XX:XX:XX:XX:XX:XX" data-slots="X" data-accept="[\dA-H]"> </label><br> <label>Signed number (3 digits): <input placeholder="±___" data-slots="±_" data-accept="^[+-]|(?!^)\d" size="4"> </label><br> <label>Alphanumeric: <input placeholder="__-__-__-____" data-slots="_" data-accept="\w" size="13"> </label><br>事件而不是键事件(例如data-slots)的解决方案将提供流畅的体验(无摆动),并且在不使用键盘进行更改(上下文菜单,鼠标拖动,其他设备...)的情况下也可以使用。

下面的代码将查找同时具有<label>Date time: <input placeholder="dd/mm/yyyy hh:mm" data-slots="dmyh"> </label><br> <label>Telephone: <input placeholder="+1 (___) ___-____" data-slots="_"> </label><br> <label>MAC Address: <input placeholder="XX:XX:XX:XX:XX:XX" data-slots="X" data-accept="[\dA-H]"> </label><br> <label>Signed number (3 digits): <input placeholder="±___" data-slots="±_" data-accept="^[+-]|(?!^)\d" size="4"> </label><br> <label>Alphanumeric: <input placeholder="__-__-__-____" data-slots="_" data-accept="\w" size="13"> </label><br>属性和data-slots属性的输入元素。 后者应在占位符中定义用作输入槽的字符,例如“ _”。 可以为可选的data-accept属性提供一个正则表达式,该正则表达式定义在此类插槽中允许使用哪些字符。 默认值为\d,即数字。

<label>Date time: 
    <input placeholder="dd/mm/yyyy hh:mm" data-slots="dmyh">
</label><br>
<label>Telephone:
    <input placeholder="+1 (___) ___-____" data-slots="_">
</label><br>
<label>MAC Address:
    <input placeholder="XX:XX:XX:XX:XX:XX" data-slots="X" data-accept="[\dA-H]">
</label><br>
<label>Signed number (3 digits):
    <input placeholder="±___" data-slots="±_" data-accept="^[+-]|(?!^)\d" size="4">
</label><br>
<label>Alphanumeric:
    <input placeholder="__-__-__-____" data-slots="_" data-accept="\w" size="13">
</label><br>
<label>Date time: 
    <input placeholder="dd/mm/yyyy hh:mm" data-slots="dmyh">
</label><br>
<label>Telephone:
    <input placeholder="+1 (___) ___-____" data-slots="_">
</label><br>
<label>MAC Address:
    <input placeholder="XX:XX:XX:XX:XX:XX" data-slots="X" data-accept="[\dA-H]">
</label><br>
<label>Signed number (3 digits):
    <input placeholder="±___" data-slots="±_" data-accept="^[+-]|(?!^)\d" size="4">
</label><br>
<label>Alphanumeric:
    <input placeholder="__-__-__-____" data-slots="_" data-accept="\w" size="13">
</label><br>
<label>Date time: 
    <input placeholder="dd/mm/yyyy hh:mm" data-slots="dmyh">
</label><br>
<label>Telephone:
    <input placeholder="+1 (___) ___-____" data-slots="_">
</label><br>
<label>MAC Address:
    <input placeholder="XX:XX:XX:XX:XX:XX" data-slots="X" data-accept="[\dA-H]">
</label><br>
<label>Signed number (3 digits):
    <input placeholder="±___" data-slots="±_" data-accept="^[+-]|(?!^)\d" size="4">
</label><br>
<label>Alphanumeric:
    <input placeholder="__-__-__-____" data-slots="_" data-accept="\w" size="13">
</label><br>

trincot answered 2020-02-14T09:28:22Z
2 votes

我前一段时间写了一个类似的解决方案。
当然,这只是一个PoC,可以进一步改进。

该解决方案涵盖以下功能:

  • 无缝字符输入
  • 模式定制
  • 键入时进行实时验证
  • 全日期验证(包括每个月中的正确天数和对leap年的考虑)
  • 描述性错误,因此用户将在无法键入字符时了解发生了什么情况
  • 固定光标位置并防止选择
  • 如果值为空,则显示占位符

<input type="text" placeholder="DD/MM/YYYY" />
<div id="date-error-msg"></div>
<input type="text" placeholder="DD/MM/YYYY" />
<div id="date-error-msg"></div>

jsfiddle的链接:[https://jsfiddle.net/d1xbpw8f/56/]

祝好运!

Slavik Meltser answered 2020-02-14T09:32:09Z
-1 votes
Array.prototype.forEach.call(document.body.querySelectorAll("*[data-mask]"), applyDataMask);

function applyDataMask(field) {
    var mask = field.dataset.mask.split('');

    // For now, this just strips everything that's not a number
    function stripMask(maskedData) {
        function isDigit(char) {
            return /\d/.test(char);
        }
        return maskedData.split('').filter(isDigit);
    }

    // Replace `_` characters with characters from `data`
    function applyMask(data) {
        return mask.map(function(char) {
            if (char != '_') return char;
            if (data.length == 0) return char;
            return data.shift();
        }).join('')
    }

    function reapplyMask(data) {
        return applyMask(stripMask(data));
    }

    function changed() {   
        var oldStart = field.selectionStart;
        var oldEnd = field.selectionEnd;

        field.value = reapplyMask(field.value);

        field.selectionStart = oldStart;
        field.selectionEnd = oldEnd;
    }

    field.addEventListener('click', changed)
    field.addEventListener('keyup', changed)
}
Date: <input type="text" value="__-__-____" data-mask="__-__-____"/><br/>
Telephone: <input type="text" value="(___) ___-____" data-mask="(___) ___-____"/><br/>
Vishnu Kant answered 2020-02-14T09:32:26Z
-1 votes

下面我描述我的方法。 我在input的输入中设置了事件,以调用Masking()方法,该方法将返回我们在input中插入的格式化字符串。

HTML:

<input name="phone" pattern="+373 __ ___ ___" class="masked" required>

JQ:在这里,我们在输入上设置事件:

$('.masked').on('input', function () {
    var input = $(this);
    input.val(Masking(input.val(), input.attr('pattern')));
});

JS:函数,它将按模式格式化字符串;

function Masking (value, pattern) {
var out = '';
var space = ' ';
var any = '_';

for (var i = 0, j = 0; j < value.length; i++, j++) {
    if (value[j] === pattern[i]) {
        out += value[j];
    }
    else if(pattern[i] === any && value[j] !== space) {
        out += value[j];
    }
    else if(pattern[i] === space && value[j] !== space) {
        out += space;
        j--;
    }
    else if(pattern[i] !== any && pattern[i] !== space) {
        out += pattern[i];
        j--;
    }
}

return out;
}
Dumitru Boaghi answered 2020-02-14T09:32:59Z
-11 votes

使用此代码:-

<input type="text" placeholder="" data-mask="9999/99/99">

添加此脚本[https://github.com/RobinHerbots/Inputmask]

Sasan.R answered 2020-02-14T09:33:24Z
translate from https://stackoverflow.com:/questions/12578507/implement-an-input-with-a-mask