Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在css动画后获得元素的位置(vanilla js)_Javascript_Css Animations - Fatal编程技术网

Javascript 如何在css动画后获得元素的位置(vanilla js)

Javascript 如何在css动画后获得元素的位置(vanilla js),javascript,css-animations,Javascript,Css Animations,我正在做一个涉及多个动画的项目,虽然大多数动画都可以用css关键帧动画轻松完成,但其他动画需要javascript,我对如何执行这些动画有点茫然。我会尽我所能描述我不能在小提琴上展示的东西(我正在把演示的东西编码成视频) 页面中有几个部分,每个部分都有不同的元素淡入淡出、旋转等。当每个部分滚动到视图中时,会向其中添加一个“animate”类以触发css动画,其中一个是svg元素,从视口的北部下降到它停驻的视口底部。但是,当用户继续向下滚动时,我需要在视口南部的视图外设置svg元素的动画,然后在下

我正在做一个涉及多个动画的项目,虽然大多数动画都可以用css关键帧动画轻松完成,但其他动画需要javascript,我对如何执行这些动画有点茫然。我会尽我所能描述我不能在小提琴上展示的东西(我正在把演示的东西编码成视频)

页面中有几个部分,每个部分都有不同的元素淡入淡出、旋转等。当每个部分滚动到视图中时,会向其中添加一个“animate”类以触发css动画,其中一个是svg元素,从视口的北部下降到它停驻的视口底部。但是,当用户继续向下滚动时,我需要在视口南部的视图外设置svg元素的动画,然后在下一部分滚动到视图中时重新进入。因此,我尝试在findSection函数中获取元素停驻时的位置(请注意),即在其关键帧动画完成后,但我尝试的方法是获取动画前的位置。通过css设置动画后,如何获取绝对定位元素的当前位置?如果有比我目前所做的更好的方法,我会洗耳恭听,尤其是如果我可以使用单个svg元素,而不是在每个部分复制它

非常感谢您的帮助/建议

威士忌T

标记(每个部分):

javascript:

const sections = document.querySelectorAll('.section');
const svgEl = document.querySelector('#svg-el');


window.addEventListener('scroll', debounce(findSection)); // yes, there's a debounce fn

function findSection(e) {

    let svgElPosition = svgEl.getBoundingClientRect();

    sections.forEach(section => {

        const sectionInAt = (window.scrollY + window.innerHeight) - section.offsetHeight / 2;

        // these both get the pre-css keyframe animation value of 'top', but I need the post-keyframe animation 'top' value
        console.log("svgElPosition.top", svgElPosition.top);
        console.log(window.getComputedStyle(svgEl, null).getPropertyValue("top"));


        // bottom of the section:
        const sectionBottom = section.offsetTop + section.offsetHeight;

        // isHalfShown is true while sectionInAt/triggerCoord > section.offsetTop (i.e., section is half viz)
        const isHalfShown = sectionInAt > section.offsetTop;

        // isNotScrolledPast is true while window.scrollY < imageBottom (i.e., image is still viz)
        const isNotScrolledPast = window.scrollY < sectionBottom;

        if (isHalfShown && isNotScrolledPast) {
            section.classList.add('animate');
        } else {
            section.classList.remove('animate');
        }

    });
}
const sections=document.querySelectorAll('.section');
const svgEl=document.querySelector('#svg el');
window.addEventListener('scroll',去盎司(findSection));//是的,这里有一个debounce fn
函数查找部分(e){
设svgElPosition=svgEl.getBoundingClientRect();
sections.forEach(section=>{
const sectionInAt=(window.scrollY+window.innerHeight)-section.offsetHeight/2;
//这两个都获得了前css关键帧动画值“top”,但我需要后关键帧动画值“top”
控制台日志(“svgElPosition.top”,svgElPosition.top);
log(window.getComputedStyle(svgEl,null.getPropertyValue(“top”));
//本节底部:
const section bottom=section.offsetTop+section.offsetHeight;
//Ishalf显示为真,而sectionInAt/triggerCoord>section.offsetTop(即,section为半viz)
const Ishalfshired=sectionInAt>section.offsetTop;
//当window.scrollY
在这种情况下,我认为最好使用setTimeout()等待动画完成的适当时间,然后在闭包函数中获得位置。下面是一个示例片段:

if (isHalfShown && isNotScrolledPast) {
    section.classList.add('animate');
    let timer = setTimeout(function() {
    let rect = element.getBoundingClientRect();
    console.log(rect.top, rect.right, rect.bottom, rect.left);
    },300); //.3 seconds, if I read that correctly from the CSS (maybe an extra .01 seconds or something as well for good measure)
}

本例中未明确使用“timer”变量,但如果您需要取消动画以同时取消计时器,则该变量可能会很有用(尽管您需要将作用域置于此条件语句之外)。

在这种情况下,我相信最好使用setTimeout()等待动画完成所需的适当时间,然后在闭包函数中获取位置。下面是一个示例片段:

if (isHalfShown && isNotScrolledPast) {
    section.classList.add('animate');
    let timer = setTimeout(function() {
    let rect = element.getBoundingClientRect();
    console.log(rect.top, rect.right, rect.bottom, rect.left);
    },300); //.3 seconds, if I read that correctly from the CSS (maybe an extra .01 seconds or something as well for good measure)
}
本例中未明确使用“timer”变量,但如果您需要取消动画以同时取消计时器,则该变量可能会很有用(尽管您需要将作用域置于此条件语句之外)。

您应该在元素上注册一个事件侦听器:

svgEl.addEventListener('animationend', function (event) {
    const svgRect = this.getBoundingClientRect();
});
每当CSS动画在元素上完成时,就会触发此命令,这是确定它已完成的可靠方法。还请注意,您可以使用、和事件。

您应该在元素上注册一个事件侦听器:

svgEl.addEventListener('animationend', function (event) {
    const svgRect = this.getBoundingClientRect();
});

每当CSS动画在元素上完成时,就会触发此命令,这是确定它已完成的可靠方法。还请注意,您可以利用、和事件。

感谢您的帮助,为我的迟交回复表示歉意,我正在忙于另一个项目。虽然我怀疑@skyline3000的建议是我所期待的汉克斯·布兰登的建议,但我想我必须与skyline3000提到的动画活动合作。我确实按照你的建议尝试了超时(当然还有更长的超时时间),但仍然得到了动画制作前的位置。感谢你的帮助,为我反应迟钝表示歉意,我正在忙于另一个项目。虽然我怀疑@skyline3000的建议是我所期待的汉克斯·布兰登的建议,但我想我必须与skyline3000提到的动画活动合作。我确实按照你的建议尝试了超时(当然还有更长的超时时间),但仍然得到了动画前的位置。感谢skyline3000,并对延迟确认表示歉意,但我已经有几天无法发布了。非常感谢。谢谢你,并对延迟确认表示歉意,但我已经几天没能发帖了。非常感谢。