【问题标题】:Animating the labels on input focus with CSS and JavaScript使用 CSS 和 JavaScript 对输入焦点上的标签进行动画处理
【发布时间】:2020-08-16 09:41:49
【问题描述】:

我有几个输入字段,我希望它们的标签按比例缩小并在焦点上滑动到顶部。我已经设法使用 CSS 和 JavaScript 实现了这一点,但它只会为页面上的第一个标签设置动画。

下面的代码 JS 使用“querySelector”来定位标签。我也尝试过使用“getElementsByClassName”和“querySelectorAll”。当我只关注一个输入字段时,它会为页面上的所有标签设置动画。

我只想为附加到输入的标签设置动画。对此的任何帮助将不胜感激。

document.addEventListener("change", function(event) {

  if (event.target && event.target.matches(".js_form-input")) {

    event.preventDefault();

    var inputField = event.target;
    var inputLabels = document.querySelector(".label-span");

    if (inputField.value) {
      inputLabels.style.top = "-1.5rem";
    } else {
      inputLabels.style.top = "0rem";
    }
  }
});
.input {
  width: 100%;
  border: 0;
  border-bottom: solid 1px grey;
  padding-left: 1rem;
  margin-bottom: 2rem;
  color: $c_pop;
  padding-bottom: 0.7rem;
}

.input-label {
  position: relative;
}

.label-span {
  position: absolute;
  top: 0;
  left: 1rem;
  transition: all 0.2s;
}

.input-label {
  font-size: 0.9rem;
}

.input:focus+.label-span {
  top: -1.5rem;
  left: 0.5rem;
  font-size: 0.7rem;
}
<div class="input-container">
  <label class="input-label" for="#">
    <input class="input js_form-input" type="text">
    <span class="label-span">First Name</span>
  </label>
</div>

<div class="input-container">
  <label class="input-label" for="#">
    <input class="input js_form-input" type="text">
    <span class="label-span">Surname</span>
  </label>
</div>

<div class="input-container">
  <label class="input-label" for="#">
    <input class="input js_form-input" type="text">
    <span class="label-span">Email</span>
  </label>
</div>

这个JS方法我也试过了:

var inputField = event.target;
        var inputLabels = document.querySelectorAll(".label-span");
    
         [].slice.call(inputLabels).forEach(function(label){
          if (inputField.value) {
            label.style.top = "-1.5rem";
           } else {
            label.style.top = "0rem";
           }
       });

【问题讨论】:

  • 你做得很完美,但在 css 中,你没有正确定义类名。在 css 中使用点 (.) 和所有类名,我认为不需要任何 javascript。删除您的 JavaScript 代码。我希望,它会解决你的问题。
  • 这是在这里编辑问题时的拼写错误。我已经纠正了。问题依然存在。
  • @KumarGaurav javascript 需要在任何输入失去焦点并且其值不是空字符串时保持标签。
  • @Yousaf 不一定,不用 JS 也能达到同样的效果。你可以看到我的第二种方法。如果我错过了任何极端情况,请告诉我。
  • @KumarGaurav 使用required 属性和:valid 选择器将不起作用,例如,如果您有一个有效密码包含至少8 个字符的密码输入字段。在这种情况下,如果你在input元素上指定minlength="8",那么如果用户输入了例如5个字符,当输入失去焦点时标签将向下移动。

标签: javascript html css


【解决方案1】:

您的 CSS 足以获得您想要的效果,只需删除 javascript。我修复的唯一问题是将pointer-events: none; 添加到.label-span 元素,因为它们在单击它们时会阻塞焦点。

进行了编辑,包括检查输入是否为空的模糊,如果已满则保持标签位置。

const inputs = document.querySelectorAll('.js_form-input');

inputs.forEach(input => {
    input.addEventListener('blur', (event) => {
    if (event.target.value.length) {
        event.target.classList.add("full");
    } else {
        event.target.classList.remove("full");
    }
});
})
#container {
  padding: 2rem 0;
}

.input {
  width: 100%;
  border: 0;
  border-bottom: solid 1px grey;
  padding-left: 1rem;
  margin-bottom: 2rem;
  color: $c_pop;
  padding-bottom: 0.7rem;
}

.input-label {
  position: relative;
}

.label-span {
  position: absolute;
  top: 0;
  left: 1rem;
  transition: all 0.2s;
  pointer-events: none;
}

