简体   繁体   English

Window 没有考虑动态vue元素

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM