J'ai cet élément input:

<input type="text" class="textfield" value="" id="subject" name="subject">

Ensuite, j'ai d'autres éléments, comme d'autres entrées de texte, des zones de texte, etc.

Lorsque l'utilisateur clique sur input avec #subject, la page doit défiler jusqu'au dernier élément de la page avec une belle animation. Ce devrait être un défilement vers le bas et non vers le haut.

Le dernier élément de la page est un bouton submit avec #submit:

<input type="submit" class="submit" id="submit" name="submit" value="Ok, Done.">

L'animation ne doit pas être trop rapide et doit être fluide.

J'utilise la dernière version de jQuery. Je préfère ne pas installer de plugin mais utiliser les fonctionnalités par défaut de jQuery pour y parvenir.

2282
DiegoP. 13 juil. 2011 à 13:49

30 réponses

Meilleure réponse

En supposant que vous disposez d'un bouton avec l'ID button, essayez cet exemple:

$("#button").click(function() {
    $([document.documentElement, document.body]).animate({
        scrollTop: $("#elementtoScrollToID").offset().top
    }, 2000);
});

J'ai obtenu le code de l'article Faites défiler facilement vers un élément sans plugin jQuery . Et je l'ai testé sur l'exemple ci-dessous.

<html>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
    <script>
        $(document).ready(function (){
            $("#click").click(function (){
                $('html, body').animate({
                    scrollTop: $("#div1").offset().top
                }, 2000);
            });
        });
    </script>
    <div id="div1" style="height: 1000px; width 100px">
        Test
    </div>
    <br/>
    <div id="div2" style="height: 1000px; width 100px">
        Test 2
    </div>
    <button id="click">Click me</button>
</html>
3972
php_nub_qq 8 juil. 2018 à 14:48
jQuery(document).ready(function($) {
  $('a[href^="#"]').bind('click.smoothscroll',function (e) {
    e.preventDefault();
    var target = this.hash,
        $target = $(target);

    $('html, body').stop().animate( {
      'scrollTop': $target.offset().top-40
    }, 900, 'swing', function () {
      window.location.hash = target;
    } );
  } );
} );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<ul role="tablist">
  <li class="active" id="p1"><a href="#pane1" role="tab">Section 1</a></li>
  <li id="p2"><a href="#pane2" role="tab">Section 2</a></li>
  <li id="p3"><a href="#pane3" role="tab">Section 3</a></li>
</ul>

<div id="pane1"></div>
<div id="pane2"></div>
<div id="pane3"></div>
35
Al Foиce ѫ 16 août 2016 à 05:08

Une version compacte de la solution "animée".

$.fn.scrollTo = function (speed) {
    if (typeof(speed) === 'undefined')
        speed = 1000;

    $('html, body').animate({
        scrollTop: parseInt($(this).offset().top)
    }, speed);
};

Utilisation de base: $('#your_element').scrollTo();

22
Rezgar Cadro 22 mai 2017 à 07:28

Pour afficher l'élément complet (si c'est possible avec la taille de fenêtre actuelle):

var element       = $("#some_element");
var elementHeight = element.height();
var windowHeight  = $(window).height();

var offset = Math.min(elementHeight, windowHeight) + element.offset().top;
$('html, body').animate({ scrollTop: offset }, 500);
2
Peter Mortensen 12 juil. 2014 à 06:44

ONELINER

