Materialise CSS 双重自动对焦

Materialize CSS double autofocus

我有一个 Rails 5 应用程序 turbolinks + Materialize css 通过 gem

我在输入 "double autofocus" 时有奇怪的行为:

   <div class="form-input input-field">
      <i class="material-icons prefix">email</i>
      <%= f.email_field :email, autofocus: true, class: "validate" %>
      <label for="user_email">Email</label>
    </div>

当我第一次访问页面时 - 没关系。但是当我第二次来到那里时,我有双重自动对焦。我想,它可以与 turbolinks 连接,但我不确定。

为了更好地理解观看视频,请: https://www.youtube.com/watch?v=aEzTjFniqsY

为什么会这样,我该如何解决?

重新访问页面时,Turbolinks 将显示该页面的 "preview"(如果它的缓存中有该页面的某个版本)。然后它从服务器加载一个新页面并替换预览。因此,您看到的是该字段集中在预览上,然后在加载新副本时重新集中。 (有一种观点认为 Turbolinks 不应在预览中自动聚焦某个字段,但这里有一些可能的解决方案。)

选择退出预览

Turbolinks 提供了一种自定义缓存行为的方法。通过将以下元标记添加到页面的头部,Turbolinks 将不会显示预览并防止闪烁:

<meta name="turbolinks-cache-control" content="no-preview">

(您可以使用 content_for/yield 助手或通过在视图中设置实例变量将其添加到单个页面。)

这样做的缺点是页面加载的感知速度可能会变慢,因为它不会立即从缓存中恢复。

从预览中删除 autofocus

另一种保持预览的方法是在缓存页面之前删除 autofocus 属性。这意味着预览的表单不会自动聚焦:

$(document).on('turbolinks:before-cache', function () {
  $('[autofocus]').removeAttr('autofocus')
})

这种方法的缺点是,如果用户通过 back/forward 按钮访问页面,该字段将不会获得焦点。

CSS 解决方案

如果以上都不令人满意,那么您可能想要覆盖 CSS。过渡到聚焦样式的物化 CSS 闪烁更加明显。 因此,一种选择是覆盖这些样式以删除过渡

另一种可能性是 "fake" 预览中的非焦点字段样式。 Turbolinks 为预览添加了一个 data-turbolinks-preview 属性,所以你可以这样做:

html[data-turbolinks-preview] {
  input:focus:not([readonly]) {
    border-bottom: $input-border;
    box-shadow: none;
  }

  .input-field {
    .prefix.active {
      color: initial; // Or whatever your default label icon color is
    }

    label:not(.label-icon).active {
      font-size: 1rem; // Or whatever your default label font-size is
      transform: translateY(0);
    }
  }

  input[type=email]:focus:not([readonly]) + label {
    color: $input-border-color; // Or whatever your default label color is
  }
}

我通常不推荐这样做,因为它覆盖了很多默认值,如果所有 CSS 值都没有正确重置,这可能会导致奇怪的行为或维护问题。它还会使输入看起来没有聚焦(实际上是聚焦的),这可能会给用户带来一些困惑。所以恕我直言,以前的解决方案之一比这个更可取。

希望有用。