97

ヘッダーがに設定されているサイトがありposition: fixedます。私のページの1つでscrollIntoView(true)、要素を使用しています。私の問題は、scrollIntoViewが呼び出されると、要素がヘッダーの下に配置されることです。要素がヘッダーのすぐ下に表示されるようにこれを修正するにはどうすればよいですか?

Bootstrapフレームワークを使用しており、ヘッダーのスタイルはnavbar navbar-fixed-top。です。

4

11 に答える 11

111

少しハッキーですが、回避策があります。

var node = 'select your element';
var yourHeight = 'height of your fixed header';

// scroll to your element
node.scrollIntoView(true);

// now account for fixed header
var scrolledY = window.scrollY;

if(scrolledY){
  window.scroll(0, scrolledY - yourHeight);
}

編集:

最新の回避策は、CSSプロパティをセレクターscroll-margin-topと組み合わせて使用​​することです。:target詳細な説明:https ://www.bram.us/2020/03/01/prevent-content-from-being-hidden-underneath-a-fixed-header-by-using-scroll-margin-top/

于 2012-12-13T10:00:18.507 に答える
38

編集:互換性は低くなりますが(Edge + IEとの互換性はありません)、Arye Eidelmanの回答scroll-margin-topに記載されているように、これも解決されます。

スクロール先の要素にpadding-topaとnegativeを適用することで、CSSでこれを解決できます。margin-top

デモ

// For demo only, no JS needed for the solution
document.querySelector('.scroll-to-working-inline').addEventListener('click', function() {
  document.querySelector('.working-inline').scrollIntoView();
});

document.querySelector('.scroll-to-working-block').addEventListener('click', function() {
  document.querySelector('.working-block').scrollIntoView();
});

document.querySelector('.scroll-to-broken').addEventListener('click', function() {
  document.querySelector('.broken').scrollIntoView();
});
/* Relevant styles */
.working-inline {
  padding-top: 60px;
  margin-top: -60px;
}

.working-block {
  padding-top: 60px;
  margin-top: -60px;
}

/* Allow scrolling to the top */
body {
  padding-top: 60px;
}

/* Only for the demo */
body { margin: 0; }

header {
  position: fixed;
  top: 0;
  background-color: tomato;
  color: white;
  width: 100%;
  height: 60px;
  line-height: 60px;
  text-align: center;
}

[class^='working'],
[class^='broken'] {
  font-size: 3rem;
}
<header>
  scroll to...
  <button class="scroll-to-working-inline">working inline element</button>
  <button class="scroll-to-working-block">working block element</button>
  <button class="scroll-to-broken">broken element</button>
</header>

