Как исправить инпут маску при вводе номера телефона?

Есть такой скрипт, работает отлично, только при вводе не отображается маска телефона +7 (___) ___ ____

window.addEventListener("DOMContentLoaded", function() {
  let callFormTel = document.querySelectorAll('.js-phoneMask');

  Array.prototype.forEach.call(callFormTel, function(input) {
    let keyCode;

    function mask(event) {
      event.keyCode && (keyCode = event.keyCode);
      let pos = this.selectionStart;
      if (pos < 3) event.preventDefault();
      let matrix = "+7 (___) ___ ____",
        i = 0,
        def = matrix.replace(/\D/g, ""),
        val = this.value.replace(/\D/g, ""),
        new_value = matrix.replace(/[_\d]/g, function(a) {
          return i < val.length ? val.charAt(i++) || def.charAt(i) : a
        });
      i = new_value.indexOf("_");
      if (i !== -1) {
        i < 5 && (i = 3);
        new_value = new_value.slice(0, i)
      }
      let reg = matrix.substr(0, this.value.length).replace(/_+/g,
        function(a) {
          return "\\d{1," + a.length + "}"
        }).replace(/[+()]/g, "\\$&");
      reg = new RegExp("^" + reg + "$");
      if (!reg.test(this.value) || this.value.length < 5 || keyCode > 47 && keyCode < 58) this.value = new_value;
      if (event.type === "blur" && this.value.length < 5) this.value = ""
    }

    input.addEventListener("input", mask, false);
    input.addEventListener("focus", mask, false);
    input.addEventListener("blur", mask, false);
    input.addEventListener("keydown", mask, false)
  });
});
<input type="tel" name="phone" class="js-phoneMask" autocomplete="off" placeholder="+7 (___) ___ ____" required>


Ответы (1 шт):

Автор решения: Vasily

Один из вариантов решения данной задачи это сделать обертку для input, указав для нее относительную позицию и добавить еще один элемент, который будет размещаться поверх данного input'a и отображать требуемый placeholder.

Быстрый набросок что бы передать основную идею:

window.addEventListener("DOMContentLoaded", function() {
  let callFormTel = document.querySelectorAll(".js-phoneMask")

  Array.prototype.forEach.call(callFormTel, function(input) {
    let keyCode

    function mask(event) {
      event.keyCode && (keyCode = event.keyCode)
      let pos = this.selectionStart
      if (pos < 3) event.preventDefault()
      let matrix = "+7 (___) ___ ____",
        i = 0,
        def = matrix.replace(/\D/g, ""),
        val = this.value.replace(/\D/g, ""),
        new_value = matrix.replace(/[_\d]/g, function(a) {
          return i < val.length ? val.charAt(i++) || def.charAt(i) : a
        })
      i = new_value.indexOf("_")
      if (i !== -1) {
        i < 5 && (i = 3)
        new_value = new_value.slice(0, i)
      }
      let reg = matrix.substr(0, this.value.length).replace(/_+/g,
        function(a) {
          return "\\d{1," + a.length + "}"
        }).replace(/[+()]/g, "\\$&")
      reg = new RegExp("^" + reg + "$")
      if (!reg.test(this.value) || this.value.length < 5 || keyCode > 47 && keyCode < 58) this.value = new_value
      if (event.type === "blur" && this.value.length < 5) this.value = ""
    }

    input.addEventListener("input", mask, false)
    input.addEventListener("focus", mask, false)
    input.addEventListener("blur", mask, false)
    input.addEventListener("keydown", mask, false)
  })
})
.wrapper {
  position: relative;
  font-size: 14px;
}

.wrapper > input {
  background-color: transparent;
  padding: 4px;
}

.wrapper > .placeholder {
  position: absolute;
  left: 0;
  font-size: inherit;
  color: #d8d8d8;
  padding: 7px;
  z-index: -1;
}
<div class="wrapper">
  <input type="tel" name="phone" class="js-phoneMask" autocomplete="off" required>
  <span class="placeholder"><span>+7 </span><span>(___) </span>___<span> ____</span></span>
<div>

Так же можно отключать видимость span'ов внутри класса .placeholder по достижению заполнения каждого из фрагментов.

→ Ссылка