web-dev-qa-db-ja.com

jQueryなしのスムーズスクロールアンカーリンク

スムーズスクロールを使用してリンクを固定することはできますが、なしjQuery?新しいサイトを作成していますが、jQueryを使用したくありません。

48
drozdzynski

ここから関数を使用します: JavaScript animation そして、それを変更してプロパティ(スタイルのプロパティだけでなく)を変更するには、次のようなものを試すことができます:

function animate(elem, style, unit, from, to, time, prop) {
    if (!elem) {
        return;
    }
    var start = new Date().getTime(),
        timer = setInterval(function () {
            var step = Math.min(1, (new Date().getTime() - start) / time);
            if (prop) {
                elem[style] = (from + step * (to - from))+unit;
            } else {
                elem.style[style] = (from + step * (to - from))+unit;
            }
            if (step === 1) {
                clearInterval(timer);
            }
        }, 25);
    if (prop) {
          elem[style] = from+unit;
    } else {
          elem.style[style] = from+unit;
    }
}

window.onload = function () {
    var target = document.getElementById("div5");
    animate(document.scrollingElement || document.documentElement, "scrollTop", "", 0, target.offsetTop, 2000, true);
};

DEMO:https://jsfiddle.net/zpu16nen/

実際にスクロールバーがあり、5番目のdivまでスクロールできるように、ウィンドウのサイズを十分に小さくしてください。

いいえ、jQueryの25%を再作成する必要はありませんでした。

これは明らかに、あなたの質問が実際に何を意味するかに応じて(ウィンドウハッシュが変更されたときなど)高度に修正する必要があります。

JQueryを使用すると、次のように簡単になります。

$(document).ready(function () {
    $("html, body").animate({
        scrollTop: $("#div5").offset().top
    }, 2000);
});

DEMO:http://jsfiddle.net/7TAa2/1/

ただ言って...

40
Ian

この答えを拡張する: https://stackoverflow.com/a/8918062/3851798

ScrollToの関数を定義した後、関数にscrollToする要素を渡すことができます。

function scrollTo(element, to, duration) {
    if (duration <= 0) return;
    var difference = to - element.scrollTop;
    var perTick = difference / duration * 10;

    setTimeout(function() {
        element.scrollTop = element.scrollTop + perTick;
        if (element.scrollTop === to) return;
        scrollTo(element, to, duration - 10);
    }, 10);
}

Id = "footer"のdivがある場合

<div id="footer" class="categories">…</div>

スクロールするために実行するスクリプトでは、これを実行できます。

elmnt = document.getElementById("footer");
scrollTo(document.body, elmnt.offsetTop, 600);

そして、あなたはそれを持っています。 jQueryを使用しないスムーズなスクロール。実際にブラウザのコンソールでそのコードをいじって、好みに合わせて微調整できます。

51
Tejas Shah

実際には、より軽量で簡単な方法があります: https://codepen.io/ugg0t/pen/mqBBBY

function scrollTo(element) {
  window.scroll({
    behavior: 'smooth',
    left: 0,
    top: element.offsetTop
  });
}

document.getElementById("button").addEventListener('click', () => {
  scrollTo(document.getElementById("8"));
});
div {
  width: 100%;
  height: 200px;
  background-color: black;
}

div:nth-child(odd) {
  background-color: white;
}

button {
  position: absolute;
  left: 10px;
  top: 10px;
}
<div id="1"></div>
<div id="2"></div>
<div id="3"></div>
<div id="4"></div>
<div id="5"></div>
<div id="6"></div>
<div id="7"></div>
<div id="8"></div>
<div id="9"></div>
<div id="10"></div>
<button id="button">Button</button>
24

これを使って:

let element = document.getElementById("box");

element.scrollIntoView();
element.scrollIntoView(false);
element.scrollIntoView({block: "end"});
element.scrollIntoView({behavior: "instant", block: "end", inline: "nearest"});