<main>
  <p>Sql daemon epoch all your base are belong to us packet system perl semaphore. Interpreter warez pragma kilo worm back door baz continue chown blob unix Dennis Ritchie stack mutex bar throw fopen man pages linux. Sql suitably small values bit infinite loop pwned rm -rf.</p>
  
  <a class="working-inline">Working inline</a>
  
  <p>Syn baz man pages unix vi crack leapfrog semaphore fail pwned afk null socket cd long leet emacs Donald Knuth bin grep todo pragma stdio.h January 1, 1970. Alloc gc system new finally sql stack trace syn mainframe cat machine code memory leak server salt flood tunnel in back door thread. Bytes fatal throw ctl-c Dennis Ritchie over clock eof tera perl regex.</p>
  
  <div class="working-block">Working block element</div>
  
  <p>Public injection class unix malloc error script kiddies packet less fail int I'm sorry Dave, I'm afraid I can't do that. Tarball memory leak double rsa pwned public all your base are belong to us. False bytes bang bar tarball semaphore warez cd port daemon exception mountain dew sql mainframe gcc ifdef chown private.</p>
  
  <div class="broken">Broken element</div>
  
  <p>Daemon bubble sort protected mutex overflow grep snarf crack warez I'm compiling bit if memory leak Starcraft nak script kiddies long it's a feature. Hello world public server James T. Kirk injection terminal wannabee race condition syn alloc. Gobble leapfrog finally bypass concurrently while irc gurfle do back door blob man pages sql over clock.</p>
  
  <p>Char hello world then man pages ascii long salt while char fatal do boolean tunnel in system else foo packet sniffer float terminal int default. Trojan horse ssh ifdef /dev/null chown cache error protocol afk todo rm -rf mainframe piggyback pwned regex xss warez Starcraft try catch stdio.h bubble sort. It's a feature I'm sorry Dave, I'm afraid I can't do that *.* port bypass ip.</p>
  
  <p>Stdio.h epoch mutex flood wannabee do race condition sql access exception. Bar pragma man pages dereference flush todo highjack while buffer bit nak big-endian syn xss salt for d00dz. Leslie Lamport linux server error hexadecimal snarf tunnel in rm -rf firewall then shell all your base are belong to us.</p>

  <p>Ascii gcc grep int flood kilo linux access mailbomb hash *.* fork semaphore frack else win bar ssh Leslie Lamport. Man pages strlen cache gnu segfault tarball race condition perl packet sniffer root cookie private chown d00dz January 1, 1970. Rsa public crack bit warez throw for void concurrently ip mutex.</p>
  
  <p>Char hello world then man pages ascii long salt while char fatal do boolean tunnel in system else foo packet sniffer float terminal int default. Trojan horse ssh ifdef /dev/null chown cache error protocol afk todo rm -rf mainframe piggyback pwned regex xss warez Starcraft try catch stdio.h bubble sort. It's a feature I'm sorry Dave, I'm afraid I can't do that *.* port bypass ip.</p>
  
  <p>Stdio.h epoch mutex flood wannabee do race condition sql access exception. Bar pragma man pages dereference flush todo highjack while buffer bit nak big-endian syn xss salt for d00dz. Leslie Lamport linux server error hexadecimal snarf tunnel in rm -rf firewall then shell all your base are belong to us.</p>

  <p>Ascii gcc grep int flood kilo linux access mailbomb hash *.* fork semaphore frack else win bar ssh Leslie Lamport. Man pages strlen cache gnu segfault tarball race condition perl packet sniffer root cookie private chown d00dz January 1, 1970. Rsa public crack bit warez throw for void concurrently ip mutex.</p>
  
  <p>Char hello world then man pages ascii long salt while char fatal do boolean tunnel in system else foo packet sniffer float terminal int default. Trojan horse ssh ifdef /dev/null chown cache error protocol afk todo rm -rf mainframe piggyback pwned regex xss warez Starcraft try catch stdio.h bubble sort. It's a feature I'm sorry Dave, I'm afraid I can't do that *.* port bypass ip.</p>
  
  <p>Stdio.h epoch mutex flood wannabee do race condition sql access exception. Bar pragma man pages dereference flush todo highjack while buffer bit nak big-endian syn xss salt for d00dz. Leslie Lamport linux server error hexadecimal snarf tunnel in rm -rf firewall then shell all your base are belong to us.</p>

  <p>Ascii gcc grep int flood kilo linux access mailbomb hash *.* fork semaphore frack else win bar ssh Leslie Lamport. Man pages strlen cache gnu segfault tarball race condition perl packet sniffer root cookie private chown d00dz January 1, 1970. Rsa public crack bit warez throw for void concurrently ip mutex.</p>
</main>

于 2016-01-11T16:42:57.723 に答える
33

次のコードは、固定ヘッダーのオフセットを使用して、要素の先頭までスムーズにスクロールします。

var topOfElement = document.querySelector('#targetElement').offsetTop - XX;
window.scroll({ top: topOfElement, behavior: "smooth" });

ここで、XXは固定ヘッダーの高さです。

于 2018-05-21T04:00:14.057 に答える
25

scroll-margin-top:$ header-height;

新しいscroll-margin-topCSSプロパティは、標準のHTMLリンクとscrollIntoViewで機能する、これを実現するためのハッキーではない方法を提供します。

scroll-margin-top垂直スクロールの宛先を変更し、ターゲット要素をビューポートの上部から離します。ヘッダーと同じ高さに設定すると、ヘッダーの後ろに配置されないようになります。

/*
  Add a scroll-margin-top to all elements that you want to be able to link to.
  (you may need to select items that don't have an id as well)
*/

* {
  scroll-margin-top: 100px;
}

scroll-margin-topを使用できますか?これは、IEや古いエッジではなく、ほとんどの最新のブラウザ、2021年5月以降の最新のSafariで機能します。

MDN docs scroll-margin-top


以下のデモにスムーズなスクロールを追加したので、これがscrollIntoViewを使用していることは明らかです。

codepenで表示

