【问题标题】:Convert this jQuery snippet to vanilla javascript (focus not working)将此 jQuery 片段转换为 vanilla javascript(焦点不起作用)
【发布时间】:2017-01-14 11:08:32
【问题描述】:

我正在尝试将此 jQuery sn-p 转换为原生 JavaScript,但我似乎遇到了 focusblur 事件的问题。

我似乎无法让我的回调函数在这些事件上执行。

为什么 jQuery sn-p 可以工作而不是我的?

HTML 片段

form(class="form js-form" method="post" action="/contact")
  div.row
    div.col-sm-12
      div.form__group.js-form-group
        label(class="form__label js-form-label" for="name") Name
        input(class="form__input js-form-input" type="text" name="name" id="name" placeholder="Name" required)

  div.row
    div.col-sm-12
      div.form__group.js-form-group
        label(class="form__label js-form-label" for="email") Email
        input(class="form__input js-form-input" type="email" name="email" id="email" placeholder="Email" required)
  div.row
    div.col-sm-6
      div.form__group.js-form-group
        label(class="form__label js-form-label" for="occasion") Occasion
        input(class="form__input js-form-input" type="text" name="occasion" id="occasion" placeholder="Occasion" required)
    div.col-sm-6
      div.form__group.js-form-group
        label(class="form__label js-form-label" for="date") Date
        input(class="form__input js-form-input" type="date" name="date" id="date" placeholder="Date" required)
  div.row
   div.col-sm-12
     div.form__group.js-form-group
       label(class="form__label js-form-label" for="message")
       textarea(class="form__textarea js-form-input" name="message" id="message" placeholder="Message" required)
  div.row
    div.col-sm-12
      button.pull-right(class="form__submit js-form-submit" type="submit") Submit

jQuery 片段

$(function() {
  $(".js-form").on("input propertychange", ".js-form-group", function(e) {
    $(this).toggleClass("has-value", !!$(e.target).val());
    console.log(this);
  }).on("focus", ".js-form-group", function() {
    $(this).addClass("focused");
    console.log('focus');
  }).on("blur", ".js-form-group", function() {
    $(this).removeClass("focused");
    console.log("blur");
  });

});

无效的原版片段

var formFloatingLabels = (function() {
  var formSelector = 'js-form',
    formGroupSelector = 'js-form-group',
    form = document.getElementsByClassName(formSelector)[0], 
    formGroup = null,
    focusedClass = 'focused',
    hasValueClass = 'has-value';

  if (!form) {
    return;
  }

  formGroup = form.getElementsByClassName(formGroupSelector);



  function init() {
    bindFormGroupEventListeners();
  }

  function toggleHasValueClass() {
    this.classList.toggle(hasValueClass);
  }

  function addFocusedClass() {
    console.log('focused');
  }

  function removeFocusedClass() {
    console.log('blurred');
  }

  function bindFormGroupEventListeners() {
    var currentFormGroup = null;
    for (var i = 0; i < formGroup.length; i++) {
      currentFormGroup = formGroup[i];

      currentFormGroup.addEventListener('input', toggleHasValueClass);
      currentFormGroup.addEventListener('focus', addFocusedClass);
      currentFormGroup.addEventListener('blur', removeFocusedClass);


    }
  }

  return {
    init: init
  }
})();

formFloatingLabels.init();

【问题讨论】:

  • 我认为焦点不是通过添加类来实现的。它是元素focus() 的方法。 developer.mozilla.org/en/docs/Web/API/HTMLElement/focus
  • @MirkoVukušić - 'focused' 类是我自己制作的 css 类。然而,这永远不会被添加,因为 addEventListener('focus'...) 永远不会被触发。我的问题是为什么?

标签: javascript jquery html revealing-module-pattern


【解决方案1】:

我不知道为什么 jQuery 代码可以工作。

'focus' 和 'blur' 是原生 &lt;input&gt; 事件。

要使您的代码正常工作,请将formGroupSelector = 'js-form-group', 更改为formGroupSelector = 'js-form-input', 或将输入标记更改为具有js-form-group 的类。

这是您在 jsbin 中的代码的一个小的工作副本:

https://jsbin.com/wiwori/2/edit?html,js,console,output

顺便说一句,放弃 jQuery 做得很好,学习 javascript 的好方法。

更新

我确实知道 jQuery 的工作原理。 http://api.jquery.com/on/

大多数浏览器事件从文档中最深、最里面的元素(事件目标)开始冒泡或传播,一直到正文和文档元素。在 Internet Explorer 8 及更低版本中,一些事件(例如更改和提交)本身不会冒泡,但 jQuery 将这些事件修补为冒泡并创建一致的跨浏览器行为。

focus 和 blur 事件由 W3C 指定为不冒泡,但 jQuery 定义了跨浏览器的 focusin 和 focusout 事件会冒泡。当 focus 和 blur 用于附加委托事件处理程序时,jQuery 映射名称并将它们分别作为 focusin 和 focusout 传递。为保持一致性和清晰性,请使用冒泡事件类型名称。

简单地说,因为你使用 'on' jQuery 将焦点事件冒泡到 div,这不是本机浏览器行为。

【讨论】:

  • 这很奇怪——我不确定 jQuery 还做了什么来实现这一点
  • 真的不确定,连jquery指南都说:“这个事件隐式适用于有限的一组元素,比如表单元素(
  • 啊,我明白了 - 因为这是委托的,并且 jquery 有自己的 pollyfill?
【解决方案2】:

使用

$(function () { //... })

效果和使用一样:

$(document).ready(function () { //... })

jQuery sn-p 等待DOMContentLoaded 事件。你的没有。这可能只是问题的原因。尝试将最后一行替换为:

document.addEventListener('DOMContentLoaded', formFloatingLabels.init, false);

【讨论】:

    【解决方案3】:

    为了让focusblur 处理非输入类型元素,它们必须有一个tabindex。

    如果你给一个元素一个tabindex,当它被点击时你会收到一个焦点事件。

    【讨论】:

      猜你喜欢
      • 2021-09-25
      • 2021-03-11
      • 2014-02-26
      • 2021-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-26
      • 2021-06-24
      相关资源
      最近更新 更多