[英]Window not taking into account dynamic vue elements
I'm trying to make my page scroll to a specific comment when that comment is passed as a prop to my component.当该评论作为道具传递给我的组件时,我试图让我的页面滚动到特定评论。
I'm currently trying to bug fix why it is not scrolling correctly to the specific comment and I think I've narrowed down the issue to be an issue with the document scroll height not being adjusted for some dynamically shown elements.我目前正在尝试修复为什么它没有正确滚动到特定评论的错误,我认为我已经将问题缩小为文档滚动高度没有针对某些动态显示的元素进行调整的问题。
These elements are shown by using v-show
and I'm thinking this as if I run这些元素是通过使用
v-show
,我认为这就像我运行一样
this.$nextTick(() => {
window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' });
});
that should theoretically scroll to the bottom of the window, but it only scrolls down to where the bottom of the window would be if the dynamically shown dropdown wasn't visible.理论上应该滚动到 window 的底部,但如果动态显示的下拉菜单不可见,它只会向下滚动到 window 的底部。
I've also tried wrapping the dynamic elements in v-if
attributes instead but that makes no difference.我也尝试过将动态元素包装在
v-if
属性中,但这没有区别。 I need to use v-show
for the elements as they are dropdown options我需要对元素使用
v-show
,因为它们是下拉选项
For reference, here is the component I am trying to run all of this in作为参考,这是我试图在其中运行所有这些的组件
<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>
Fixed by wrapping everything within a requestAnimationFrame
function like this通过像这样将所有内容包装在
requestAnimationFrame
function 中来修复
requestAnimationFrame(() => {
window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' });
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.