blob: 6fbaf533c1360f8c713e0459457ac1d380a2a972 [file]
/**[Public]
* 导航电梯功能,可选
*
*/
define([
"jQuery",
"Mousetrap"
], function($, Mousetrap){
/**[public]
* 根据提供的ID数组
* @param {[Array]} navId 元素ID属性(带#号)数组
*
* @return {[Array]} 返回对应的距离顶部数值
*/
var getTopValue = function(navId,offset){
var topValueSet = [];
var offset = offset || 0; // 可能需要修正,比如要考虑头部高度
// 循环遍历获取每个条目到顶部的距离值
for(var i = 0;i<navId.length;i++){
topValueSet.push(+$(''+navId[i]).offset().top + offset);
}
return topValueSet;
};
/**[public]
* 获取该值所在的区间范围的索引值
* @param {[int]} value 数值
* @param {[Array]} valueSet 数值所在的数组
* @param {[int]} offset 偏移值
*
* @return {[int]} 区间所在索引值
*/
var getCurrentPos = function(value,valueSet,offset){
var offset = offset || 0;
var index = -1; // 最上面的区域定义index为-1
var value = value + offset ; // 这里添加一个固定的值作为偏移
for(var i = 0;i<valueSet.length;i++){
if(value < valueSet[0]){
return index + 1; // 为了视觉连贯,让在第一屏的时候也高亮第一个标签
}else if(value > valueSet[valueSet.length-1]){
return index+valueSet.length;
}else if(value < valueSet[i] && valueSet[i-1] && value > valueSet[i-1]){
return index+i;
}
}
}
/**[public]
*
* 初始化电梯组件
* @param {[jQuery]} $toc 目录对象
*
* @return none 添加scroll事件,完成电梯功能
*/
var init = function($toc) {
// 所有的标题链接是存储在目录a标签里的
var navId = [];
var menu = $toc.find(".gtoc-menu");
var link = menu.find("a");
var scrollBody = $(".body-inner,.book-body");
link.each(function(){
var node = $(this);
navId.push(node.attr("href"));
// 为了防止出现"闪烁"问题,需要修改href属性
node.data("href",node.attr("href"));
node.attr("href","javascript:void(0);");
});
// 将所有标题距离顶部的距离放置在topValue数组中
var topValueSet = getTopValue(navId,0); // 后面的数值用于修正
// 获取当前点击的Index值
menu.on("click","a",function(){
var index = link.index(this); // 获取当前链接索引值
// 滚动到目标地址
scrollBody.animate({scrollTop:+topValueSet[index]},'1000',"linear");
link.removeClass("state-current");
$(this).addClass("state-current");
});
// 添加滚动事件,增加电梯
scrollBody.on("scroll",function(){
// 先清除掉所有的active样式
link.removeClass("state-current");
// 获取当前滚动条的距离
var topValue = Math.max(scrollBody[0].scrollTop,scrollBody[1].scrollTop);// 获取实际滚动距离
// 根据距离判断应当让哪个导航高亮
var nIndex = getCurrentPos(topValue,topValueSet,40);
$(link[nIndex]).addClass("state-current");
});
};
return {
init: init,
getTopValue:getTopValue,
getCurrentPos:getCurrentPos
};
});