I have a view-port div which is 48px high and 400px wide. Inside that view-port, I have another div which contains a list of divs. Each of the divs in the list are 48px high and 400px wide. There is obviously an overflow here and the goal is to have it so when the user stops scrolling it will find the closest element to the view-port. My code is below:
javascript, html, and css:
var i; window.onload = function(){ var timer = null; var optionsScrollTop = 0; var selectLists = document.getElementsByClassName('selectList'); for(i = 0; i != selectLists.length; i++) { var currentElement = i; document.getElementsByClassName('selectList')[currentElement].onmouseover = function() { //alert(currentElement+' mousover'); document.getElementById('contentContainer').style.overflow = 'hidden'; }; document.getElementsByClassName('selectList')[currentElement].onmouseout = function() { //alert(currentElement+' mouseout'); document.getElementById('contentContainer').style.overflow = 'auto'; }; var options = document.getElementsByClassName('selectList')[currentElement].getElementsByClassName('selectListOptions')[0].getElementsByClassName('option'); for(var j = 0; j != options.length; j++) { var oldTitle = ''; options[j].onmouseover = function() { this.parentElement.parentElement.title = this.title; oldTitle = this.title; this.title = ''; }; options[j].onmouseout = function() { this.title = oldTitle; }; } document.getElementsByClassName('selectList')[currentElement].onscroll = function() { if(timer !== null) { clearTimeout(timer); } timer = setTimeout(function(){ var allOptionOffsets = []; var selectViewPortOffset = document.getElementsByClassName('selectList')[currentElement].offsetTop; var options = document.getElementsByClassName('selectList')[currentElement].getElementsByClassName('selectListOptions')[0].getElementsByClassName('option'); for(var i = 0; i != options.length; i++) { allOptionOffsets.push(options[i].offsetTop); //selectViewPortOffset } for(var i = 0; i != allOptionOffsets.length; i++) { alert(allOptionOffsets[i]+' element '+i); alert('viewport offset: '+selectViewPortOffset); if(allOptionOffsets[i] == selectViewPortOffset-24 || allOptionOffsets[i] == selectViewPortOffset+24) { alert(i+' is closest'); } //selectViewPortOffset /*if(allOptionOffsets[i]-selectViewPortOffset > 0) { if(allOptionOffsets[i]-selectViewPortOffset < 48) { document.getElementsByClassName('selectList')[currentElement].scrollTop = allOptionOffsets[i]-selectViewPortOffset; } }*/ //alert(allOptionOffsets[i]); } }, 1000); }; } }; /* var viewPortOffset = document.getElementsByClassName('selectList')[currentElement].offsetTop; var optionsOffset = []; var options = document.getElementsByClassName('selectList')[currentElement].getElementsByClassName('selectListOptions')[0].getElementsByClassName('option'); for(var i = 0; i != options.length; i++) { var optionOffset = document.getElementsByClassName('selectList')[currentElement].getElementsByClassName('selectListOptions')[0].getElementsByClassName('option')[i].offsetTop; optionsOffset.push(optionOffset); } for(var i = 0; i < optionsOffset.length; i++) { alert(optionsOffset[i]); } */
.selectList { width:400px; height:48px; border:2px solid #000; border-radius:5px; overflow:auto; } .selectListOptions { text-align:center; } .selectListOptions .option { font-size:30px; height:48px; text-align:center; border-top:1px solid #000; border-bottom:1px solid #000; -o-box-sizing:border-box; -webkit-box-sizing:border-box; -moz-box-sizing:border-box; -ms-box-sizing:border-box; box-sizing:border-box; } .selectListOptions .label { font-size:30px; height:48px; text-align:center; border-top:1px solid #000; border-bottom:1px solid #000; }
<div id="simulatorOfOtherContentThisNormalyWouldn'tBeHere" style="padding:10%"> <div class="selectList" id="incomingMessageSound"> <div class="selectListOptions"> <div class="label option" title='optionDefault'>Incoming Message Sound</div> <div class="option" title='option2'>Sound 1</div> <div class="option" title='option3'>Sound 2</div> <div class="option" title='option4'>Sound 3</div> <div class="option" title='option5'>Sound 4</div> <div class="option" title='option6'>Sound 5</div> </div> </div> </div>
This should do it if I understood correctly (I used jQuery to save some lines):
function goToClosest(){
clearTimeout(window.lastTimeout);
window.lastTimeout = setTimeout(function(){
var BaseOffset = $('.selectList').offset().top + 2, // I add 2 because of border top
ViewrportHeight = $('.selectList').height(),
ScrollTop = $('.selectList').scrollTop(),
distSum = 0,
closest,closestDist,closestScrollTop;
$('.selectListOptions > div').each(function(i,e){
var e = $(e);
var distance = Math.abs(e.offset().top - BaseOffset);
if(!closest || closestDist > distance){
closest = e;
closestDist = distance;
closestScrollTop = distSum;
}
distSum += e.height() + 2; // Again +2 for border
});
$('.selectList').animate({scrollTop:closestScrollTop+'px'},300,'swing');
},1000);
}
$(document).ready(function(){
$('.selectList').scroll(goToClosest);
});
Fiddle: https://jsfiddle.net/8d7Ln5mc/
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.