每天一个jquery插件-做锚点吸顶3
做锚点吸顶3
额,今天没有水,今天确实是完成了,昨天的法子行之有效,啥,切水果?没听见,今天就削了个皮,估计还得好几天
下面是效果图
然后我换个方式讲一下,直接放代码然后对着代码讲自己当时的思路,当然实现的方式永远不只一种,并且我这个也是玩弄的插件,严谨和兼容啥的谈不上,但是希望能给大家一个思路。
- html部分
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>做锚点吸顶</title>
<script src="js/jquery-3.4.1.min.js"></script>
<script src="js/mdxd.js"></script>
<link href="css/mdxd.css" rel="stylesheet" type="text/css" />
<style>
#main{
width:70%;
margin: 200px auto;
border: 1px solid lightgray;
}
#main li{
margin-bottom: 400px;
}
</style>
</head>
<body>
<div id="main">
<ul>
<li class="mdxd">标题1</li>
<li class="mdxd">标题2</li>
<li class="mdxd">标题3</li>
<li class="mdxd">标题4</li>
<li class="mdxd">标题5</li>
<li class="mdxd">标题6</li>
<li class="mdxd">标题7</li>
<li class="mdxd">标题8</li>
<li class="mdxd">标题9</li>
</ul>
</div>
</body>
</html>
<script>
$(function(){
var mdxd = zmdxd("mdxd")
mdxd.load();
})
</script>
- 这里没啥好讲的,给自己模拟一个需要的场景,然后再先给上自己觉着有用的参数就行了,其他的直接放到引用文件之中
- css部分
* {
margin: 0;
padding: 0;
}
li{
list-style: none;
}
a{
text-decoration: none;
}
.fz{
width:30px;
position: fixed;
top: 0;
left: 0;
}
.fd{
position: relative;
}
.nobt{
position:static!important;
background-color: lightgray!important;
color: gray!important;
}
.bt{
width: 30px;
height: 30px;
display: flex;
justify-content: center;
align-items: center;
position: absolute;
left: -30px;
top: 0;
border-radius: 50%;
background-color: #2ecc71;
color: white;
}
.bt:hover{
cursor: pointer;
opacity: 0.9;
}
.bt:active{
opacity: 0.8;
}
- 前三个是去掉一些默认参数的影响,.fz是用来做辅助容器的,里面的left会根据目标容器改变位置,js里面会控制,.fd好像是之前原本用来清浮的,但是原本是考虑让辅助容器从指定class的父容器上 absolute出去浮在边上用的,但是效果不好所以当前效果中没用,.nobt和.bt是对应远点的标记的俩状态的,前者是添加到浮动容器之后去除本身的浮动的,后者是用来让标记从目标标题中浮出来挪到左边用的,然后接着的俩伪类就是用来做特效的,就是点击的一般效果
- js部分
var zmdxd = function(cls) {
var $cls = $("."+cls);
$cls.addClass("fd")
for(var i = 0;i<$cls.length;i++){
var $bt = $("<div class='bt' data-index='"+i+"'>"+(i+1)+"</div>");
$bt.appendTo($cls[i])
}
var $par = $cls.parent();
var $dom = $("<div class='fz'></div>")
$dom.css({
"left":$par[0].offsetLeft-30
})
$dom.appendTo($("body"))
return{
$dom:$dom,
$cls:$cls,
load:function(){
var that =this;
$(document).scroll(function(e){
var t = $(this).scrollTop()
for(var i = 0;i<that.$cls.length;i++){
var item = that.$cls[i];
var t2 =item.offsetTop-$dom.height();
if(t2<t){
$(item).children(".bt").addClass("nobt")
$(item).children(".bt").appendTo(that.$dom)
}else{
$(item).children(".bt").removeClass("nobt")
$(".bt[data-index='"+i+"']").removeClass("nobt");
$(".bt[data-index='"+i+"']").appendTo($(item))
}
}
})
$(".bt").click(function(){
var index = $(this).attr("data-index");
var top = that.$cls[index].offsetTop;
console.log(top)
$('html').stop().animate({
scrollTop:top
},500)
})
}
}
}
- js这部分就很简单了,以页面的滚动作为驱动事件,逐个判断拿到的标题处于什么位置,这里面有个参数是
var t2 =item.offsetTop-$dom.height();
,就是刚好让下个节点碰到辅助容器的底部的时候再向上移动就添加进辅助容器,接着下下个标记来的时候这个参数会达到下下个标记的要求再重复同样的效果,然后同一个驱动事件中有合当然有分,只不过是判断的两边的效果而已,把合的效果反着写一遍就行了。最后就是点击跳到指定高度了,这个在之前的滚楼梯特效中用过所以就不做解释了
完事,洗澡碎觉!