如何滚动到具有粘性定位的元素?

How can I scroll to an element with sticky positioning?

我有以下代码,我想使用 id 在幻灯片之间切换,但是使用 id 它不起作用,而且还有 JS scrollTo、scrollIntoView 和其他变体。 它在下降但不上升的过程中起作用。

我尝试制作一个与自身重叠的网站,并为调查创建一个很好的渐进流程。 它还应该能够移动到上一张幻灯片,以便您可以在此类调查中输入或更改一些答案。

我希望你能帮助我,也许能看到一些我没有看到的东西。

// set color for each slide
window.onload = function() {
    let slides = [...document.getElementsByClassName("slide")];
    for(let n in slides) {
        let slide = slides[n];
        slide.style.backgroundColor = "hsl("+((360 / slides.length) * n)+", 100%, 25%)";
    }
}
body {
    font-size: 3vw;
    margin: 0;
    padding: 0;
    position: relative;
}

#ref {
    background-color: black;
    position: fixed;
    top: 0;
    z-index: 1000;
}

#ref a {
    color: white;
    text-decoration: none;
}

.slide {
    background-color: #404050;
    border: 1px solid white;
    color: white;
    height: calc(100vh - 2px);
    left: 0;
    position: sticky;
    top: 0;
    width: calc(100vw - 2px);
}
<!DOCTYPE html>
<html>
    <head>
        <title>Page Title</title>
    </head>
    <body>
        <div id="ref">
            <a href="#s1">S1</a>
            <a href="#s2">S2</a>
            <a href="#s3">S3</a>
            <a href="#s4">S4</a>
            <a href="#s5">S5</a>
            <a href="#s6">S6</a>
            <a href="#s7">S7</a>
            <a href="#s8">S8</a>
            <a href="#s9">S9</a>
        </div>
        <div id="s1" class="slide">
            <h1>Slide 1</h1>
        </div>
        <div id="s2" class="slide">
            <h1>Slide 2</h1>
        </div>
        <div id="s3" class="slide">
            <h1>Slide 3</h1>
        </div>
        <div id="s4" class="slide">
            <h1>Slide 4</h1>
        </div>
        <div id="s5" class="slide">
            <h1>Slide 5</h1>
        </div>
        <div id="s6" class="slide">
            <h1>Slide 6</h1>
        </div>
        <div id="s7" class="slide">
            <h1>Slide 7</h1>
        </div>
        <div id="s8" class="slide">
            <h1>Slide 8</h1>
        </div>
        <div id="s9" class="slide">
            <h1>Slide 9</h1>
        </div>
    </body>
</html>

非常喜欢这个实现。这么小css,这么强大的作用

但似乎浏览器不会对粘性元素执行 # 魔法。虽然这可以用 JS 解决,但想到了 HTML-CSS 解决方案,方法是在 HTML 中稍加调整(添加额外的静态元素以供 # 参考)。希望您喜欢这个解决方案。

// set color for each slide
window.onload = function() {
    let slides = [...document.getElementsByClassName("slide")];
    for(let n in slides) {
        let slide = slides[n];
        slide.style.backgroundColor = "hsl("+((360 / slides.length) * n)+", 100%, 25%)";
    }
}
body {
    font-size: 3vw;
    margin: 0;
    padding: 0;
    position: relative;
}

#ref {
    background-color: black;
    position: fixed;
    top: 0;
    z-index: 1000;
}

#ref a {
    color: white;
    text-decoration: none;
}

