4

Есть такой скрипт, работает отлично, только при вводе не отображается маска телефона +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)

}) })

.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;
}


// сделать невидимым "+7"

.placeholder span:first-of-type {
   visibility: hidden;
}
<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>
Aleksandr
  • 840
  • Вроде работает ваш код. Вот, что я вижу. И это вполне подходит под маску +7 (___) ___ ____ Она начинает отображаться, когда в поле достаточно цифр. Или это и есть ваша проблема? – Стас Jul 25 '20 at 17:42
  • при клике появляется маска исчезает, а надо что бы постоянно было +7 (___) ___ ____ – Aleksandr Jul 25 '20 at 18:14
  • @Alexander не нужно копировать код предложенного решения в свой вопрос, Вы тем самым делаете ответ на него неактуальным – Vasily Aug 21 '20 at 19:20

1 Answers1

5

Один из вариантов решения данной задачи это сделать обертку для 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 &amp;&amp; (keyCode = event.keyCode)
  let pos = this.selectionStart
  if (pos &lt; 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 &lt; val.length ? val.charAt(i++) || def.charAt(i) : a
    })
  i = new_value.indexOf("_")
  if (i !== -1) {
    i &lt; 5 &amp;&amp; (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, "\\$&amp;")
  reg = new RegExp("^" + reg + "$")
  if (!reg.test(this.value) || this.value.length &lt; 5 || keyCode &gt; 47 &amp;&amp; keyCode &lt; 58) this.value = new_value
  if (event.type === "blur" &amp;&amp; this.value.length &lt; 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 по достижению заполнения каждого из фрагментов:

// сделать невидимым "+7"

.placeholder span:first-of-type { visibility: hidden; }

Vasily
  • 11,547
  • к сожалению не то, видно задача не выполнима, так как я лично перерыл много ресурсов, но ответа так и не нашел. Есть тяжелый плагин jQuery inputmask, но он тяжелы. – Aleksandr Jul 27 '20 at 14:32
  • 1
    при вводе цифр, маска остается в виде серой подложки под уже вбитыми цифрами. Согласен, что ничего невыполнимого нет, это делается через плагин вездесущего jQuery... – Aleksandr Jul 27 '20 at 14:36
  • @Alexander я же уже частично реализовал решение этого момента в своем примере. Вам только осталось добавить это в скрипт. Вы набираете часть номера и часть подложки выключается. – Vasily Jul 27 '20 at 14:39