javascript - 在剪切路径中使用时重新计算滚动 div 的位置

原文 标签 javascript jquery html css

我正在使用剪切路径根据背景颜色更改我的 Logo 颜色。

除此之外, Logo 会根据用户在页面上的垂直位置从上到下滚动。页面顶部 = 顶部 Logo ,页面底部 = 底部 Logo 等。

不幸的是,当我添加剪切路径时, Logo 失去了滚动位置,在第一个之后,根本不起作用。

有没有解决的办法?此外,标志位置开始时有点偏离,所以如果有任何方法可以同时解决这个问题。

您可以在此处查看原始问题:
div position based on scroll position

我已经尝试过了,但我似乎无法让它工作。

Scroll position lost when hiding div

我正在使用高级自定义字段,每个部分的 PHP 文件在标题中都有这个作为剪切路径的一部分,相应地使用白色或深色版本的 Logo 。其父级相对定位,其子级绝对定位。

div class="logo-scroll">
        <div class="scroll-text">
                    <a href="/home"><img width="53px" height="260px" src="/wp-content/uploads/2019/07/sheree-walker-web-design-edinburgh-vertical-01.svg"/></a>
       </div>
</div>  

Javascript
const docHeight = Math.max(document.documentElement.scrollHeight, document.body.scrollHeight);
const logo = document.querySelector('.scroll-text');
const logoHeight = logo.offsetHeight;
// to get the pseudoelement's '#page::before' top we use getComputedStyle method
const barTopMargin = parseInt(getComputedStyle(document.querySelector('#page'), '::before').top);

let viewportHeight, barHeight, maxScrollDist, currentScrollPos, scrollFraction;

logo.style.top = barTopMargin + 'px';

window.addEventListener('load', update);
window.addEventListener('resize', setSizes);
document.addEventListener('scroll', update);

setSizes();


function update() {
    currentScrollPos = Math.max(document.documentElement.scrollTop, document.body.scrollTop);
    scrollFraction = currentScrollPos / (docHeight - viewportHeight);

    logo.style.top = barTopMargin + (scrollFraction * maxScrollDist) + 'px';
}

function setSizes() {
    viewportHeight = window.innerHeight;
    // to get the pseudoelement's '#page::before' height we use getComputedStyle method
    barHeight = parseInt(getComputedStyle(document.querySelector('#page'), '::before').height); 
    maxScrollDist = barHeight - logoHeight;
    update();
}

CSS
.logo-scroll .scroll-text img {
    padding: 0 6px 0 17px;
}


#page::before {
    content: "";
    position: fixed;
    top: 30px;
    bottom: 30px;
    left: 30px;
    right: 30px;
    border: 2px solid white;
    pointer-events: none;
    -webkit-transition: all 2s; /* Safari prior 6.1 */
    transition: all 2s;
}

.logo-scroll {
    position: fixed;
    left: 30px;
    top: 30px;
    bottom: 30px;
    border-right: 2px solid white;
    width: 75px;
    z-index: 10;
}

.scroll-text {
    position: fixed;
}

最佳答案

let logos, logoHeight, barTopMargin;
let viewportHeight;

window.addEventListener('load', init);
window.addEventListener('resize', setSizes);
document.addEventListener('scroll', update);


function init(lockUpdate) {
    logos = document.querySelectorAll('.scroll-text');
    setSizes(lockUpdate);
}

function update() {
    // ensure initialization and prevent recursive call
    if (!logos) init(true);
    //*************************************************

    /**************************************************
        THIS LINE MUST BE HERE.
    **************************************************/
    let maxScrollDist  = document.documentElement.scrollHeight - viewportHeight;
    //*************************************************

    let currentScrollPos = document.documentElement.scrollTop;
    let newTop;

    let middle = currentScrollPos + viewportHeight/2;
    let middleY = maxScrollDist/2;

    if (middle >= (maxScrollDist+viewportHeight)/2) {
        let p = (middleY - Math.floor(middle - (maxScrollDist+viewportHeight)/2))*100/middleY;

        newTop = viewportHeight/2 - logoHeight/2;
        newTop += (100-p)*(viewportHeight/2)/100;
        newTop -= (100-p)*(barTopMargin +logoHeight/2)/100;
        newTop = Math.max(newTop, viewportHeight/2 - logoHeight/2); /*fix*/
    } else {
        let p = (middleY - Math.floor(-middle + (maxScrollDist+viewportHeight)/2))*100/middleY;
        newTop = barTopMargin*(100-p)/100+(viewportHeight/2 - (logoHeight/2)*p/100 )*p/100;
        newTop = Math.min(newTop, viewportHeight/2 - logoHeight/2); /*fix*/
    }

    logos.forEach(function(el) {
        el.style.top = newTop + "px";
    });
}