.slide {
    background-color: #404050;
    border: 1px solid white;
    color: white;
    height: calc(100vh - 2px);
    left: 0;
    position: sticky;
    top: 0;
    width: calc(100vw - 2px);
}
<!DOCTYPE html>
<html>
    <head>
        <title>Page Title</title>
    </head>
    <body>
        <div id="ref">
            <a href="#s1">S1</a>
            <a href="#s2">S2</a>
            <a href="#s3">S3</a>
            <a href="#s4">S4</a>
            <a href="#s5">S5</a>
            <a href="#s6">S6</a>
            <a href="#s7">S7</a>
            <a href="#s8">S8</a>
            <a href="#s9">S9</a>
        </div>
        <div id="s1"> </div><!--Extra static element for # reference-->
          <div class="slide">
            <h1>Slide 1</h1>
          </div>
        
        <div id="s2"></div><!--Extra static element for # reference-->
          <div class="slide">
            <h1>Slide 2</h1>
          </div>
        
        <div id="s3"></div><!--Extra static element for # reference-->
          <div class="slide">
            <h1>Slide 3</h1>
          </div>
        
        <div id="s4"></div><!--Extra static element for # reference-->
          <div class="slide">
            <h1>Slide 4</h1>
          </div>
        
        <div id="s5"></div><!--Extra static element for # reference-->
          <div class="slide">
            <h1>Slide 5</h1>
          </div>
        
        <div id="s6"></div><!--Extra static element for # reference-->
          <div class="slide">
            <h1>Slide 6</h1>
          </div>
        
        <div id="s7"></div><!--Extra static element for # reference-->
          <div class="slide">
            <h1>Slide 7</h1>
          </div>
        
        <div id="s8"></div><!--Extra static element for # reference-->
          <div class="slide">
            <h1>Slide 8</h1>
          </div>
        
        <div id="s9"></div><!--Extra static element for # reference-->
          <div class="slide">
            <h1>Slide 9</h1>
          </div>
        
    </body>
</html>

经过很长时间的尝试,我找到了一个解决方案,但它非常具体。

你需要有一个只包含幻灯片的父元素(在本例中是main),然后你需要给父元素一个高度和一个自动溢出。

在这些步骤之后添加 javascript,它获取所选元素及其父元素(这里又是 main),然后计算每个元素的平均高度,之后它获取元素的索引elem相对于parent,乘以height得到scrollOffset,这是上一步为parent设置的。

// set color for each slide
window.onload = function() {
    let slides = [...document.getElementsByClassName("slide")];
    for(let n in slides) {
        let slide = slides[n];
        slide.style.backgroundColor = "hsl("+((360 / slides.length) * n)+", 100%, 25%)";
    }
}

window.onhashchange = function() {
    let hash = document.body.querySelector(location.hash);
    let parent = hash.parentElement;
    let scrollOffset = parent.scrollHeight / parent.childElementCount;
    scrollOffset *= Array.prototype.indexOf.call(parent.children, hash);
    parent.scrollTop = scrollOffset;
}
body {
    font-size: 3vw;
    margin: 0;
    padding: 0;
    position: relative;
}

#ref {
    background-color: black;
    position: fixed;
    top: 0;
    z-index: 1000;
}

#ref a {
    color: white;
    text-decoration: none;
}

main {
    height: 100vh;
    overflow: auto;
}

.slide {
    background-color: #404050;
    border: 1px solid white;
    color: white;
    height: calc(100vh - 2px);
    left: 0;
    position: sticky;
    top: 0;
    width: calc(100vw - 2px);
}
<!DOCTYPE html>
<html>
    <head>
        <title>Page Title</title>
    </head>
    <body>
        <div id="ref">
            <a href="#s1">S1</a>
            <a href="#s2">S2</a>
            <a href="#s3">S3</a>
            <a href="#s4">S4</a>
            <a href="#s5">S5</a>
            <a href="#s6">S6</a>
            <a href="#s7">S7</a>
            <a href="#s8">S8</a>
            <a href="#s9">S9</a>
        </div>
        <main>
            <div id="s1" class="slide">
                <h1>Slide 1</h1>
            </div>
            <div id="s2" class="slide">
                <h1>Slide 2</h1>
            </div>
            <div id="s3" class="slide">
                <h1>Slide 3</h1>
            </div>
            <div id="s4" class="slide">
                <h1>Slide 4</h1>
            </div>
            <div id="s5" class="slide">
                <h1>Slide 5</h1>
            </div>
            <div id="s6" class="slide">
                <h1>Slide 6</h1>
            </div>
            <div id="s7" class="slide">
                <h1>Slide 7</h1>
            </div>
            <div id="s8" class="slide">
                <h1>Slide 8</h1>
            </div>
            <div id="s9" class="slide">
                <h1>Slide 9</h1>
            </div>
        </main>
    </body>
</html>