[〜#〜] demo [〜#〜]https://jsfiddle.net/anderpo/x8ucc5ak/1/ =

5
Anderpo

:targetセレクターを使用したCSS3トランジションは、JSハッキングなしで素晴らしい結果をもたらすことができます。私はこれを実装するかどうかを考えていましたが、Jqueryがないと少し面倒になります。詳細については この質問 をご覧ください。

4
Louis Maddox

requestAnimationFrameを使用して、イージングとすべてのブラウザーがサポートされているVanilla jsバリアント:

const requestAnimationFrame = window.requestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.oRequestAnimationFrame ||
    window.msRequestAnimationFrame;

function scrollTo(to) {
    const start = window.scrollY || window.pageYOffset
    const time = Date.now()
    const duration = Math.abs(start - to) / 3;

    (function step() {
        var dx = Math.min(1, (Date.now() - time) / duration)
        var pos = start + (to - start) * easeOutQuart(dx)

        window.scrollTo(0, pos)

        if (dx < 1) {
            requestAnimationFrame(step)
        }
    })()
}

すべて easing がサポートされています!

3

純粋な軽量JavaScriptライブラリ: githubでのスムーズスクロール

2
Jeremy Lynch

現在、私のお気に入りのスクロール先ライブラリは Zenscroll です。これは 幅広い機能 と小さなサイズ(現在は3.17kbのみ)のためです。

将来的にはネイティブの scrollIntoView 機能を使用する方が理にかなっているかもしれませんが、IEサポート。すべての場合に代わりにZenscrollを使用することをお勧めします。

1
Zach Saucier

ここでこのコードを試してください:

window.scrollTo({
        top: 0,
        left: 0,
        behavior: 'smooth'
    });
1
Alberto Junior

ポリフィルでのスムーズなスクロール動作...

例:

document.querySelectorAll('a[href^="#"]').addEventListener("click", function(event) {
  event.preventDefault();
  document.querySelector(this.getAttribute("href")).scrollIntoView({ behavior: "smooth" });
});

リポジトリ: https://github.com/iamdustan/smoothscroll

1
MNF

@Ianからアップグレードされたバージョンです

// Animated scroll with pure JS
// duration constant in ms
const animationDuration = 600;
// scrollable layout
const layout = document.querySelector('main');
const fps = 12;  // in ms per scroll step, less value - smoother animation
function scrollAnimate(elem, style, unit, from, to, time, prop) {
    if (!elem) {
        return;
    }
    var start = new Date().getTime(),
        timer = setInterval(function () {
            var step = Math.min(1, (new Date().getTime() - start) / time);
            var value =  (from + step * (to - from)) + unit;
            if (prop) {
                elem[style] = value;
            } else {
                elem.style[style] = value;
            }
            if (step === 1) {
                clearInterval(timer);
            }
        }, fps);
    if (prop) {
        elem[style] = from + unit;
    } else {
        elem.style[style] = from + unit;
    }
}

function scrollTo(hash) {
    const target = document.getElementById(hash);
    const from = window.location.hash.substring(1) || 'start';
    const offsetFrom = document.getElementById(from).offsetTop;
    const offsetTo = target.offsetTop;
    scrollAnimate(layout,
        "scrollTop", "", offsetFrom, offsetTo, animationDuration, true);
    setTimeout(function () {
      window.location.hash = hash;
    }, animationDuration+25)
};

// add scroll when click on menu items 
var menu_items = document.querySelectorAll('a.mdl-navigation__link');
menu_items.forEach(function (elem) {
    elem.addEventListener("click",
        function (e) {
            e.preventDefault();
            scrollTo(elem.getAttribute('href').substring(1));
        });
});

// scroll when open link with anchor 
window.onload = function () {
    if (window.location.hash) {
        var target = document.getElementById(window.location.hash.substring(1));
        scrollAnimate(layout, "scrollTop", "", 0, target.offsetTop, animationDuration, true);
    }
}
0

2019年の誰にとっても、まず、イベントリスナーを追加します

  document.getElementById('id').addEventListener('click', () => scrollTo())

次に、要素をターゲットにしてスムーズに進みます

function scrollTo() {
    let target = document.getElementById('target');
    target.scrollIntoView({
        behavior: "smooth", 
        block: "end", 
        inline: "nearest"
    })
}
0

pure JavaScriptの簡単なソリューションを次に示します。 CSSプロパティscroll-behaviorを利用します:smooth

function scroll_to(id) {       
    document.documentElement.style.scrollBehavior = 'smooth'
    element = document.createElement('a');
    element.setAttribute('href', id)
    element.click();
}

使用法

10個のdivがあるとします。

<div id='df7ds89' class='my_div'>ONE</div>
<div id='sdofo8f' class='my_div'>TWO</div>
<div id='34kj434' class='my_div'>THREE</div>
<div id='gbgfh98' class='my_div'>FOUR</div>
<div id='df89sdd' class='my_div'>FIVE</div>
<div id='34l3j3r' class='my_div'>SIX</div>
<div id='56j5453' class='my_div'>SEVEN</div>
<div id='75j6h4r' class='my_div'>EIGHT</div>
<div id='657kh54' class='my_div'>NINE</div>
<div id='43kjhjh' class='my_div'>TEN</div>

選択したIDにスクロールできます

scroll_to('#657kh54')

クリックイベントでこの関数を呼び出すだけです(たとえば、ボタンをクリックしてdiv#9までスクロールします)。

結果

enter image description here

もちろん、実際の生活ではずっと滑らかに見えます。

[〜#〜] fiddle [〜#〜]

残念ながら、IEとSafariはscrollBehavior = 'smooth'をサポートしません2019

enter image description hereMDN Webドキュメント

0
Cybernetic