1

I'm working with multiple ordered-lists <ol>

Each <ol> has one <li> with class .highlight

Problem:

Sometimes the highlighted <li> is located somewhere down the scrollable <ol> and therefor not visible.

   highlighted list           highlighted list   
   item not visible             item visible
 ____________________       ____________________
|                    |     |                    |
|   browser window   |     |   browser window   | 
|____________________|     |____________________|
|                    |     |                    |
|   List:            |     |   List:            |
|   1. green         |     |   1. green         |
|   2. blue          |     |** 2. blue **       |
|   3. red           |     |   3. red           |  
 --------------------       --------------------
    4. brown                   4. brown     
    5. purple                  5. purple        
    6. yellow                  6. yellow
 ** 7. pink **                 7. pink
    8. orange                  8. orange

Solution?

Scroll the <li> with class .highlight to the top of each <ol>

else

At least scroll the <li> with class .highlight into view inside each <ol>

Project Link:

http://www.paintings.directory

Hover over image to add class .highlight to corresponding list-items. (artist, artwork, year, ...)

Often the highlighted <li> is located low inside the <ol>and therefor I cannot see them. -_-"

How do I scroll into view the highlighted <li> inside each <ol>?

What I tried in jQuery:

$('ol > li.highlight').animate({ scrollTop: $('ol').height() }, "slow");

What I also tried in jQuery:

I tried implementing .scrollIntoView(); as follows:

$('img').hover(function() {
        var classes = $(this).attr('class').split(" ").map(function(value) {
            return "." + value;
        }).join(",")
        $('section > ol > li' + classes).addClass('highlight');

        
        $('.highlight').scrollIntoView(); //  <---


    }, function() {
        $('section > ol > li').removeClass('highlight');
});

Research:

I found these helpful, but was unable to implement properly:

  1. https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
  2. https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollLeft
  3. https://codepen.io/ayoungh/pen/Vjzvdk
Jordy
  • 347
  • 2
  • 11

3 Answers3

0

You can use scrollIntoView, but it won't animate, it will jump:

jQuery('button').on('click',(e)=>{
  jQuery(".scrolltome")[0].scrollIntoView();
});
ul {
  list-style: none;
  height: 100px;
  overflow-x: hidden;
  overflow-y: scroll;
}
  li {
    height: 30px;
    background: #ccc;
    border-bottom: black 1px solid;
  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<ul>


  <li>item 11</li>
  <li>item 12</li>
  <li>item 13</li>

  <li>item 11</li>
  <li>item 12</li>
  <li>item 13</li>

  <li>item 11</li>
  <li>item 12</li>
  <li>item 13</li>

  <li class='scrolltome'>item 14 scroll to</li>

  <li>item 15</li>
  <li>item 16</li>
  <li>item 17</li>
  <li>item 18</li>
  <li>item 19</li>
  <li>item 20</li>

</ul>

<button>!scroll now!</button>
freedomn-m
  • 27,664
  • 8
  • 35
  • 57
0

If you want all the ol's to scroll to the active class, you can use the following:

$(document).ready(function(){
        active_scroll($('.active'));
    });

    function active_scroll(identifier){
        const yOffset = -30; // adjust if needed (pixel offset)
        var id_class = identifier.attr('class'),
        // element
        element = document.getElementsByClassName(id_class);
        // loop though found
        $.each(element, function(index, item) {
            var y = item.offsetTop + yOffset;
            $(item.parentElement).animate({scrollTop: y},'slow');
        });
    }

You can ofcourse also bind it to a button click of something like that. Just call active_scroll($('.active'))

hixlax
  • 31
  • 5
0

As highlight class will get added dynamically and to different lis in ol tag so you need to loop through each highlight class and then use $(this)[0].scrollIntoView(); to scroll at required li .

Demo Code :

$('img').hover(function() {
  //get class split it and then generated comma seperated value..
  var classes = $(this).attr('class').split(" ").map(function(value) {
    return "li." + value;
  }).join(",")
  $(classes).addClass('highlight'); //add there classs
  //get all highlight ..
  $("section > ol > li.highlight").each(function() {
    $(this)[0].scrollIntoView(); //scroll there
  })
}, function() {
  $('ol > li').removeClass('highlight'); //remove class
});
.highlight {
  color: red;
}

img {
  width: 100px;
  height: 100px
}

ol {
  width: 100%;
  overflow: hidden;
  padding: 0 0 10px 0;
  margin: 0;
  border-bottom: 1px solid gainsboro;
}

section {
  position: relative;
  display: block;
  float: left;
  width: 30%;
  height: 100px;
  box-sizing: border-box;
  overflow-y: scroll;
}

ol li {
  list-style-type: none;
  list-style-position: inside;
  margin: 0;
  padding: 0 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<img src="https://www.ultimatesource.toys/wp-content/uploads/2013/11/dummy-image-portrait-1.jpg" class="year_2010 artist_picasso color_green">
<img src="https://www.ultimatesource.toys/wp-content/uploads/2013/11/dummy-image-portrait-1.jpg" class="year_2009 artist_matisse color_blue">
<img src="https://www.ultimatesource.toys/wp-content/uploads/2013/11/dummy-image-portrait-1.jpg" class="year_2011 artist_matisse color_orange">
<br/>
<section>
  <ol>
    <h1>year</h1>
    <li class="year_2008">2008</li>
    <li class="year_2009">2009</li>
    <li class="year_2001">2001</li>
    <li class="year_2002">2002</li>
    <li class="year_2003">2003</li>
    <li class="year_2010">2010</li>
    <li class="year_2011">2011</li>
  </ol>
</section>
<section>
  <ol>
    <h1>artist</h1>
    <li class="year_DavidHockney">Hockney</li>
    <li class="artist_matisse">Matisse</li>
    <li class="artist_matisse1">Matisse1</li>
    <li class="artist_matisse1">Matisse1</li>
    <li class="artist_miro">Miro</li>
    <li class="year_DavidHockney">Hockney2</li>
    <li class="year_DavidHockney">Hockney2</li>
    <li class="artist_picasso">Picasso</li>
  </ol>
</section>
<section>
  <ol>
    <h1>color</h1>
    <li class="color_blue">Blue</li>
    <li class="color_gred">gren</li>
    <li class="color_red">red</li>
    <li class="color_yeloow">yelow</li>
    <li class="color_green">Green</li>
    <li class="color_red">Red</li>
    <li class="color_pink">pink</li>
    <li class="color_orange">orange</li>
  </ol>
</section>
Swati
  • 28,069
  • 4
  • 21
  • 41
  • Elegant solution. What precisely does [0] do? Is this the offset? – Jordy Jun 29 '21 at 07:00
  • 1
    Check [this](https://stackoverflow.com/questions/32783869/what-does-selector0-mean-in-jquery) post will give you good explanation :) – Swati Jun 29 '21 at 07:06