动画css最后一个元素用js和vue添加
Animation css for the last element added with js and Vue
我有一个数组,其中我放置了所有具有 class 框的元素,然后我使用 Vue 添加了一个新的 div,这是正确添加的,但我尝试了最后一个我添加的div出现了不透明效果(我会改变它以获得更好的效果),但结果不是预期的。
发生的情况是添加了新元素,但效果将它添加到前一个元素中,我希望它始终在我首先添加的新元素中,也就是说,它将是索引 0 之一,
?我做错了什么?
html代码:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Preguntas en vivo</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div id="app">
<div class="mt-5 d-flex flex-column align-items-center container">
<div>
<input type="text" v-model="nuevoAutor"><br>
<input type="text" v-model="nuevaPregunta"><br>
<button @click="agregarMensaje">Agregar</button>
</div>
<div class="box" v-for="pregunta in preguntas">
{{pregunta.autor}}: {{pregunta.mensaje}}
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
<script src="js/vue.js"></script>
<script src="js/index.js"></script>
</body>
</html>
Vue代码:
const app = new Vue({
el: "#app",
data: {
preguntas: [
],
preguntasAprobadas: [
],
nuevoAutor: "",
nuevaPregunta: "",
boxes: []
},
methods: {
agregarMensaje: function(){
this.preguntas.unshift({
autor: this.nuevoAutor,
mensaje: this.nuevaPregunta,
publicado: false
});
this.nuevaPregunta = "";
this.nuevoAutor = "";
boxes = document.querySelectorAll(".box");
this.agregarClase();
},
agregarClase: function(){
boxes[0].className += " animation";
}
}
})
css代码:
.box {
width: 100%;
background-color: rgb(255, 224, 174);
border: 1px solid rgb(255, 210, 137);
padding: 20px;
margin-top: 30px;
min-height: 200px;
}
.animation {
animation: show 5s;
-webkit-animation: show 5s;
}
@keyframes show {
0% { opacity: 0; }
100% { opacity: 1; }
}
编辑:
我简化了,只有一个class,加了div,有class框,但是加载样式到最后一个,也就是第一个底部,而不是添加到最后一个。
.box {
background-color: rgb(255, 224, 174);
border: 1px solid rgb(255, 210, 137);
padding: 20px;
margin-top: 30px;
min-height: 200px;
width: 100%;
opacity: 1;
animation: show 1s;
-webkit-animation: show 1s;
}
@keyframes show {
0% {
width: 1%;
opacity: 0;
}
100% {
width: 100%;
opacity: 1;
}
}
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Preguntas en vivo</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div id="app">
<div class="mt-5 d-flex flex-column align-items-center container">
<div>
<input type="text" v-model="nuevoAutor"><br>
<input type="text" v-model="nuevaPregunta"><br>
<button @click="agregarMensaje">Agregar</button>
</div>
<div class="row box" v-for="pregunta in preguntas">
<div class="col-12">
{{pregunta.autor}}: {{pregunta.mensaje}}
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
<script src="js/vue.js"></script>
<script src="js/index.js"></script>
</body>
</html>
您正在寻找 vue 组件 transition-group
(参见 docs)。
这是一个组件,可以在添加/删除/重新排序元素时添加 css classes,因此它可以让您对它们进行动画处理。
这是一个例子:
<template>
<div id="app">
<transition-group name="fade" class="questions" mode="in-out">
<div v-for="question of questions" :key="question.id" class="item">
{{ question.msg }}
</div>
</transition-group>
<button @click="addQuestion">Add question</button>
</div>
</template>
<script>
export default {
data () {
return {
questions: [
{ id: 1, msg: 'Hey'},
{ id: 2, msg: 'there'},
{ id: 3, msg: 'General'},
{ id: 4, msg: 'Kenobi'},
],
}
},
methods: {
addQuestion () {
const newId = Math.floor(Math.random() * 1000 + 4)
const newQuestion = { id: newId, msg: 'New question' + newId }
this.questions.push(newQuestion)
}
}
}
</script>
<style>
#app {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
gap: 16px;
max-width: 300px;
margin: 0 auto;
height: 80vh;
}
.questions {
display: flex;
flex-direction: column;
gap: 8px;
}
.questions .item {
background: #fafafa;
border: 1px solid lightgray;
text-align: center;
min-width: 130px;
padding: 4px 12px;
}
// Fade animation for each item
.item.fade-enter-active {
transition: opacity 1s;
}
.item.fade-enter, .item.fade-leave-to {
opacity: 0;
}
</style>
每次您添加一个项目(在开头、结尾、中间,都无所谓),都会应用此 css 转换。删除时相同(参见 fade-leave-to
class)
参见示例 CodePen
我有一个数组,其中我放置了所有具有 class 框的元素,然后我使用 Vue 添加了一个新的 div,这是正确添加的,但我尝试了最后一个我添加的div出现了不透明效果(我会改变它以获得更好的效果),但结果不是预期的。
发生的情况是添加了新元素,但效果将它添加到前一个元素中,我希望它始终在我首先添加的新元素中,也就是说,它将是索引 0 之一,
?我做错了什么?
html代码:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Preguntas en vivo</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div id="app">
<div class="mt-5 d-flex flex-column align-items-center container">
<div>
<input type="text" v-model="nuevoAutor"><br>
<input type="text" v-model="nuevaPregunta"><br>
<button @click="agregarMensaje">Agregar</button>
</div>
<div class="box" v-for="pregunta in preguntas">
{{pregunta.autor}}: {{pregunta.mensaje}}
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
<script src="js/vue.js"></script>
<script src="js/index.js"></script>
</body>
</html>
Vue代码:
const app = new Vue({
el: "#app",
data: {
preguntas: [
],
preguntasAprobadas: [
],
nuevoAutor: "",
nuevaPregunta: "",
boxes: []
},
methods: {
agregarMensaje: function(){
this.preguntas.unshift({
autor: this.nuevoAutor,
mensaje: this.nuevaPregunta,
publicado: false
});
this.nuevaPregunta = "";
this.nuevoAutor = "";
boxes = document.querySelectorAll(".box");
this.agregarClase();
},
agregarClase: function(){
boxes[0].className += " animation";
}
}
})
css代码:
.box {
width: 100%;
background-color: rgb(255, 224, 174);
border: 1px solid rgb(255, 210, 137);
padding: 20px;
margin-top: 30px;
min-height: 200px;
}
.animation {
animation: show 5s;
-webkit-animation: show 5s;
}
@keyframes show {
0% { opacity: 0; }
100% { opacity: 1; }
}
编辑: 我简化了,只有一个class,加了div,有class框,但是加载样式到最后一个,也就是第一个底部,而不是添加到最后一个。
.box {
background-color: rgb(255, 224, 174);
border: 1px solid rgb(255, 210, 137);
padding: 20px;
margin-top: 30px;
min-height: 200px;
width: 100%;
opacity: 1;
animation: show 1s;
-webkit-animation: show 1s;
}
@keyframes show {
0% {
width: 1%;
opacity: 0;
}
100% {
width: 100%;
opacity: 1;
}
}
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Preguntas en vivo</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div id="app">
<div class="mt-5 d-flex flex-column align-items-center container">
<div>
<input type="text" v-model="nuevoAutor"><br>
<input type="text" v-model="nuevaPregunta"><br>
<button @click="agregarMensaje">Agregar</button>
</div>
<div class="row box" v-for="pregunta in preguntas">
<div class="col-12">
{{pregunta.autor}}: {{pregunta.mensaje}}
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
<script src="js/vue.js"></script>
<script src="js/index.js"></script>
</body>
</html>
您正在寻找 vue 组件 transition-group
(参见 docs)。
这是一个组件,可以在添加/删除/重新排序元素时添加 css classes,因此它可以让您对它们进行动画处理。
这是一个例子:
<template>
<div id="app">
<transition-group name="fade" class="questions" mode="in-out">
<div v-for="question of questions" :key="question.id" class="item">
{{ question.msg }}
</div>
</transition-group>
<button @click="addQuestion">Add question</button>
</div>
</template>
<script>
export default {
data () {
return {
questions: [
{ id: 1, msg: 'Hey'},
{ id: 2, msg: 'there'},
{ id: 3, msg: 'General'},
{ id: 4, msg: 'Kenobi'},
],
}
},
methods: {
addQuestion () {
const newId = Math.floor(Math.random() * 1000 + 4)
const newQuestion = { id: newId, msg: 'New question' + newId }
this.questions.push(newQuestion)
}
}
}
</script>
<style>
#app {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
gap: 16px;
max-width: 300px;
margin: 0 auto;
height: 80vh;
}
.questions {
display: flex;
flex-direction: column;
gap: 8px;
}
.questions .item {
background: #fafafa;
border: 1px solid lightgray;
text-align: center;
min-width: 130px;
padding: 4px 12px;
}
// Fade animation for each item
.item.fade-enter-active {
transition: opacity 1s;
}
.item.fade-enter, .item.fade-leave-to {
opacity: 0;
}
</style>
每次您添加一个项目(在开头、结尾、中间,都无所谓),都会应用此 css 转换。删除时相同(参见 fade-leave-to
class)
参见示例 CodePen