js 实现菜单与内容的联动

菜单与内容联动

  1. 实现思路

 菜单是拥有点击事件 -->采用锚点跳到对应内容
 内容跳转到菜单 --> scroll 滚动事件 计算锚点的offset 和pageYoffset
 给对应菜单目录添加样式

2.实现


为了给不熟悉ES6语法读者更好的体验,代码全部都使用ES5 
<!DOCTYPE html><html><head></head>
    <style>
        /*菜单容器样式,设置水平垂直居中,方便点击*/
        .menu{position: fixed;width: 200px;height: 200px;top: 50%;left: 50%;transform: translate(-50%,-50%);}
        /*菜单样式*/
        [href]{display: inline-block;width: 40px;}
        /*内容的样式*/
        [name]{display: block;width: 300px;height: 400px;border-top: 5px solid salmon;}
        /*菜单高亮的样式*/
        .active{font-size: 32px;background-color: chartreuse;}
    </style>
    <body>
        <!--内容容器-->
        <div class="content"></div>
        <!--菜单容器-->
        <div class="menu"></div>        
    </body></html><script>
//初始化选择器,将获取到的element数组转化为数组对象
function $(selector){
    return Array.prototype.slice.call(document.querySelectorAll(selector))//支持css3的选择器
}
//创建内容和菜单的DOM
function createDom(attr){
    var html = '';
    var temp = attr=='href'?'#':'';
    for (var i=1;i<10;i++) {
        html+='<a '+attr+'="'+(temp+i)+'">'+i+'</a>';
    }
    return html;
}
$('.content')[0].innerHTML = createDom('name')
$('.menu')[0].innerHTML = createDom('href')

//获取内容的偏移量(相对于浏览器顶部)
var nameOffsets = $('[name]').map(function(v){
    return v.offsetTop
});

window.onscroll = function(e){
    //获取当前页面相对于浏览器顶部的偏移量
    var pageOffset = window.pageYOffset;
    var abs = Math.abs; //获取绝对值函数
    //查找离当前浏览器顶部的偏移量最近的菜单锚点.
    var nearHash =  nameOffsets.reduce(function(a,b){
        return abs(a-pageOffset)>abs(b-pageOffset)?b:a;
    })
    //获取菜单锚点
    var index = nameOffsets.indexOf(nearHash);
    //给菜单锚点添加 .active ,移除其他菜单元素的.active
    $('.active').forEach(function(v){
        v.className=''  
    })
    $('[href]')[index].className = 'active'
}
</script>

3.思考


实现方式的优化
onscroll 应该使用throttle 做一个节流,或者使用debounce触发最后一次即可,减少计算的次数..

动态内容解决方案,
将nameOffsets 这个数组在scroll里面获取,这样每次都会重新获取对应的内容的位置,动态内容也能准确定位


未解决的问题,没有考虑id 锚点的情况,没有考虑锚点隐藏(display:none)的情况,


4.总结
实现方式有些粗糙,但也不乏是一种解决思路,针对大多数情况来说,这个已经可以解决问题,缺陷确实难免,毕竟是有感而发,随意为之,后续有时间再来改进.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值