jQuery scroll à element

j'ai cet élément input :

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

puis j'ai d'autres éléments, comme d'autres entrées de texte, textareas, etc.

lorsque l'utilisateur clique sur input avec #subject , la page doit faire défiler jusqu'au dernier élément de la page avec une belle animation. Il 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 devrait être fluide.

j'exécute 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 arriver.

1922
demandé sur Maistrenko Vitalii 2011-07-13 13:49:44

25 réponses

si vous avez 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 doucement faire défiler à un élément sans un 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>
3535
répondu Steve 2018-07-08 14:48:17

jQuery .scrollTo() Method

jQuery .scrollTo(): Vue de la Démo, l'API Source

j'ai écrit ce plugin léger pour rendre le défilement de page/élément beaucoup plus facile. Il est flexible où vous pouvez passer dans 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 : un élément, une chaîne ou un nombre qui indique la position désirée du rouleau.

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

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

easing : une chaîne indiquant quelle fonction d'assouplissement utiliser pour la transition.

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

463
répondu Timothy Perez 2017-05-17 10:37:03

si vous n'êtes pas très intéressé par l'effet Smooth scroll et que vous voulez simplement faire défiler un élément en particulier, vous n'avez pas besoin d'une fonction jQuery pour cela. Javascript couvre votre cas:

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

donc tout ce que vous devez faire est: $("selector").get(0).scrollIntoView();

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

279
répondu Atharva 2014-01-21 06:19:32

découvrez les ScrollTo plugin. Vous pouvez voir la démo ici .

j'espère que ça aidera.

43
répondu add9 2014-07-12 06:42:35

utilisant ce script simple

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

ferait en sorte que si une étiquette de hachage est trouvée dans l'url, le scrollTo s'anime à L'ID. Si ce n'est pas le cas, ignorez le script.

31
répondu Warface 2017-11-24 04:34:21

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>
27
répondu davidcondrey 2016-08-16 05:08:51

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

Mais dans certains cas, vous pouvez avoir à convertir la valeur d'un entier. Étrangement, la valeur retournée de $("...").offset().top est parfois dans float .

Use: parseInt($("....").offset().top)

par exemple:

$("#button").click(function() {
    $('html, body').animate({
        scrollTop: parseInt($("#elementtoScrollToID").offset().top)
    }, 2000);
});
16
répondu Tejasvi Hegde 2015-08-27 06:03:00

une version compacte de la solution" animate".

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

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

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

15
répondu Rezgar Cadro 2017-05-22 07:28:57

si vous ne faites que défiler vers un élément d'entrée, vous pouvez utiliser focus() . Par exemple, si vous voulez faire défiler vers la première entrée visible:

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

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

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

merci à Tricia Ball pour avoir souligné cela!

12
répondu Benjamin Oakes 2017-05-23 12:02:47

avec cette solution vous n'avez pas besoin de plugin et il y a aucune configuration requise en plus de placer le script avant votre fermeture" étiquette </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 href hachage par exemple #top , nous y faisons défiler.

12
répondu Jonathan 2016-10-20 17:37:56

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

j'ai écrit sur les raisons d'utiliser un plugin ailleurs . En bref, le seul liner à la base de 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 des utilisateurs. Il continue même si l'utilisateur clique, tape 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 être fenêtre. L'animation par défilement s'arrête brusquement alors, au milieu du mouvement.

pour traiter ces questions (et un tas d'autres ), vous pouvez utiliser un de mes plugins, jQuery.scrollable . L'appel devient alors

$( window ).scrollTo( targetPosition );

et c'est tout. Bien sûr, il ya plus d'options .

en ce qui concerne la position cible, $target.offset().top ne le travail dans la plupart des cas. Mais sachez que la valeur retournée ne prend pas en compte une bordure sur l'élément html ( voir cette démo ). Si vous avez besoin de la position cible pour être précis en toutes circonstances, il est préférable d'utiliser

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

qui fonctionne même si une bordure sur l'élément html est placée.

7
répondu hashchange 2015-08-17 11:43:44

c'est mon approche faisant abstraction 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>
5
répondu vascogaspar 2015-06-21 16:46:37

très simple et facile à utiliser custom jQuery plugin. Il suffit d'ajouter l'attribut scroll= à votre élément cliquable et de définir sa valeur au sélecteur vers lequel vous voulez faire défiler.

comme ainsi: <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>
5
répondu DevWL 2017-10-31 16:32:57
var scrollTo = function($parent, $element) {
    var topDiff = $element.position().top - $parent.position().top;

    $parent.animate({
        scrollTop : topDiff
    }, 100);
};
4
répondu kayz1 2015-07-03 06:27:36

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
  });  
});
4
répondu 2017-02-27 10:09:12

$('html, body').animate(...) ne me convient pas sur iphone, Android chrome safari browser.

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

$('#cotnent').animer.(..)

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

Tous les corps, contenu connecté avec un #div du contenu

<html>
....
<body>
<div id="content">
....
</div>
</body>
</html>
3
répondu Shahdat 2017-02-06 11:20:01

moyen facile d'atteindre le rouleau de la page pour cibler div id

var targetOffset = $('#divID').offset().top;
$('html, body').animate({scrollTop: targetOffset}, 1000);
3
répondu Irshad Khan 2017-10-10 13:03:06
$('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);
2
répondu 2014-02-12 14:22:28

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

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
répondu Roman Shamritskiy 2014-07-12 06:44:22

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

exemple d'usage:

// 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");

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
répondu isapir 2015-11-18 19:46:13

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

le dernier élément de la page est un bouton Soumettre avec # soumettre

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

cela va d'abord faire défiler vers le bas à #submit puis restaurer le curseur à l'entrée qui a été cliqué, 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.

Peut cette façon d'utiliser focus fonction imiter l'animation d'une meilleure façon, par l'enchaînement focus appels. Je n'ai pas testé cette théorie, mais elle ressemblerait à quelque chose comme 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>
2
répondu Khaled.K 2015-11-28 12:34:55

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

Il crée un faux entrée de la hauteur de l'élément cible, puis met l'accent, et le navigateur prendra en charge le reste n'importe quelle profondeur dans le défilement de la hiérarchie de vous. 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
répondu martinh_kentico 2016-02-26 11:40:12

j'ai mis en place un module défilement de l'élément 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)

écrit avec l'aide des postes de 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 }
}
1
répondu steven iseki 2017-05-23 12:10:41

si vous voulez faire défiler dans un conteneur débordant (au lieu de $('html, body') répondu ci-dessus), en travaillant aussi avec le positionnement absolu, c'est la façon de faire:

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

container.animate({
  scrollTop: pos
}
0
répondu FAjir 2017-09-23 00:11:45

C'est 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 une iframe, vous pouvez choisir un élément dans le cadre parent pour faire défiler en vue:

 $('#element-in-parent-frame', window.parent.document).get(0).scrollIntoView();
0
répondu cynya 2018-09-22 04:25:31