I am experimenting with creating a vertical scrolling animation.
Within a div, I have 9 elements with overflow hidden, allowing only 3 elements to be visible at once.
Every 5 seconds, I aim to add styles to the elements using negative margin-top values and adjusting the orderStep variable. For example, when orderStep is 1, I set the margin-top to 0; for 2, -190px; and for 3, -380px.
I have defined a function within the methods object to handle this which I call on created after fetching records from the backend.
Unfortunately, my current implementation isn't working correctly:
// Vue object data method
data() {
return {
articles: [],
errors: [],
step: 1
}
},
methods: {
changeSlide() {
const elements = document.querySelectorAll('.most__popular');
setInterval(() => {
switch (this.step) {
case 1:
for(let val of elements) {
val.style.margin = "10px 0";
}
this.step = 2;
break;
case 2:
for(let val of elements) {
val.style.margin = "-190px 0 0 0";
}
this.step = 3;
break;
case 3:
for(let val of elements) {
val.style.margin = "-380px 0 0 0";
}
this.step = 1;
break;
}
},5000);
}
},
async created() {
try {
const response = await axios.get(`/api/article/getMostPopular.php`, axiosConfig);
this.articles = response.data.records;
this.changeSlide();
} catch (e) {
this.errors.push(e)
}
},
After some debugging, it turns out that the NodeList returned by document.querySelectorAll is empty, likely because I'm referencing elements rendered asynchronously through v-for below my axios.get request. How can I resolve this issue?
Following RoyJ's recommendation, I'm now binding styles using the :style directive in the template:
<div class="most__popular"
v-for="n in articles" :key="n.id"
:style="{margin: sliderMargin}">
The margin value is controlled by the sliderMargin variable updated in my function:
changeSlide() {
setInterval(() => {
switch (this.step) {
case 1:
console.log('step1');
this.sliderMargin = '10px 0 0 0';
this.step = 2;
break;
case 2:
console.log('step2');
this.sliderMargin = '-190px 0 0 0';
this.step = 3;
break;
case 3:
console.log('step3');
this.sliderMargin = '-190px 0 0 0';
this.step = 1;
break;
}
},5000);
}
However, this approach applies the margin to all elements causing them to disappear instead of scrolling. To achieve the desired result:
- On the first step, apply margin-top: 10px to all elements
- On the second step, apply -190px margin-top to elements 1, 2, and 3, while the rest have 10px
- On the third step, apply -190px margin-top to elements 1-6, while the rest have 10px
How can I adjust the :style directive to target only the first three elements if this.step is equal to 2, or six elements if this.step is equal to 3, and none if this.step is equal to 1?