function setSizes(lockUpdate) {
    logoHeight     = logos[0].offsetHeight;
    barTopMargin   = parseInt(getComputedStyle(document.querySelector('#page'), '::before').top);
    viewportHeight = window.innerHeight;
    if (lockUpdate === true) return;
    update();
}

更新和测试。

检查它把这段代码放在你的控制台中:
document.removeEventListener('scroll', update);
document.onscroll = function() {
    let _logoHeight     = logos[0].offsetHeight;
    let _barTopMargin   = parseInt(getComputedStyle(document.querySelector('#page'), '::before').top);
    let _viewportHeight = window.innerHeight;
    let _maxScrollDist  = document.documentElement.scrollHeight - _viewportHeight;

    let currentScrollPos = document.documentElement.scrollTop;
    let percent100 = currentScrollPos + _viewportHeight;

    let scrolledPercent = currentScrollPos * 100/_maxScrollDist;

    let newTop = ((_viewportHeight - _logoHeight/2)*scrolledPercent/100);

    let middle = currentScrollPos + _viewportHeight/2;
    let middleY = _maxScrollDist/2; // 100

    if (middle >= (_maxScrollDist+_viewportHeight)/2) {
        let y1 = middleY - Math.floor(middle - (_maxScrollDist+_viewportHeight)/2);
        let p = y1*100/middleY;

        newTop = _viewportHeight/2 - _logoHeight/2;
        newTop += (100-p)*(_viewportHeight/2)/100;
        newTop -= (100-p)*(30 +_logoHeight/2)/100;

        newTop = Math.max(newTop, _viewportHeight/2 - _logoHeight/2); /*fix*/

    } else {
        let y2 = middleY - Math.floor(-middle + (_maxScrollDist+_viewportHeight)/2);
        let p = y2*100/middleY;
        newTop = 30*(100-p)/100+(_viewportHeight/2 - (_logoHeight/2)*p/100 )*p/100;

        newTop = Math.min(newTop, _viewportHeight/2 - _logoHeight/2); /*fix*/
    }

    logos.forEach(function(el) {
        el.style.top = newTop + "px";
    });
}

CSS 修复:
custom.css::第 767 行
@media (max-width: 1000px)...
.scroll-text {
    padding-left: 13px;
    /*width: 27px;*/
}
.scroll-text img {
    /* remove it. but if necessary move it to .scroll-text rule above
    width: 27px; */
}

custom.css::第 839 行
@media (max-width: 599px)...
.logo-scroll {
    /*display: none; why! remove it*/
}

custom.css::第 268 行
.scroll-text {
    position: fixed;
    /* height: 280px; remove it*/
    padding-left: 20px;
}

看到这个capture

最后,祝您有美好的一天,再见。

关于javascript - 在剪切路径中使用时重新计算滚动 div 的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57346371/

相关文章:

javascript - Angular - 检查多个子组件表单是否脏

javascript - 尝试将监听器添加到多个标记时出现未定义的函数错误

javascript - jQuery在单击的选项卡上添加类并在没有时删除

javascript - 随机bgColor:每次点击的颜色是否可能有所不同?

javascript - 生成器理解与数组理解

c# - 如何在 C# 中使用 WkHtmlToXSharp

html - 在IE11中将响应页面宽度从640px调整为1117px会导致错误对齐

javascript - 如何使用 jquery 销毁动态创建的 DOM 元素?

javascript - 来自 Cloud Storage 的图像未在 .map 列表中重新渲染

javascript - 使用 jQuery UI 小部件时如何发现所有可用属性?