gpt4 book ai didi

javascript - 为什么 CSS 关键帧动画在具有作用域样式的 Vue 组件中被破坏?

转载 作者:搜寻专家 更新时间:2023-10-30 22:15:41 24 4
gpt4 key购买 nike

我正在尝试在 Vue 中实现 CSS 键入指示器。没有 Vue,它看起来像这样:

.typing-indicator {
background-color: #E6E7ED;
width: auto;
border-radius: 50px;
padding: 20px;
display: table;
margin: 0 auto;
position: relative;
-webkit-animation: 2s bulge infinite ease-out;
animation: 2s bulge infinite ease-out;
}
.typing-indicator:before, .typing-indicator:after {
content: '';
position: absolute;
bottom: -2px;
left: -2px;
height: 20px;
width: 20px;
border-radius: 50%;
background-color: #E6E7ED;
}
.typing-indicator:after {
height: 10px;
width: 10px;
left: -10px;
bottom: -10px;
}
.typing-indicator span {
height: 15px;
width: 15px;
float: left;
margin: 0 1px;
background-color: #9E9EA1;
display: block;
border-radius: 50%;
opacity: 0.4;
}
.typing-indicator span:nth-of-type(1) {
-webkit-animation: 1s blink infinite 0.3333s;
animation: 1s blink infinite 0.3333s;
}
.typing-indicator span:nth-of-type(2) {
-webkit-animation: 1s blink infinite 0.6666s;
animation: 1s blink infinite 0.6666s;
}
.typing-indicator span:nth-of-type(3) {
-webkit-animation: 1s blink infinite 0.9999s;
animation: 1s blink infinite 0.9999s;
}

@-webkit-keyframes blink {
50% {
opacity: 1;
}
}

@keyframes blink {
50% {
opacity: 1;
}
}
@-webkit-keyframes bulge {
50% {
-webkit-transform: scale(1.05);
transform: scale(1.05);
}
}
@keyframes bulge {
50% {
-webkit-transform: scale(1.05);
transform: scale(1.05);
}
}
html {
display: table;
height: 100%;
width: 100%;
}

body {
display: table-cell;
vertical-align: middle;
}
<div class="typing-indicator">
<span></span>
<span></span>
<span></span>
</div>

– 来源:http://jsfiddle.net/Arlina/gtttgo93/

问题是添加 scoped 时动画不起作用属性到组件的样式定义 ( <style lang="scss" scoped> )。我认为这可能与应该全局声明的关键帧有关。

带有.typing-indicator的元素位于具有作用域样式的组件模板中。

有没有人知道如何让我的组件在使关键帧动画起作用的同时具有作用域样式?

最佳答案

问题

问题在于 Vue 的 Webpack 加载器 ( vue-loader ) 在将 ID 添加到作用域选择器和其他标识符时如何错误地解析动画名称。这很重要,因为 vue-loader 的 CSS 作用域使用添加到元素的独特属性来复制 CSS 作用域的行为。虽然您的关键帧名称会附加 ID,但在作用域样式中对动画规则中关键帧的引用不会。

你的 CSS:

@-webkit-keyframes blink {
50% {
opacity: 1;
}
}

@keyframes blink {
50% {
opacity: 1;
}
}
@-webkit-keyframes bulge {
50% {
-webkit-transform: scale(1.05);
transform: scale(1.05);
}
}
@keyframes bulge {
50% {
-webkit-transform: scale(1.05);
transform: scale(1.05);
}
}

.typing-indicator {
...
-webkit-animation: 2s bulge infinite ease-out;
animation: 2s bulge infinite ease-out;
}

.typing-indicator span:nth-of-type(1) {
-webkit-animation: 1s blink infinite 0.3333s;
animation: 1s blink infinite 0.3333s;
}
.typing-indicator span:nth-of-type(2) {
-webkit-animation: 1s blink infinite 0.6666s;
animation: 1s blink infinite 0.6666s;
}
.typing-indicator span:nth-of-type(3) {
-webkit-animation: 1s blink infinite 0.9999s;
animation: 1s blink infinite 0.9999s;
}

应该转化为:

@-webkit-keyframes blink-data-v-xxxxxxxx {
50% {
opacity: 1;
}
}