links = [ ...document.getElementsByClassName("js-link")]
links.forEach(element => {
  element.addEventListener("click", e => {
    e.preventDefault()
    document.getElementById(e.target.dataset.target).scrollIntoView({
      behavior: "smooth", block: "start", inline: "nearest"
    })
  })
})
body {
  margin: 0;
}

header {
  position: sticky;
  top: 0;
  left: 0;
  right: 0;
  height: 100px;
  background: #eee;
  display: flex;
  align-items: center;
}
header a {
  padding: 0.5em;
}

h1 {
  padding: 0.7em;
}

* {
  scroll-margin-top: 100px;
}

p {
  padding: 1em;
}
<header>
  <h1>page title</h1>
  <nav>
    <a href="#p1" class="js-link" data-target="p1">1</a>
    <a href="#p2" class="js-link" data-target="p2">2</a>
    <a href="#p3" class="js-link" data-target="p3">3</a>
    <a href="#p4" class="js-link" data-target="p4">4</a>
    <a href="#p5" class="js-link" data-target="p5">5</a>
  </nav>
</header>

<main>
  <p id="p1">
    paragraph 1.
    <br>
    Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsu
  </p>
  <p id="p2">
    paragraph 2.
    <br>
    Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsu
  </p>
  <p id="p3">
    paragraph 3.
    <br>
    Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsu
  </p>
  <p id="p4">
    paragraph 4.
    <br>
    Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsu
  </p>
  <p id="p5">
    paragraph 5.
    <br>
    Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsu
  </p>
</main>

于 2019-12-09T17:34:46.937 に答える
6

次のことを試してください。それは私にとってうまくいきます:

  const headerHeight = 50; /* PUT HEADER HEIGHT HERE */
  const buffer = 25; /* MAY NOT BE NEEDED */
  const scrollToEl = document.querySelector("#YOUR-ELEMENT-SELECTOR");

  const topOfElement = window.pageYOffset + scrollToEl.getBoundingClientRect().top - headerHeight - buffer;
  window.scroll({ top: topOfElement, behavior: "smooth" });
于 2019-06-05T13:52:25.357 に答える
5

非常に簡単な解決策(Sanyam Jainのコメントに触発された)は、{block: 'center'}次のように選択範囲を垂直方向に中央揃えするために使用することです。

scrollIntoView({block: 'center'})

編集-残念ながら、MDNページで、この機能は「実験的-本番環境では使用しないでください」であることがわかりました。また、IEはそれをサポートしていません(それが必要な場合)。

ここに画像の説明を入力してください

于 2020-12-10T21:05:56.010 に答える
1

scrollIntoViewの後でコンテナdivの上部マージンが無視されるという問題が発生した場合は、要素をビューにスクロールする代わりに、親のスクロールコンテナに対してscrollTopを実行します。

var topOfElementToView= $('#elementToScroll').position().top;
$('#parentScrollingContainer').scrollTop(topOfElementToView);

このスレッドでuser113716から回答を得ました:ページ上の特定の要素に移動するにはどうすればよいですか?

于 2017-03-21T15:11:59.447 に答える
1

個人にとって何がうまくいくかはページレイアウトに大きく依存するのではないかと思うので、この回答は誰かを奪うのではなく、追加のオプションとして意図されています。

私がする必要があるのは、falseを渡してスクロールして表示することだけでしたscrollIntoView(false)

