web-dev-qa-db-fra.com

Liens d'ancrage de défilement lisses SANS jQuery

Est-il possible d'utiliser le défilement régulier pour ancrer les liens mais sans jQuery? Je crée un nouveau site et je ne veux pas utiliser jQuery.

40
drozdzynski

En utilisant la fonction d'ici: Animation JavaScript et en la modifiant pour modifier une propriété (pas seulement la propriété d'un style), vous pouvez essayer quelque chose comme:

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/

Assurez-vous que la taille de la fenêtre est suffisamment petite pour qu'il y ait une barre de défilement et que vous puissiez faire défiler jusqu'au 5e div.

Et non, cela ne nécessitait pas la reconstitution de 25% de jQuery.

Cela serait évidemment très fortement modifié en fonction de la signification de votre question (par exemple, lorsque le hachage de la fenêtre change, ou quelque chose du genre).

Notez qu'avec jQuery, c'est aussi simple que:

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

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

Juste en disant ...

36
Ian

Étendre cette réponse: https://stackoverflow.com/a/8918062/3851798

Après avoir défini votre fonction de scrollTo, vous pouvez passer l'élément que vous voulez faire défiler dans la fonction.

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);
}

Si vous avez un div avec un id = "footer"

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

Dans le script que vous exécutez pour faire défiler, vous pouvez exécuter ceci,

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

Et voila. Défilement lisse sans jQuery. Vous pouvez réellement jouer avec ce code sur la console de votre navigateur et l’ajuster à votre guise.

49
Tejas Shah

En fait, il existe un moyen plus léger et simple de le faire: 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>

17
Alexander Svetly

Utilisez ceci:

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

Les transitions CSS3 avec un sélecteur :target peuvent donner un résultat agréable sans piratage JS. J'étais en train de réfléchir à l'opportunité de modifier cela, mais sans Jquery, cela devient un peu compliqué. Voir cette question pour plus de détails.

4
Louis Maddox

Bibliothèque javascript légère et pure: smooth-scroll on github

2
Jeremy Lynch

Ma bibliothèque de défilement préférée actuellement est Zenscroll en raison de la vaste gamme de fonctionnalités et de sa petite taille (actuellement, seulement 3,17 Ko). 

À l'avenir, il serait peut-être plus judicieux d'utiliser la fonctionnalité native scrollIntoView , mais comme elle devrait être remplie dans la plupart des sites de production aujourd'hui en raison du manque de prise en charge de IE, je recommande plutôt d'utiliser Zenscroll dans tous les cas. 

1
Zach Saucier

Vanilla js variant utilisant requestAnimationFrame avec les accélérations et tous les navigateurs pris en charge:

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)
        }
    })()
}

Tout assouplissement supporté!

1
user1444621

Lisser le comportement de défilement avec polyfill ...

Exemple:

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

Référentiel: https://github.com/iamdustan/smoothscroll

1
M N Fuad

vous pouvez utiliser cette bibliothèque javascript pour ajouter un défilement régulier à tous vos liens internes. Vous pouvez également ajouter une configuration, pour fournir des liens à ignorer . Vous pouvez avoir un aperçu détaillé ici . https://codingninjascodes.github.io/SmoothScrollJs/

0
user3147343

C'est une version mise à jour de @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
Yevhenii Dehtiar

Voici une solution simple en pure JavaScript. Il tire parti de la propriété CSS scroll-behavior: smooth

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

Usage

Disons que nous avons 10 divs:

<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>

Nous pouvons faire défiler jusqu’à l’ID de choix

scroll_to('#657kh54')

Vous appelez simplement cette fonction lors de l'événement click (par exemple, cliquez sur le bouton puis faites défiler jusqu'à div # 9). 

Résultat

 enter image description here

Bien sûr, cela semble beaucoup plus fluide dans la vie réelle. 

VIOLON

Malheureusement, IE et Safari ne supportent pas scrollBehavior = 'smooth' à partir de 2019

 enter image description here Documents Web MDN

0
Cybernetic