Scroll container so that given element becomes visible
by Dmitry
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.js"></script>
<div class="scrollable">
<table>
<tbody>
<tr num="1"><td>Row 1</td></tr>
<tr num="2"><td>Row 2</td></tr>
<tr num="3"><td>Row 3</td></tr>
<tr num="4"><td>Row 4</td></tr>
<tr num="5"><td>Row 5</td></tr>
<tr num="6"><td>Row 6</td></tr>
<tr num="7"><td>Row 7</td></tr>
<tr num="8"><td>Row 8</td></tr>
<tr num="9"><td>Row 9</td></tr>
<tr num="10"><td>Row 10</td></tr>
<tr num="11"><td>Row 11</td></tr>
<tr num="12"><td>Row 12</td></tr>
<tr num="13"><td>Row 13</td></tr>
<tr num="14"><td>Row 14</td></tr>
<tr num="15"><td>Row 15</td></tr>
<tr num="16"><td>Row 16</td></tr>
<tr num="17"><td>Row 17</td></tr>
<tr num="18"><td>Row 18</td></tr>
<tr num="19"><td>Row 19</td></tr>
<tr num="20"><td>Row 20</td></tr>
<tr num="21"><td>Row 21</td></tr>
<tr num="22"><td>Row 22</td></tr>
<tr num="23"><td>Row 23</td></tr>
<tr num="24"><td>Row 24</td></tr>
<tr num="25"><td>Row 25</td></tr>
<tr num="26"><td>Row 26</td></tr>
<tr num="27"><td>Row 27</td></tr>
<tr num="28"><td>Row 28</td></tr>
<tr num="29"><td>Row 29</td></tr>
<tr num="30"><td>Row 30</td></tr>
<tr num="31"><td>Row 31</td></tr>
<tr num="32"><td>Row 32</td></tr>
<tr num="33"><td>Row 33</td></tr>
<tr num="34"><td>Row 34</td></tr>
<tr num="35"><td>Row 35</td></tr>
<tr num="36"><td>Row 36</td></tr>
<tr num="37"><td>Row 37</td></tr>
<tr num="38"><td>Row 38</td></tr>
<tr num="39"><td>Row 39</td></tr>
<tr num="40"><td>Row 40</td></tr>
<tr num="41"><td>Row 41</td></tr>
<tr num="42"><td>Row 42</td></tr>
<tr num="43"><td>Row 43</td></tr>
<tr num="44"><td>Row 44</td></tr>
<tr num="45"><td>Row 45</td></tr>
<tr num="46"><td>Row 46</td></tr>
<tr num="47"><td>Row 47</td></tr>
<tr num="48"><td>Row 48</td></tr>
<tr num="49"><td>Row 49</td></tr>
<tr num="50"><td>Row 50</td></tr>
<tr num="51"><td>Row 51</td></tr>
<tr num="52"><td>Row 52</td></tr>
<tr num="53"><td>Row 53</td></tr>
<tr num="54"><td>Row 54</td></tr>
<tr num="55"><td>Row 55</td></tr>
<tr...
CSS
.scrollable {
overflow-x: auto;
height: 30em;
width: 10%;
}
table {
width: 100%;
border: 1px solid black;
border-collapse: collapse;
}
tr:not(:first-child) {
border-top: 1px solid blue;
}
.focused {
background-color: #FFFFC8;
}
JavaScript
(function($) {
/**
* Scroll container so that given element becomes visible. Features:
* <ol>
* <li>If element is already visible, then no action is taken.
* <li>If element is above view port, the viewport is scrolled upwards so that element becomes visible at the top.
* <li>If element is below view port, the viewport is scrolled downwards so that element becomes visible at the bottom.
* </ol>
*
* @param element
* optional string (selector) or jQuery object that controls the scrolling of the element
* @param options
* optional extra settings
* @param options.animationSpeed
* if defined, then scrolling is animated; determines time in milliseconds after which the element should
* be scrolled into viewport
* @param options.heightScale
* double number from 0 to 1; when scrolling the element from bottom sometimes it is desirable to scroll
* element close to the top; e.g. to scroll it to the center specify 0.5; to scroll it to the top specify 0
* @param options.complete
* function to be called after animation is completed; if there is no animation, the function is called straight away
*/
$.fn.scrollTo = function(element, options) {
options = options || {};
var elementTop = element.offset().top;
var containerTop = this.offset().top;
var newScrollTop = null;
if (elementTop < containerTop) {
// Scroll to the top:
newScrollTop = Math.round(this.scrollTop() + elementTop - containerTop);
} else {
// Scroll to the bottom:
var elementBottom = elementTop + element.outerHeight(true);
var containerHeight = this.height();
if (elementBottom > containerTop + containerHeight) {
if (options.heightScale != null) {
if (options.heightScale === 0) {
// This will effectively turn the formulae below into "elementTop - containerTop":
containerHeight = element.outerHeight(true);
} else {
containerHeight *= options.heightScale;
}
}
newScrollTop =...