Intersection Observer 不观察新元素
Intersection Observer doesn't observe new elements
我需要观察列表中的元素,并在它们出现在用户视口中时将它们标记为已读。但是当我在数组的开头添加新元素时(unshift),观察者不起作用:(
我用的是Vue,但我知道这个问题与它无关。
这是观察者方法,不会为新元素触发:
onElementObserved(entries) {
entries.forEach(({ target, isIntersecting}) => {
if (!isIntersecting) {
return;
}
this.observer.unobserve(target);
setTimeout(() => {
const i = target.getAttribute("data-index");
this.todos[i].seen = true;
}, 1000)
});
}
v-for
项没有指定 key
,因此 Vue 通过索引跟踪每个列表元素。当新项目未移入列表时,新元素的索引为 0
,该索引已存在于列表中,因此现有元素只是简单地修补到位。由于没有创建新元素,因此不会触发 Intersection Observer。
要解决此问题,请为 v-for
中的每个项目设置一个唯一的 key
。例如,您可以将 id
属性 添加到每个数组元素,然后将 id
绑定为 <todo>
:
的键
let nextId = 0;
const TodoList = Vue.extend({
template: `
<div>
<ul class="TodoList">
<todo
v-for="(todo, i) in todos"
:todo="todo"
:observer="observer"
:index="i"
:key="todo.id"
></todo>
</ul>
<button @click="pushNewTodo()">PUSH NEW</button>
</div>
`,
data() {
return {
todos: [
{ id: nextId++, seen: false, text: "Add app skeleton" },
{ id: nextId++, seen: false, text: "Add to-do component" },
{ id: nextId++, seen: false, text: "Add to-do list component" },
{ id: nextId++, seen: false, text: "Style the components" },
{ id: nextId++, seen: false, text: "Add the IntersectionObserver" },
{ id: nextId++, seen: false, text: "Mark to-do's as seen" }
],
};
},
methods: {
pushNewTodo() {
this.todos.unshift({ id: nextId++, seen: false, text: "Add app skeleton BLAH BLAH BLAH" })
},
}
})
我需要观察列表中的元素,并在它们出现在用户视口中时将它们标记为已读。但是当我在数组的开头添加新元素时(unshift),观察者不起作用:(
我用的是Vue,但我知道这个问题与它无关。
这是观察者方法,不会为新元素触发:
onElementObserved(entries) {
entries.forEach(({ target, isIntersecting}) => {
if (!isIntersecting) {
return;
}
this.observer.unobserve(target);
setTimeout(() => {
const i = target.getAttribute("data-index");
this.todos[i].seen = true;
}, 1000)
});
}
v-for
项没有指定 key
,因此 Vue 通过索引跟踪每个列表元素。当新项目未移入列表时,新元素的索引为 0
,该索引已存在于列表中,因此现有元素只是简单地修补到位。由于没有创建新元素,因此不会触发 Intersection Observer。
要解决此问题,请为 v-for
中的每个项目设置一个唯一的 key
。例如,您可以将 id
属性 添加到每个数组元素,然后将 id
绑定为 <todo>
:
let nextId = 0;
const TodoList = Vue.extend({
template: `
<div>
<ul class="TodoList">
<todo
v-for="(todo, i) in todos"
:todo="todo"
:observer="observer"
:index="i"
:key="todo.id"
></todo>
</ul>
<button @click="pushNewTodo()">PUSH NEW</button>
</div>
`,
data() {
return {
todos: [
{ id: nextId++, seen: false, text: "Add app skeleton" },
{ id: nextId++, seen: false, text: "Add to-do component" },
{ id: nextId++, seen: false, text: "Add to-do list component" },
{ id: nextId++, seen: false, text: "Style the components" },
{ id: nextId++, seen: false, text: "Add the IntersectionObserver" },
{ id: nextId++, seen: false, text: "Mark to-do's as seen" }
],
};
},
methods: {
pushNewTodo() {
this.todos.unshift({ id: nextId++, seen: false, text: "Add app skeleton BLAH BLAH BLAH" })
},
}
})