1

I am targeting multiple similar child divs inside multiple container divs. Subsequently the page scrolls towards the first targeted child div.

Unfortunately, the page doesn't scroll towards the first child div and then stop scrolling. The page keeps scrolling towards all of the child divs one-by-one-by-one.

Without luck I am trying to change this behaviour. I wish the page would just stop scrolling at the first child div.

To see my problem in action please click on any year in the header: http://paintings.directory

Current jQuery code:

var $sections = $('section');
$('#index_year p, section p').on('click', function(e) {
  let year = $(this).data('y');
  $sections.each(function() {
    let $section = $(this);
    let $target = $('.' + year, $section);
    if ($target.length) {
      $('html, body').animate({
        scrollTop: $target.offset().top - 128
      }, 2000);
      $section.removeClass('yearNotFound');
      $section.animate({
        scrollLeft: $section.scrollLeft() + $target.position().left
      }, 2000);
    } else {
      $section.addClass('yearNotFound');
    };
  });
});

So far I have unsuccessfully tried to:

  1. give the child divs I am targeting a class to then scroll to the first child div with that class as follows:
$('html, body').animate({
    scrollTop: $('.class:visible:first').offset().top
}, 1000);
  1. add return, false; after the current scrolling code as follows:
$('html, body').animate({
    scrollTop: $target.offset().top - 128
}, 2000); return, false;
  1. use a :first selector as follows:
$( "$target:first" )`
  1. place the 'scrolling-code' outside of the loop, by making a separate
$('#index_year p, section p').on('click', function() {
    $('html, body').animate({
        scrollTop: $target.offset().top - 128
    }, 2000);
});
  1. add scrollIntoView, I just couldn't phantom where and how to use this.

So far it's not working out for me and I am therefor looking for help.

Jack Bashford
  • 43,180
  • 11
  • 50
  • 79
Jordy
  • 347
  • 2
  • 11
  • 1
    `$("$target")` - meant to be `$("#target")`? – Jack Bashford Apr 04 '19 at 02:54
  • You just need to exit the `.each()` loop as sso as there is a `$target.length`. So in that `if`, add a `return true;` at the end. – Louys Patrice Bessette Apr 04 '19 at 03:04
  • I see, where exactly do I place the return true? Behind `}, 2000);`? – Jordy Apr 04 '19 at 03:05
  • Right before `} else {`... Inside the `if`. *(yes, I think we talk about the same place ;)* -- That is instead of `return, false;`. -- Replace that with `return true;` **no coma!**. – Louys Patrice Bessette Apr 04 '19 at 03:06
  • It's still scrolling through all of them http://paintings.directory I must be doing something wrong. – Jordy Apr 04 '19 at 03:10
  • Hi @JackBashford I believe there is no div with ID target, I think the $ instead of # has to do with `let $target = $('.' + year, $section);` please correct me if I'm wrong. – Jordy Apr 04 '19 at 03:11
  • In that case, do `$($target + ":first")`. – Jack Bashford Apr 04 '19 at 03:12
  • @LouysPatriceBessette currently I have it like this with no luck: `$('html, body').animate({ scrollTop: $target.offset().top - 128 }, 2000); return true;` – Jordy Apr 04 '19 at 03:17
  • Naa... Maybe I'm tired... Try `return false;` **but without coma**... Here is a [reference](https://stackoverflow.com/questions/1784780/how-to-break-out-of-jquery-each-loop); – Louys Patrice Bessette Apr 04 '19 at 03:21
  • 1
    Same here, up for 40 hours, this did the trick, although now the rows without paintings from the targeted year are not fading out. Just some of them. I think we are now keeping all sections from temporary getting class yearNotFound.... (thanks for your time and effort!) http://www.paintings.directory – Jordy Apr 04 '19 at 03:23
  • ;) Just before the `return false`, add `$(".yearNotFound").removeClass"yearNotFound");`. ;) -- Sleep is needed to keep a coder coding! Take care ;) – Louys Patrice Bessette Apr 04 '19 at 03:26
  • -_-" whoops and not all years scroll to the left so the scrollLeft bit also just works once. I see... return false stops the loop, therefore stops all the scrolling down, however also keeps the original code from working correctly, should I just place the `$('html, body').animate({...});` section somewhere else completely? I have bitten of more than I can chew that's for sure..... – Jordy Apr 04 '19 at 03:27
  • Ha ok... You want to add the class `yearNotFound` to all of them anyway (whern there's none)... I see... Hold on. – Louys Patrice Bessette Apr 04 '19 at 03:29
  • I would let the loop got through all... But instead of animating in that loop, I would store the first hit in another variable. After the loop, animate that one. So, `if($target.length && typeof($storedTarget) =="undefined")` --> store the target. – Louys Patrice Bessette Apr 04 '19 at 03:31
  • Wait that makes me think, if all the paintings I don't want to see have class `.yearNotFound` can I not then just scroll the `$('html, body)` towards the first div not having class `yearNotFound` something maybe like this: `first:div:NOT:.yearNotFound` or is this not possible? That has the same outcome? :-D – Jordy Apr 04 '19 at 03:38

1 Answers1

1

I would store the first painting having the "year" class in another variable to procede to the scroll after the loop.

But the animation of each section having a matched date has to be in the loop...

$('#index_year p, section p').on('click', function(e) {
  let year = $(this).data('y');
  var $storedTarget;

  $sections.each(function() {
    let $section = $(this);
    let $target = $('.' + year, $section);
    if ($target.length) {

      // Store the target here.
      if(typeof($storedTarget) == "undefined"){
        $storedTarget = $target.first();  // The first one!
      }

      // Animate sections left/right if there's a match
      $section.animate({
        scrollLeft: $section.scrollLeft() + $target.position().left
      }, 1500);

      $section.removeClass('yearNotFound');
    } else {
      $section.addClass('yearNotFound');
    }
  });

  // Make sure there is at least a result..
  if($storedTarget.length>0){

    // Scrolling to the first section that has a match
    $('html, body').animate({
      scrollTop: $storedTarget.offset().top - 128
    }, 1500);

  }
});
Louys Patrice Bessette
  • 33,375
  • 6
  • 36
  • 64
  • Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackoverflow.com/rooms/191201/discussion-on-answer-by-louys-patrice-bessette-how-to-scroll-to-first-child-div). – Samuel Liew Apr 04 '19 at 05:00
  • Let us continue in [chat](https://chat.stackoverflow.com/rooms/191201/discussion-on-answer-by-louys-patrice-bessette-how-to-scroll-to-first-child-div) – Louys Patrice Bessette Apr 04 '19 at 05:03
  • 1
    Beautiful solution. Works like a charm. Thank you @LouysPatriceBessette – Jordy Apr 04 '19 at 05:19