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 值都没有正确重置,这可能会导致奇怪的行为或维护问题。它还会使输入看起来没有聚焦(实际上是聚焦的),这可能会给用户带来一些困惑。所以恕我直言,以前的解决方案之一比这个更可取。
希望有用。
我有一个 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 值都没有正确重置,这可能会导致奇怪的行为或维护问题。它还会使输入看起来没有聚焦(实际上是聚焦的),这可能会给用户带来一些困惑。所以恕我直言,以前的解决方案之一比这个更可取。
希望有用。