.input-label {
  font-size: 0.9rem;
}

.input:focus+.label-span, .input.full+.label-span {
  top: -1.5rem;
  left: 0.5rem;
  font-size: 0.7rem;
}
<div id="container">
  <div class="input-container">
    <label class="input-label" for="#">
      <input class="input js_form-input" type="text">
      <span class="label-span">First Name</span>
    </label>
  </div>

  <div class="input-container">
    <label class="input-label" for="#">
      <input class="input js_form-input" type="text">
      <span class="label-span">Surname</span>
    </label>
  </div>

  <div class="input-container">
    <label class="input-label" for="#">
      <input class="input js_form-input" type="text">
      <span class="label-span">Email</span>
    </label>
  </div>
</div>

【讨论】:

  • 感谢您的宝贵时间,但这不是完美的解决方案。如果您专注于输入,则标签会生成动画。但是,当您在输入中输入内容并聚焦时,标签会动画回到原来的位置并覆盖输入字段的值。
  • 太真实了@rockymalpo,编辑了我的答案以包括值检查。
【解决方案2】:

希望,这能解决您的问题。

var myform = document.querySelectorAll(".input-label");

        Array.from(myform).map(x => {
            x.addEventListener('change', (e) => {
                var el = e.target.parentNode.children[1];
                if (e.target.value !== "") {
                    el.style.top = "-1.5rem";
                } else {
                    el.style.top = "0rem";
                }
            });
        });
* {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: Arial, Helvetica, sans-serif;
        }

        .input-container {
            padding: 20px;
        }

        .input {
            width: 100%;
            border: 0;
            border-bottom: solid 1px grey;
            padding-left: 1rem;
            margin-bottom: 2rem;
            color: #000;
            padding-bottom: 0.7rem;
        }

        .input-label {
            position: relative;
        }

        .label-span {
            position: absolute;
            top: 0;
            left: 1rem;
            transition: all 0.2s;
        }

        .input-label {
            font-size: 0.9rem;
        }

        .input:focus+.label-span {
            top: -1.5rem;
            left: 0.5rem;
            font-size: 0.7rem;
        }
<div class="input-container">
            <label class="input-label" for="#">
                <input class="input js_form-input" type="text" />
                <span class="label-span">First Name</span>
            </label>
        </div>

        <div class="input-container">
            <label class="input-label" for="#">
                <input class="input js_form-input" type="text" />
                <span class="label-span">Surname</span>
            </label>
        </div>

        <div class="input-container">
            <label class="input-label" for="#">
                <input class="input js_form-input" type="text" />
                <span class="label-span">Email</span>
            </label>
        </div>

【讨论】:

    【解决方案3】:

    另一个无需 Javascript 也能达到相同结果的技巧。

    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
      font-family: sans-serif;
    }
    .input-container {
      padding: 20px;
    }
    .input {
      width: 100%;
      border: 0;
      border-bottom: solid 1px grey;
      padding-left: 1rem;
      margin-bottom: 2rem;
      color: #000;
      padding-bottom: 0.7rem;
    }
    
    .input-label {
      position: relative;
    }
    
    .label-span {
      position: absolute;
      top: 0;
      left: 1rem;
      transition: all 0.2s;
    }
    
    .input-label {
      font-size: 0.9rem;
    }
    
    .input:focus + .label-span,
    .input:valid + .label-span {
      top: -1.5rem;
      left: 0.5rem;
      font-size: 0.9rem;
    }
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>Document</title>
      </head>
      <body>
        <div class="input-container">
          <label class="input-label" for="#">
            <input class="input js_form-input" type="text" required />
            <span class="label-span">First Name</span>
          </label>
        </div>
    
        <div class="input-container">
          <label class="input-label" for="#">
            <input class="input js_form-input" type="text" required/>
            <span class="label-span">Surname</span>
          </label>
        </div>
    
        <div class="input-container">
          <label class="input-label" for="#">
            <input class="input js_form-input" type="text" required/>
            <span class="label-span">Email</span>
          </label>
        </div>
      </body>
    </html>

    【讨论】:

    • 我同意这是一个简洁的纯 CSS 解决方案,但它将验证功能与与验证无关的显示问题混淆了。 (如果字段中有文本,无论该文本是否对特定字段有效,标签都应保持向上。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-13
    • 1970-01-01
    • 2021-11-16
    • 2013-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多