it('should be able to click a button selector', function () {
    let EC = protractor.ExpectedConditions;
    let button = element(by.css('.my-button-css));

    browser.executeScript('arguments[0].scrollIntoView(false)', button.getWebElement()).then(function () {
        browser.wait(EC.elementToBeClickable(button), 3000).then(function () {
            expect(button.isDisplayed()).toBeTruthy();
            button.click();

            // more test logic here

        });
    });
});

jeffを再起動してくれてありがとう

于 2018-10-26T10:45:58.763 に答える
0

誰かがスクロール後にHeader\Titleを非表示にするnavbarを修正した場合、解決策は次のとおりです(@coco puffsの回答とこれに基づく):

let anchorLinks = document.querySelectorAll('a[href^="#"]')

for (let item of anchorLinks) {
  item.addEventListener('click', (e) => {
    let hashVal = item.getAttribute('href')
    let topOfElement = document.querySelector(hashVal).offsetTop - 70

    window.scroll({ top: topOfElement, behavior: "smooth" })
    history.pushState(null, null, hashVal)
    e.preventDefault()
  })
}

コード70pxで使用されます。

于 2018-07-23T18:29:39.993 に答える
0

私にとっては、要素をウィンドウの中央にスクロールするとうまくいきました。

scrollIntoViewIfNeeded({ block: "center" })これはうまく機能しますが、残念ながらブラウザの互換性は限られています(https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoViewIfNeeded)。IEとFirefoxでは動作しません。

ただし、この関数は自分で非常に簡単に作成できます。

function scrollIntoCenter(element) {
  // first scroll element into view. This means element is at the very top.
  element.scrollIntoView();
  
  // calculate new scrollYPosition by subtracting half of window-height
  let y = window.scrollY - window.innerHeight/2;
  
  // scroll up by half of window height
  window.scroll(0, y);
}
于 2021-06-02T18:33:54.463 に答える
0

こんな感じでした

var messageContainer
var message
var autoScroll

var messageCounter = 0
var messageQuantity = 20
while(messageQuantity >1){
        messageQuantity--
        messageContainer = document.createElement('div')
        messageContainer.className = 'messageContainer'

        message = document.createElement('div')
        message.className = 'message'

        message.innerHTML = `message: ${messageCounter++}`
        messageContainer.append(message)

        document.getElementsByClassName('overflow_section')[0].append(messageContainer)
        
        document.getElementById('messageQuantity').textContent = `counter: ${messageCounter}`
}

var appendMessage = document.getElementsByClassName('appendMessage')[0]
        appendMessage.addEventListener("click", ()=>{
            autoScroll = document.getElementById('autoScroll')
                    
            messageContainer = document.createElement('div')
            messageContainer.className = 'messageContainer'
            
            message = document.createElement('div')
            message.className = 'message'
        
            message.innerHTML = `message: ${messageCounter++}`
            messageContainer.append(message)
            
            document.getElementsByClassName('overflow_section')[0].append(messageContainer)
            
            if(autoScroll.checked){
                var count = document.getElementsByClassName('overflow_section')[0].getElementsByClassName('messageContainer')
                document.getElementsByClassName('messageContainer')[count.length - 1].scrollIntoView({
                    behavior: 'smooth', block: 'nearest', inline: 'start' 
                })
            }
            document.getElementById('messageQuantity').textContent = `counter: ${messageCounter}`
                
        })
        
        var scrollUp = document.getElementsByClassName('scrollUp')[0]       
        scrollUp.addEventListener("click", ()=>{
            var count = document.getElementsByClassName('overflow_section')[0].getElementsByClassName('messageContainer')   
                if(count.length > 0){
                   document.getElementsByClassName('messageContainer')[0].scrollIntoView({
                        behavior: 'smooth', block: 'center', inline: 'start' 
                    })  
                }           
                        
        })
        
        var scrollDown = document.getElementsByClassName('scrollDown')[0]       
        scrollDown.addEventListener("click", ()=>{
            var count = document.getElementsByClassName('overflow_section')[0].getElementsByClassName('messageContainer')   
                if(count.length > 0){
                     document.getElementsByClassName('messageContainer')[count.length - 1].scrollIntoView({
                        behavior: 'smooth', block: 'nearest', inline: 'start' 
                    })
                }           
                            
        })
button{
    background-color: rgb(0 0 0 / 80%);
    border-radius:5px;
    padding:10px;
    border:none;
    color:white;
}

input{
   background-color: rgb(179 229 249 / 50%);
   position:relative;
   top:10px;
    width:30px;
    height:30px;
}

.overflow_section{
    overflow: auto;
    font-size:20px;
    background-color: rgb(179 229 249 / 50%);
    width:50%;
    height:200px;
    margin:15px;
    margin-left:auto;
    margin-right:auto;
}

.messageContainer{
    background-color: rgb(255 120 0 / 50%);
    border-radius:5px;
    margin:5px;
    padding:15px;
}


#messageQuantity{
    background-color: rgb(255 120 0 / 100%);
    font-weight:700;
    border-radius:5px;
    padding:10px;
    color:black;
}
<div align="center">
    <span align="center" id='messageQuantity'></span>
    <button class='appendMessage'>Append message</button>
    <button class='scrollUp'>Scroll Up</button>
    <button class='scrollDown'>Scroll Down</button>

    <input type="checkbox" id="autoScroll" />
    <label for="vehicle1">Auto scroll</label>
</div>
<div class='overflow_section'></div>

于 2022-01-17T04:27:22.057 に答える