subject.onclick = e=> window.scroll({ top: submit.offsetTop, behavior: 'smooth'});
subject.onclick = e=> window.scroll({top: submit.offsetTop, behavior: 'smooth'});
.box,.foot{display: flex;background:#fdf;padding:500px 0} .foot{padding:250px}
<input type="text" class="textfield" value="click here" id="subject" name="subject">

<div class="box">
  Some content
  <textarea></textarea>
</div>

<input type="submit" class="submit" id="submit" name="submit" value="Ok, Done.">

<div class="foot">Some footer</div>
1
Kamil Kiełczewski 20 févr. 2020 à 14:02

Lorsque l'utilisateur clique sur cette entrée avec #subject, la page doit défiler jusqu'au dernier élément de la page avec une belle animation. Ce devrait être un défilement vers le bas et non vers le haut.

Le dernier élément de la page est un bouton d'envoi avec #submit

$('#subject').click(function()
{
    $('#submit').focus();
    $('#subject').focus();
});

Cela fera d'abord défiler vers le bas jusqu'à #submit, puis restaurera le curseur sur l'entrée sur laquelle vous avez cliqué, ce qui imite un défilement vers le bas et fonctionne sur la plupart des navigateurs. Il ne nécessite pas non plus jQuery car il peut être écrit en JavaScript pur.

Cette façon d'utiliser la fonction focus peut-elle mieux imiter l'animation, en enchaînant les appels focus. Je n'ai pas testé cette théorie, mais elle ressemblerait à ceci:

<style>
  #F > *
  {
    width: 100%;
  }
</style>

<form id="F" >
  <div id="child_1"> .. </div>
  <div id="child_2"> .. </div>
  ..
  <div id="child_K"> .. </div>
</form>

<script>
  $('#child_N').click(function()
  {
    $('#child_N').focus();
    $('#child_N+1').focus();
    ..
    $('#child_K').focus();

    $('#child_N').focus();
  });
</script>
3
Khaled.K 28 nov. 2015 à 12:34

Voici la réponse d'Atharva de: https: //developer.mozilla. org / en-US / docs / Web / API / element.scrollIntoView. Je voulais juste ajouter si votre document est dans un iframe, vous pouvez choisir un élément dans le cadre parent pour faire défiler la vue:

 $('#element-in-parent-frame', window.parent.document).get(0).scrollIntoView();
4
cynya 22 sept. 2018 à 04:25

Pour ce que ça vaut, c'est ainsi que j'ai réussi à obtenir un tel comportement pour un élément général qui peut être à l'intérieur d'un DIV avec défilement. Dans notre cas, nous ne faisons pas défiler le corps entier, mais seulement des éléments particuliers avec débordement: auto; dans une disposition plus grande.

Il crée une fausse entrée de la hauteur de l'élément cible, puis y met l'accent, et le navigateur se charge du reste, quelle que soit la profondeur de la hiérarchie déroulante. Fonctionne comme un charme.

var $scrollTo = $('#someId'),
inputElem = $('<input type="text"></input>');

$scrollTo.prepend(inputElem);
inputElem.css({
  position: 'absolute',
  width: '1px',
  height: $scrollTo.height()
});
inputElem.focus();
inputElem.remove();
2
martinh_kentico 26 févr. 2016 à 11:40

J'ai écrit une fonction à usage général qui défile jusqu'à un objet jQuery, un sélecteur CSS ou une valeur numérique.

Exemple d'utilisation:

// scroll to "#target-element":
$.scrollTo("#target-element");

// scroll to 80 pixels above first element with class ".invalid":
$.scrollTo(".invalid", -80);

// scroll a container with id "#my-container" to 300 pixels from its top:
$.scrollTo(300, 0, "slow", "#my-container");

Le code de la fonction:

/**
* Scrolls the container to the target position minus the offset
*
* @param target    - the destination to scroll to, can be a jQuery object
*                    jQuery selector, or numeric position
* @param offset    - the offset in pixels from the target position, e.g.
*                    pass -80 to scroll to 80 pixels above the target
* @param speed     - the scroll speed in milliseconds, or one of the
*                    strings "fast" or "slow". default: 500
* @param container - a jQuery object or selector for the container to
*                    be scrolled. default: "html, body"
*/
jQuery.scrollTo = function (target, offset, speed, container) {

    if (isNaN(target)) {

        if (!(target instanceof jQuery))
            target = $(target);

        target = parseInt(target.offset().top);
    }

    container = container || "html, body";
    if (!(container instanceof jQuery))
        container = $(container);

    speed = speed || 500;
    offset = offset || 0;

    container.animate({
        scrollTop: target + offset
    }, speed);
};
2
isapir 18 nov. 2015 à 19:46

Plugin jQuery personnalisé très simple et facile à utiliser. Ajoutez simplement l'attribut scroll= à votre élément cliquable et définissez sa valeur sur le sélecteur vers lequel vous souhaitez faire défiler.

Comme ça: <a scroll="#product">Click me</a>. Il peut être utilisé sur n'importe quel élément.

(function($){
    $.fn.animateScroll = function(){
        console.log($('[scroll]'));
        $('[scroll]').click(function(){
            selector = $($(this).attr('scroll'));
            console.log(selector);
            console.log(selector.offset().top);
            $('html body').animate(
                {scrollTop: (selector.offset().top)}, //- $(window).scrollTop()
                1000
            );
        });
    }
})(jQuery);

// RUN
jQuery(document).ready(function($) {
    $().animateScroll();
});

// IN HTML EXAMPLE
// RUN ONCLICK ON OBJECT WITH ATTRIBUTE SCROLL=".SELECTOR"
// <a scroll="#product">Click To Scroll</a>
6
CDspace 31 oct. 2017 à 16:32

La solution de Steve et Peter fonctionne très bien.

Mais dans certains cas, vous devrez peut-être convertir la valeur en entier. Étrangement, la valeur renvoyée par $("...").offset().top se trouve parfois dans float.
Utilisez: parseInt($("....").offset().top)

Par exemple:

$("#button").click(function() {
    $('html, body').animate({
        scrollTop: parseInt($("#elementtoScrollToID").offset().top)
    }, 2000);
});
29
ann 27 août 2015 à 06:03

Dans la plupart des cas, il serait préférable d'utiliser un plugin. Sérieusement. Je vais tout le mien ici. Bien sûr, il y en a d'autres aussi. Mais veuillez vérifier s'ils évitent vraiment les pièges pour lesquels vous voudriez un plugin en premier lieu - pas tous.

J'ai écrit sur les raisons de l'utilisation d'un plug-in ailleurs. En un mot, la doublure qui sous-tend la plupart des réponses ici

$('html, body').animate( { scrollTop: $target.offset().top }, duration );

Est mauvais UX.

  • L'animation ne répond pas aux actions de l'utilisateur. Il continue même si l'utilisateur clique, touche ou essaie de faire défiler.

  • Si le point de départ de l'animation est proche de l'élément cible, l'animation est douloureusement lente.

  • Si l'élément cible est placé près du bas de la page, il ne peut pas défiler vers le haut de la fenêtre. L'animation de défilement s'arrête alors brusquement, au milieu du mouvement.

Pour gérer ces problèmes (et un un tas d'autres), vous pouvez utiliser l'un de mes plugins, jQuery.scrollable. L'appel devient alors

$( window ).scrollTo( targetPosition );

Et c'est tout. Bien sûr, il existe des plus d'options.

En ce qui concerne la position cible, $target.offset().top fait le travail dans la plupart des cas. Mais sachez que la valeur renvoyée ne prend pas en compte l'élément html (voir cette démo). Si vous avez besoin que la position cible soit précise en toutes circonstances, il est préférable d'utiliser

targetPosition = $( window ).scrollTop() + $target[0].getBoundingClientRect().top;

Cela fonctionne même si une bordure sur l'élément html est définie.

8
hashchange 17 août 2015 à 11:43

Si vous ne gérez que le défilement vers un élément d'entrée, vous pouvez utiliser focus(). Par exemple, si vous vouliez faire défiler jusqu'à la première entrée visible:

$(':input:visible').first().focus();

Ou la première entrée visible dans un conteneur de classe .error:

$('.error :input:visible').first().focus();

Merci à Tricia Ball pour l'avoir signalé!

17
Community 23 mai 2017 à 12:02

J'ai installé un module scroll-element npm install scroll-element. Cela fonctionne comme ceci:

import { scrollToElement, scrollWindowToElement } from 'scroll-element'

/* scroll the window to your target element, duration and offset optional */
let targetElement = document.getElementById('my-item')
scrollWindowToElement(targetElement)

/* scroll the overflow container element to your target element, duration and offset optional */
let containerElement = document.getElementById('my-container')
let targetElement = document.getElementById('my-item')
scrollToElement(containerElement, targetElement)

Rédigé avec l'aide des messages SO suivants:

Voici le code:

export const scrollToElement = function(containerElement, targetElement, duration, offset) {
  if (duration == null) { duration = 1000 }
  if (offset == null) { offset = 0 }

  let targetOffsetTop = getElementOffset(targetElement).top
  let containerOffsetTop = getElementOffset(containerElement).top
  let scrollTarget = targetOffsetTop + ( containerElement.scrollTop - containerOffsetTop)
  scrollTarget += offset
  scroll(containerElement, scrollTarget, duration)
}

export const scrollWindowToElement = function(targetElement, duration, offset) {
  if (duration == null) { duration = 1000 }
  if (offset == null) { offset = 0 }

  let scrollTarget = getElementOffset(targetElement).top
  scrollTarget += offset
  scrollWindow(scrollTarget, duration)
}

function scroll(containerElement, scrollTarget, duration) {
  let scrollStep = scrollTarget / (duration / 15)
  let interval = setInterval(() => {
    if ( containerElement.scrollTop < scrollTarget ) {
      containerElement.scrollTop += scrollStep
    } else {
      clearInterval(interval)
    }
  },15)
}

function scrollWindow(scrollTarget, duration) {
  let scrollStep = scrollTarget / (duration / 15)
  let interval = setInterval(() => {
    if ( window.scrollY < scrollTarget ) {
      window.scrollBy( 0, scrollStep )
    } else {
      clearInterval(interval)
    }
  },15)
}

function getElementOffset(element) {
  let de = document.documentElement
  let box = element.getBoundingClientRect()
  let top = box.top + window.pageYOffset - de.clientTop
  let left = box.left + window.pageXOffset - de.clientLeft
  return { top: top, left: left }
}
3
Community 23 mai 2017 à 12:10

C'est ainsi que je le fais.

document.querySelector('scrollHere').scrollIntoView({ behavior: 'smooth' })

Fonctionne dans n'importe quel navigateur.

Il peut facilement être enveloppé dans une fonction

function scrollTo(selector) {
    document.querySelector(selector).scrollIntoView({ behavior: 'smooth' })
}

Voici un exemple de travail

$(".btn").click(function() {
  document.getElementById("scrollHere").scrollIntoView( {behavior: "smooth" })
})
.btn {margin-bottom: 500px;}
.middle {display: block; margin-bottom: 500px; color: red;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<button class="btn">Scroll down</button>

<h1 class="middle">You see?</h1>

<div id="scrollHere">Arrived at your destination</div>

Documents

18
Edvard Åkerberg 20 juin 2019 à 13:59
jQuery(document).ready(function($) {
  $('a[href^="#"]').bind('click.smoothscroll',function (e) {
    e.preventDefault();
    var target = this.hash,
        $target = $(target);

    $('html, body').stop().animate( {
      'scrollTop': $target.offset().top-40
    }, 900, 'swing', function () {
      window.location.hash = target;
    } );
  } );
} );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<ul role="tablist">
  <li class="active" id="p1"><a href="#pane1" role="tab">Section 1</a></li>
  <li id="p2"><a href="#pane2" role="tab">Section 2</a></li>
  <li id="p3"><a href="#pane3" role="tab">Section 3</a></li>
</ul>

<div id="pane1"></div>
<div id="pane2"></div>
<div id="pane3"></div>
2
Minguocode 19 mars 2019 à 15:25

Si vous n'êtes pas très intéressé par l'effet de défilement fluide et simplement intéressé par le défilement vers un élément particulier, vous n'avez pas besoin d'une fonction jQuery pour cela. Javascript a couvert votre cas:

https://developer.mozilla.org/en-US/docs/Web/API/element.scrollIntoView

Il vous suffit donc de: $("selector").get(0).scrollIntoView();

.get(0) est utilisé car nous voulons récupérer l'élément DOM de JavaScript et non l'élément DOM de JQuery.

362
Atharva 21 janv. 2014 à 06:19

Ceci est mon approche abstraite des ID et des href, en utilisant un sélecteur de classe générique

$(function() {
  // Generic selector to be used anywhere
  $(".js-scroll-to").click(function(e) {

    // Get the href dynamically
    var destination = $(this).attr('href');

    // Prevent href=“#” link from changing the URL hash (optional)
    e.preventDefault();

    // Animate scroll to destination
    $('html, body').animate({
      scrollTop: $(destination).offset().top
    }, 500);
  });
});
<!-- example of a fixed nav menu -->
<ul class="nav">
  <li>
    <a href="#section-1" class="nav-item js-scroll-to">Item 1</a>
  </li>
  <li>
    <a href="#section-2" class="nav-item js-scroll-to">Item 2</a>
  </li>
  <li>
    <a href="#section-3" class="nav-item js-scroll-to">Item 3</a>
  </li>
</ul>
6
vascogaspar 21 juin 2015 à 16:46

Je connais un moyen sans jQuery:

document.getElementById("element-id").scrollIntoView();
14
GameMaster1928 20 déc. 2018 à 17:22

Un moyen facile de faire défiler la page pour cibler l'ID de div

var targetOffset = $('#divID').offset().top;
$('html, body').animate({scrollTop: targetOffset}, 1000);
7
Irshad Khan 10 oct. 2017 à 13:03

Animations:

// slide to top of the page
$('.up').click(function () {
    $("html, body").animate({
        scrollTop: 0
    }, 600);
    return false;
});

// slide page to anchor
$('.menutop b').click(function(){
    //event.preventDefault();
    $('html, body').animate({
        scrollTop: $( $(this).attr('href') ).offset().top
    }, 600);
    return false;
});

// Scroll to class, div
$("#button").click(function() {
    $('html, body').animate({
        scrollTop: $("#target-element").offset().top
    }, 1000);
});

// div background animate
$(window).scroll(function () {

    var x = $(this).scrollTop();

    // freezze div background
    $('.banner0').css('background-position', '0px ' + x +'px');

    // from left to right
    $('.banner0').css('background-position', x+'px ' +'0px');

    // from right to left
    $('.banner0').css('background-position', -x+'px ' +'0px');

    // from bottom to top
    $('#skills').css('background-position', '0px ' + -x + 'px');

    // move background from top to bottom
    $('.skills1').css('background-position', '0% ' + parseInt(-x / 1) + 'px' + ', 0% ' + parseInt(-x / 1) + 'px, center top');

    // Show hide mtop menu  
    if ( x > 100 ) {
    $( ".menu" ).addClass( 'menushow' );
    $( ".menu" ).fadeIn("slow");
    $( ".menu" ).animate({opacity: 0.75}, 500);
    } else {
    $( ".menu" ).removeClass( 'menushow' );
    $( ".menu" ).animate({opacity: 1}, 500);
    }

});

// progres bar animation simple
$('.bar1').each(function(i) {
  var width = $(this).data('width');  
  $(this).animate({'width' : width + '%' }, 900, function(){
    // Animation complete
  });  
});
8
user7601056user7601056 27 févr. 2017 à 10:09

$('html, body').animate(...) ne fonctionne pas pour moi sur iphone, navigateur android safari chrome.

J'ai dû cibler l'élément de contenu racine de la page.

$ ('# cotnent'). animate (...)

Voici ce que j'ai fini avec

if (navigator.userAgent.match(/(iPod|iPhone|iPad|Android)/)) {           
    $('#content').animate({
    scrollTop: $("#elementtoScrollToID").offset().top
   }, 'slow');
}
else{
    $('html, body').animate({
    scrollTop: $("#elementtoScrollToID").offset().top
    }, 'slow');
}

Tout le contenu du corps est connecté avec une div #content

<html>
....
<body>
<div id="content">
....
</div>
</body>
</html>
4
Malkev 6 févr. 2017 à 11:20

jQuery .scrollTo() Method

jQuery .scrollTo (): Affichage - Démo, API, source

J'ai écrit ce plugin léger pour faciliter le défilement des pages / éléments. Il est flexible où vous pouvez passer un élément cible ou une valeur spécifiée. Peut-être que cela pourrait faire partie de la prochaine version officielle de jQuery, qu'en pensez-vous?


Exemples d'utilisation:

$('body').scrollTo('#target'); // Scroll screen to target element

$('body').scrollTo(500); // Scroll screen 500 pixels down

$('#scrollable').scrollTo(100); // Scroll individual element 100 pixels down

Options:

scrollTarget : élément, chaîne ou nombre qui indique la position de défilement souhaitée.

offsetTop : nombre définissant un espacement supplémentaire au-dessus de la cible de défilement.

durée : chaîne ou nombre déterminant la durée de l'animation.

easing : chaîne indiquant la fonction d'accélération à utiliser pour la transition.

complete : Une fonction à appeler une fois l'animation terminée.

516
Alex78191 17 mai 2017 à 10:37

Réponse mise à jour en 2019:

$('body').animate({
    scrollTop: $('#subject').offset().top - $('body').offset().top + $('body').scrollTop()
}, 'fast');
1
stardust4891 17 janv. 2019 à 19:58

Cela a fonctionné pour moi:

var targetOffset = $('#elementToScrollTo').offset().top;
$('#DivParent').animate({scrollTop: targetOffset}, 2500);
2
Polaris 7 nov. 2018 à 08:51

Utilisation de ce script simple

if($(window.location.hash).length > 0){
        $('html, body').animate({ scrollTop: $(window.location.hash).offset().top}, 1000);
}

Faire en sorte que si une balise de hachage est trouvée dans l'url, le scrollTo s'anime vers l'ID. Si aucune balise de hachage n'a été trouvée, ignorez le script.

48
Warface 24 nov. 2017 à 04:34

Avec cette solution vous n'avez besoin d'aucun plugin et il n'y a aucune configuration requise en plus de placer le script avant votre balise de fermeture </body>.

$("a[href^='#']").on("click", function(e) {
  e.preventDefault();
  $("html, body").animate({
    scrollTop: $($(this).attr("href")).offset().top
  }, 1000);
});

if ($(window.location.hash).length > 1) {
  $("html, body").animate({
    scrollTop: $(window.location.hash).offset().top
  }, 1000);
}

Au chargement, s'il y a un hachage dans l'adresse, nous y faisons défiler.

Et - chaque fois que vous cliquez sur un lien a avec un hachage href, par exemple #top, nous y faisons défiler.

16
Jonathan 20 oct. 2016 à 17:37

Si vous souhaitez faire défiler un conteneur de débordement (au lieu de $('html, body') répondu ci-dessus), en travaillant également avec un positionnement absolu, voici la façon de procéder:

var elem = $('#myElement'),
    container = $('#myScrollableContainer'),
    pos = elem.position().top + container.scrollTop() - container.position().top;

container.animate({
  scrollTop: pos
}
7
FAjir 23 sept. 2017 à 00:11
$('html, body').animate({scrollTop: 
  Math.min( 
    $(to).offset().top-margintop, //margintop is the margin above the target
    $('body')[0].scrollHeight-$('body').height()) //if the target is at the bottom
}, 2000);
3
user669677user669677 12 févr. 2014 à 14:22
var scrollTo = function($parent, $element) {
    var topDiff = $element.position().top - $parent.position().top;

    $parent.animate({
        scrollTop : topDiff
    }, 100);
};
4
kayz1 3 juil. 2015 à 06:27