Javascript 不考虑动态vue元素的窗口
当某个注释作为道具传递给我的组件时,我试图使我的页面滚动到该注释 我目前正在尝试修复为什么它不能正确滚动到特定的注释,我想我已经缩小了问题的范围,使其成为一个文档滚动高度没有针对某些动态显示的元素进行调整的问题 这些元素是通过使用Javascript 不考虑动态vue元素的窗口,javascript,vue.js,dom,vuejs2,Javascript,Vue.js,Dom,Vuejs2,当某个注释作为道具传递给我的组件时,我试图使我的页面滚动到该注释 我目前正在尝试修复为什么它不能正确滚动到特定的注释,我想我已经缩小了问题的范围,使其成为一个文档滚动高度没有针对某些动态显示的元素进行调整的问题 这些元素是通过使用v-show显示的,我认为这就像我在运行一样 this.$nextTick(() => { window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' }); }); 理论上
v-show
显示的,我认为这就像我在运行一样
this.$nextTick(() => {
window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' });
});
理论上,它应该滚动到窗口的底部,但是如果动态显示的下拉列表不可见,它只会向下滚动到窗口的底部
我还尝试将动态元素包装在v-if
属性中,但这没有什么区别。我需要对元素使用v-show
,因为它们是下拉选项
作为参考,这里是我试图在其中运行所有这些的组件
<template>
<div class="w-8/12 rounded overflow-hidden elevation-10 px-4 py-4 pt-3 m-2">
<ul class="flex mb-0 list-none flex-wrap pt-3 pb-4 flex-row justify-between space-x-2">
<li class="flex-auto text-center">
<a
class="text-xs font-bold uppercase px-5 py-3 shadow-lg rounded block leading-normal cursor-pointer hover:text-white hover:bg-blue-600"
@click="changeTab(1)"
:class="{'text-blue-600 bg-white': tab !== 1, 'text-white bg-blue-600': tab === 1}"
>
<i class="fad fa-camera"></i> Post
</a>
</li>
<li class="flex-auto text-center">
<a
class="text-xs font-bold uppercase px-5 py-3 shadow-lg rounded block leading-normal cursor-pointer hover:text-white hover:bg-blue-600"
@click="changeTab(3)"
:class="{'text-blue-600 bg-white': tab !== 3, 'text-white bg-blue-600': tab === 3}"
>
<i class="fad fa-cogs"></i> Options
</a>
</li>
</ul>
<div :class="{'hidden': tab !== 1, 'block': tab === 1}">
<div class="pt-4 pb-2 flex justify-between">
<p
class="text-gray-700 text-base"
v-html="$options.filters.getHashtag(post.caption)"
></p>
<div>
<button
@click="like"
class="focus:outline-none"
><i
class="fad fa-thumbs-up mr-1"
:class="{'text-blue-600': liked}"
></i></button><span class="inline-block text-sm font-semibold text-gray-700 mr-2">{{likes}}</span>
<button
@click="toggleComments"
class="focus:outline-none"
>
<i class="fad fa-comments-alt px-2"></i>
</button>
</div>
</div>
<div class="flex justify-end mb-2">
<button
class="inline-block text-sm font-semibold text-gray-700 focus:outline-none"
@click="toggleComments"
>{{comments.length}} Comments</button>
</div>
<transition
enter-active-class="transition ease-out duration-100 transform"
enter-class="opacity-0 scale-95"
enter-to-class="opacity-100 scale-100"
leave-active-class="transition ease-in duration-75 transform"
leave-class="opacity-100 scale-100"
leave-to-class="opacity-0 scale-95"
>
<div>
<div
v-if="comments.length > 0"
>
<div
v-show="commentDropdown && !moreComments"
class="border-t"
>
<button
@click="toggleMoreComments"
class="focus:outline-none mt-2"
>
Show More <i class="fad fa-chevron-down"></i>
</button>
<div
v-for="(comment) in comments.slice(comments.length - 3, comments.length)"
:ref="comment.id"
:key="comment.id"
class="py-2"
>
<comment
:comment="comment"
:post="post"
@deleteComment="removeComment"
@commentReply="replyToComment"
></comment>
</div>
</div>
<div
class="border-t"
v-show="commentDropdown && moreComments"
>
<button
@click="toggleMoreComments"
class="focus:outline-none mt-2"
>
Show Less <i class="fad fa-chevron-up"></i>
</button>
<div
v-for="(comment) in comments"
:ref="comment.id"
:key="comment.id"
class="py-2"
>
<comment
:comment="comment"
:post="post"
@deleteComment="removeComment"
@commentReply="replyToComment"
></comment>
</div>
</div>
</div>
<div
class="flex items-center w-full"
v-if=$page.user
>
<div class="flex-shrink-0 h-10 w-10">
<img
class="h-10 w-10 rounded-full"
:src="$page.user.profile_photo_url"
:alt="$page.user.username"
>
</div>
<div class="ml-4 w-full">
<input
class="form-input mt-1 block w-full"
placeholder="Enter a comment"
v-model="comment"
@keyup.enter="submitComment"
ref="commentInput"
>
<div v-if="replying">
<small>Replying to {{replying.user.username}}'s comment</small>
<small
class="text-red-600 cursor-pointer hover:text-red-400"
@click="stopReplying"
><i class="fad fa-times"></i></small>
</div>
</div>
</div>
<div
class="flex items-center w-full"
v-else
>
<p>
You must be logged in to add a comment, either <inertia-link
:href="$route('login')"
class="underline font-semibold text-blue-600 hover:text-blue-400"
> sign in</inertia-link> or <inertia-link
:href="$route('register')"
class="underline font-semibold text-blue-600 hover:text-blue-400"
> register</inertia-link>
</p>
</div>
</div>
</transition>
</div>
</div>
</template>
<script>
import Comment from "@/Includes/Comment";
import _ from "lodash";
export default {
props: {
post: Object,
scrollComment: {
type: String,
default: null
}
},
components: {
Comment,
},
data() {
return {
vfTransitions: ["swipe"],
tab: 1,
liked: this.post.is_liked,
likes: this.post.likes.length,
commentDropdown: false,
comments: this.post.comments,
comment: "",
moreComments: false,
replying: "",
};
},
mounted() {
if (this.scrollComment != null) {
this.commentDropdown = true;
var index = 0;
for (let i = 0; i < this.comments.length; i++) {
const comment = this.comments[i];
if (comment.id == this.scrollComment) {
index = i;
break;
}
}
if (index < (this.comments.length - 3)) {
this.moreComments = true;
}
this.$nextTick(() => {
window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' });
});
}
},
methods: {
changeTab(number) {
this.tab = number;
},
like() {
if (this.$page.user) {
if (this.liked) {
this.liked = false;
this.likes -= 1;
this.$http.delete(`/posts/${this.post.id}/like`);
} else {
this.liked = true;
this.likes += 1;
this.$http.post(`/posts/${this.post.id}/like`);
}
} else {
this.$inertia.visit("/login");
}
},
toggleComments() {
this.commentDropdown = !this.commentDropdown;
},
showComments() {
this.commentDropdown = true;
},
submitComment() {
var comment = {
user: this.$page.user,
comment: this.comment,
created_at: moment(),
};
if (this.replying == "") {
this.$http
.post(`/posts/${this.post.id}/comments`, {
comment: this.comment,
})
.then((res) => {
this.comments.push(res.data);
});
} else {
this.$http
.post(`/posts/${this.post.id}/comments`, {
comment: this.comment,
replying: true,
parent: this.replying
})
.then((res) => {
this.$emit('createdReply', {
parent_id: this.replying.id,
comment: res.data
});
this.replying = "";
});
}
this.comment = "";
},
removeComment(comment) {
this.comments = _.remove(this.comments, function (n) {
return n.id !== comment.id;
});
},
toggleMoreComments() {
this.moreComments = !this.moreComments;
},
replyToComment(comment) {
this.replying = comment;
this.$refs.commentInput.focus();
},
stopReplying() {
this.replying = "";
},
},
filters: {
getHashtag: function (value) {
if (!value) return "";
value = value.toString();
value = value.replace(
/#\w+/gm,
'<a href="/hashtags?=$&" class="font-bold underline text-blue-600 hover:text-blue-400">$&</a>'
);
return value;
},
getTimeAgo: function (value) {
if (!value) return "";
return moment(value).fromNow();
},
},
};
</script>
-
'
);
返回值;
},
getTimeAgo:函数(值){
如果(!value)返回“”;
返回力矩(值).fromNow();
},
},
};
通过将所有内容包装在requestAnimationFrame
函数中修复
requestAnimationFrame(() => {
window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' });
});
是否在显示动态元素之前进行滚动,从而增加页面高度并移动滚动偏移量?@Decademon否,显示动态元素,滚动在
此方法中。$nextTick
方法中,该方法在装入的方法中运行,所有的动态元素都是在data ObjectDo中设置的。这是我运行上述代码时应该发生的事情,但我得到的是页面滚动到大约全高的一半,这(如前所述)可能是因为如果我有动态元素,您会注意到一个computed属性用于限制正在呈现的列表元素的数量,而不使用模板中的v-show
或v-if
,该模板提供了正确的滚动高度。