@keyframes blink-data-v-xxxxxxxx {
50% {
opacity: 1;
}
}
@-webkit-keyframes bulge-data-v-xxxxxxxx {
50% {
-webkit-transform: scale(1.05);
transform: scale(1.05);
}
}
@keyframes bulge-data-v-xxxxxxxx {
50% {
-webkit-transform: scale(1.05);
transform: scale(1.05);
}
}

.typing-indicator {
...
-webkit-animation: 2s bulge-data-v-xxxxxxxx infinite ease-out;
animation: 2s bulge-data-v-xxxxxxxx infinite ease-out;
}

.typing-indicator span:nth-of-type(1) {
-webkit-animation: 1s blink-data-v-xxxxxxxx infinite 0.3333s;
animation: 1s blink-data-v-xxxxxxxx infinite 0.3333s;
}
.typing-indicator span:nth-of-type(2) {
-webkit-animation: 1s blink-data-v-xxxxxxxx infinite 0.6666s;
animation: 1s blink-data-v-xxxxxxxx infinite 0.6666s;
}
.typing-indicator span:nth-of-type(3) {
-webkit-animation: 1s blink-data-v-xxxxxxxx infinite 0.9999s;
animation: 1s blink-data-v-xxxxxxxx infinite 0.9999s;
}

然而它只会被转化为:

@-webkit-keyframes blink-data-v-xxxxxxxx {
50% {
opacity: 1;
}
}

@keyframes blink-data-v-xxxxxxxx {
50% {
opacity: 1;
}
}
@-webkit-keyframes bulge-data-v-xxxxxxxx {
50% {
-webkit-transform: scale(1.05);
transform: scale(1.05);
}
}
@keyframes bulge-data-v-xxxxxxxx {
50% {
-webkit-transform: scale(1.05);
transform: scale(1.05);
}
}

.typing-indicator {
...
-webkit-animation: 2s bulge infinite ease-out;
animation: 2s bulge infinite ease-out;
}

.typing-indicator span:nth-of-type(1) {
-webkit-animation: 1s blink infinite 0.3333s;
animation: 1s blink infinite 0.3333s;
}
.typing-indicator span:nth-of-type(2) {
-webkit-animation: 1s blink infinite 0.6666s;
animation: 1s blink infinite 0.6666s;
}
.typing-indicator span:nth-of-type(3) {
-webkit-animation: 1s blink infinite 0.9999s;
animation: 1s blink infinite 0.9999s;
}

Something to note: in the actual transformation, references to keyframe names in animation rules are missing the -data-v-xxxxxxxx at the end. This is the bug.

目前(截至 47c3317 )速记动画规则声明中的动画名称是通过获取由任何空白字符分割动画规则的第一个值来识别的 [1] 。然而,动画属性的正式定义声明动画名称​​可以出现在规则定义中的任何位置。

<single-animation> = <time> || <single-timing-function> || <time> || <single-animation-iteration-count> || <single-animation-direction> || <single-animation-fill-mode> || <single-animation-play-state> || [ none | <keyframes-name> ]

animation正式语法 [2]

因此,虽然您的动画声明有效,但 vue-loader 无法解析它。

解决方法

当前的解决方法是将您的动画名称移动到动画规则声明的开头。您的关键帧声明不需要更改,它们保留在作用域样式表中。您的动画声明现在应该如下所示:

.typing-indicator {
...
-webkit-animation: bulge 2s infinite ease-out;
animation: bulge 2s infinite ease-out;
}
.typing-indicator span:nth-of-type(1) {
-webkit-animation: blink 1s infinite 0.3333s;
animation: blink 1s infinite 0.3333s;
}
.typing-indicator span:nth-of-type(2) {
-webkit-animation: blink 1s infinite 0.6666s;
animation: blink 1s infinite 0.6666s;
}
.typing-indicator span:nth-of-type(3) {
-webkit-animation: blink 1s infinite 0.9999s;
animation: blink 1s infinite 0.9999s;
}

引用资料

关于javascript - 为什么 CSS 关键帧动画在具有作用域样式的 Vue 组件中被破坏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47283989/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com