我正在研究压延机。
结构很简单:外部div #calender
包含所有日期字段,其中类.field
和ID为#DD-MM-YYYY
。现在,我想要将月份名称放在最前面(“1月”)到2月,当用户滚过#01-02-2015
DIV时依此类推......所以月份名称是动态的。
问题: 如何检测滚动到哪个div?
答案 0 :(得分:1)
您无法真正知道哪个div滚动到。您可以比较div的原始位置(相对于文档),并查看滚动窗口是否已到达该位置。
无论何时请求, window.pageYOffset
都会为您提供文档已滚动到的像素数。现在你需要的是将一个事件监听器附加到scroll
事件,给它#01-02-2015
div的相对文档顶部位置,并检查是否{{1比这更重要。如果是,您可以替换月份名称。如果不是这样,你可以将其更换回来。
要知道相对于文档的window.pageYOffset
div的偏移量,您可以使用jquery的#01-02-2015
函数,或尝试以下内容并让我知道它是否有效:
offset()
(改编自finding element's position relative to the document)
** 编辑 **
所以,正如你所说function getOffsetTop(element){
var offsetTop = 0;
do {
if ( !isNaN( element.offsetTop ) )
offsetTop += element.offsetTop;
} while( element = element.offsetParent );
return offsetTop;
}
函数有效。在页面加载时,您需要获取所有getOffsetTop
div的位置/偏移量,并且假设您还为他们提供了课程或.first
具体月份。因此,让我们从创建这些值的数组开始,例如:
data-id
现在你有一个看起来像var firsts = document.querySelectorAll('.first');
var array = []
for(var i=0;i<firsts.length;i++)
array.push({month:firsts[i].getAttribute('data-id'), offset:getOffsetTop(firsts[i])});
的数组。
同样,在不查看代码的情况下,我认为你需要在加载时声明一个全局(或者在滚动函数之外声明)变量,该变量存储当前月份的索引。 (假设[{month:'january',offset:214},{month:'february',offset:462}...]
为零,则可以从array [0]开始)。 scroll函数需要在本月之前和之后继续检查数组项,以查看是否正在访问其中任何一个滚动点,如果是,则根据需要更改div内容,并更新window.pageYOffset
变量。类似的东西:
currentMonth
我还没有测试过这些,但让我知道你是如何做出来的,或者是否是控制台抛出错误。
** EDIT3 **:MDN参考(link)建议使用var currentMonth = 0;
window.onscroll = function(){
var index = currentMonth;
if(array[index-1] && window.pageYOffset < array[index-1].offset)){
// change the specific div's innerHTML to that of previous one. You can also target a particular `first` by using document.querySelector('.first[data-id="'+array[index].month+"]'):
currentMonth = currentMonth - 1;
}
else if(array[index+1] && window.pageYOffset > array[index+1].offset)){
// change the div to next one
currentMonth = currentMonth + 1;
}
}
代替window.pageYOffset
来实现跨浏览器兼容性,因此我&#39;我更新了我的答案。
答案 1 :(得分:0)
您可以使用.offsetTop
检查每个单元格的当前y
位置,计算当前显示在哪一行,然后通过id
检查当前月份。
for (var i=0; i < rows.length; i++) {
// Select the last day, incase the first few days are still from the previous month
var lastcell = rows[i].querySelector(".field:last-of-type");
// Check if offsetTop is smaller than 100 (leave some error margin)
if (lastcell.offsetTop < 100) {
var id = lastcell.attribute("id").split("-");
var month = id[1];
// Update month
}
}
答案 2 :(得分:0)
我会根据.field
高度和#calendar
的当前滚动来计算它。
您可以使用以下代码获取当前的div滚动:
var position = document.getElementById('calendar').scrollTop;
答案 3 :(得分:0)
在每个月之间添加隐藏的div作为分隔符(为此使用css)。也许每个月应该从新的(css)线开始。然后,您可以通过获取日历的滚动偏移量来查看您所在的月份,并查看哪些分隔符在哪个。假设您知道每个分隔符的偏移量,或者您可以使用jQuery循环并获得更接近的分隔符。< / p>
更新:
在每个月的日期之间添加隐藏的分隔符div,例如<span class="month-separator"></span>
。然后根据定义,这些分隔符将具有不同的offsets
(因为整个月的日期在它们中的每一个之间)。然后,当用户滚动时,计算通过每个分隔符的当前offset
循环,并查看偏移量是否接近其中一个:
伪码:
var calendarScroll = calendar.pageYOffset; // compute this
var whichMonth = 1; // start with january, i.e 1st month
// for each month separator
$('.month-separator').each(function(index){
// break when encountering the month that is not yet scrolled to
if ($(this).offset().top > calendarScroll)
{
whichMonth = index;
return false; // break from each loop
}
});
您可能希望将上面的代码放在滚动处理程序中,如window.onscroll
事件处理程序(例如,请参阅example with sticky header on scroll here)。
答案 4 :(得分:0)
假设您已经准备好了代码以突出显示滚动的下一个日期,那么您可能会在下一个日期突出显示该句柄。一个简单的方法是滚动,获取突出显示的div的值(应该是日期)。如果值=== 1,它是新月的第一个,所以显示下个月。
要获得下个月,您可以存储所有月份的数组,然后迭代数组。如果当前迭代等于日历上的当前月份,则返回数组的下一个元素
function getNextMonth(current_month) {
var month_array = [
'January',
'February',
'March',
'etc'
];
$.each(month_array, function(month, foo) {
if(month == current_month) {
return month_array[($.inArray(current_month, month_array) + 1) % month_array.length];
}
});
}
var calendar = $('calendar');
calendar.hover(function() {
calendar.scroll(function() {
//Your logic to change highlighted div
var current_date = $('#datediv').val(),//However you are selecting your current date div
month = $('#month_div');
if(current_date === 1) {
var next_month = getNextMonth(month);
month.val(next_month);
}
});
});
老实说,从用户的角度来看,在日历上滚动日期是很奇怪的。对于我见过的大多数日历,滚动会改变月份。这可能是一种更好的设计方法,除非你必须按照你现在的方式去做。