Day4-自制网站卷轴(中)_想要更多造型

今天开始来写出自制的卷轴,构想是这样子的
https://ithelp.ithome.com.tw/upload/images/20210918/20141991p1oER6OqBj.png
根据构想先把框架写出来

<div class="text_box ">
    <div class="my-scroll">
        <div class="scroll-bar" id="draggable"></div>
    </div>
    <div id="text_content">
        <img src="…" style="width: 100%;">
        ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz</br>
        ………
    </div>
</div>

卷轴的部分会分成轨道跟拉杆(会跟着内文动的那个部分),拉杆在轨道内
因为卷轴需要浮在内文上方,所以先把text_content跟my-scroll设定成position: absolute;
并对my-scroll设定right: 0; height: 100%; 让他置右跟预设卷轴位置重叠
然後拉杆需要在轨道内乖乖待着,所以另外把scroll-bar设定成position: relative;
为了方便观看这边先个别设定颜色跟长度,宽度的部分就是自己喜欢就好
设好之後会长这样
https://ithelp.ithome.com.tw/upload/images/20210918/20141991aPiNt8Tk04.jpg

图上可以看到我把轨道的宽度设成比拉杆宽,这样子当轨道颜色拔掉时,就能让拉杆有上一篇提到的「跟边框有一些距离」的效果

接下来放入一些内文来让text_content自己长大
这边同样需要对最外框的text_box设定overflow: auto; 或overflow: overlay;
没设定的话text_content会冲出去外面像这样
https://ithelp.ithome.com.tw/upload/images/20210918/20141991vOi6P7dgf0.jpg
再来就是因为我们虽然会自己做出假的卷轴,却没办法做出卷动的效果,所以还是需要使用到CSS本身卷轴的卷动功能
设定好overflow後,会发现我们自制的卷轴被CSS做出来的卷轴挡住
https://ithelp.ithome.com.tw/upload/images/20210918/201419910R0F0DPCQJ.jpg
所以我们需要把CSS的卷轴隐藏起来
这边我们要利用上一篇有使用到的chrome卷轴语法
直接把预设卷轴颜色设成透明的

.text_box::-webkit-scrollbar {
    background: transparent;
}

就会发现我们成功把卷轴隐藏了,但依旧保有卷轴的功能在
https://i.imgur.com/QhXoWQe.gif
同时也会发现,因为原本的卷轴比较宽,所以会发生没点在卷轴上,内文却可以移动的状况,这时候我们就要依据我们自制卷轴的宽度,去让预设卷轴的宽度与自制的卷轴完全相符
这边我的my-scroll是设定width: 7px; 为了点击比较好点,预设卷轴就设定成9px

.text_box::-webkit-scrollbar {
    width: 9px;
    background: transparent;
}

CSS的部分就到这边,接下来我们要进入JS了
前一张动图中应该有发现,虽然我们预设的卷轴有在作用,但我们的漂亮卷轴一卷就跟着内文跑上去了
这是因为my-scroll的预设top: 0; 如果父层text_box卷轴卷动,text_box的内容就会被往上卷,「0」的位置也会被拉上去,像是图片这样
https://ithelp.ithome.com.tw/upload/images/20210918/20141991dALVaOet3G.png
所以我们需要让my-scroll的top自己改变数值,这个就要在JS中抓取东西给my-scroll使用了

首先我们要有一个概念
如果要让my-scroll一直存在我们的视线中,它的top值就必须跟我们卷轴卷动的量是一样的,往下卷就增加,往上卷就减少
这里要用到.scrollTop()这个函数,它的作用是可以侦测目前卷动的位置距离顶层多少数值
而我们需要在「卷动当下」不断地侦测然後把数字给my-scroll,所以要这样子写

$('.text_box').scroll(function () {
    $('.my-scroll').attr("style", "top:" +$(this).scrollTop() + "px");
})

因为.scrollTop()给的只有数值,但top需要有px,所以我们要自己补充px给它,然後我们的my-scroll就会像是停在原地一样不动了
https://i.imgur.com/7bgrQNr.gif

接下来是需要思考的地方
我们无法每一次都帮内文卡好一个死死的数字,然後手动都去计算「拉杆」需要多长
所以我们要让JS去帮我们计算并设定我们的拉杆长度,这边先把为了方便截图而设定好的scroll-bar高度拿掉
https://ithelp.ithome.com.tw/upload/images/20210918/20141991M2r9oCXodn.jpg

然後看看这张图
https://ithelp.ithome.com.tw/upload/images/20210918/20141991nXjfiCpcIw.png
从图上我们看出
整体长度 : 可视长度 = 卷轴长度 : 拉杆长度
根据数学计算可以得出
拉杆长度 = 可视长度 * 卷轴长度 / 整体长度
知道算法後我们在JS中写入

var scroll_h = $('.text_box').height() * $('.my-scroll').height() / $('#text_content').height();
$('.scroll-bar').attr("style", "height:" + scroll_h + "px");

利用JS去计算拉杆长度後,就不用担心内文有增减而必须去改其他拉杆相关的数值了!!
https://ithelp.ithome.com.tw/upload/images/20210918/20141991z7aAjNDwl1.jpg

接着我们要让自制的拉杆也能像卷轴一样卷动
刚刚我们已经知道要怎麽去获得卷动的数值,但因为我们的拉杆移动的范围只在my-scroll之中,所以原本卷动的数值我们也要按比例做缩小
换算完再给拉杆做使用,整体的JS程序码是这样

/*--自制假滚轮--*/
    var scroll_h = $('.text_box').height() * $('.my-scroll').height() / $('#text_content').height();
    $('.scroll-bar').attr("style", "height:" + scroll_h + "px");
    var scroll_ = 0;  //滚动多少
    var scroll_float = 0;
    var scale_ = $('#text_content').height() / $('.text_box').height() //可视范围占整体比例
    $('.text_box').scroll(function () {
        scroll_ = $(this).scrollTop()
        scroll_float = scroll_ / scale_ //总滚动大小转换成可视范围比例大小
        $('.my-scroll').attr("style", "top:" + $(this).scrollTop() + "px");
        $('.scroll-bar').attr("style", "top:" + scroll_float + "px;height:" + scroll_h + "px");
    })

这样就完成自制假滚轮的样子啦!!
https://i.imgur.com/pepkxVi.gif

然後我们就可以利用改变div的z-index数值,做出平时在图片下面,hover时在图片上面的效果了
把辣眼睛的颜色都拿掉後就完成啦!!
https://i.imgur.com/a6pA1Oe.gif
也能在hover时让拉杆出现不同颜色或透明度之类的!!

明天写这个系列最後一篇,如果我就特立独行想把拉杆放左边或中间那该怎麽做呢?


<<:  Day 4: 人工智慧在音乐领域的应用 (AI发展史与简介 - 第一次寒冬)

>>:  第 4 集:CSS 盒模型(box model)

入门魔法 - 针对 DOM 节点的简单操作

前情提要 上回说了希望选择学习火属性魔法後,艾草带我走到一棵大树下。 艾草:「来尝试用自己现有的魔力...

D29-(9/29)-广达(2382)-有肉松之称的电脑代工厂

注:发文日和截图的日期不一定是同一天,所以价格计算上和当日不同,是很正常的。 声明:这一系列文章并无...

第10车厢-你今天table了吗?tableRWD+简易分页应用篇

本篇延续<第9车厢-使用content:attr()实现tableRWD应用>的版,透过程序自动产...

企业资料通讯Week7 (2) | rdt(reliable data transfer)[下]

rdt3.0 rdt3.0 开始考虑到packet loss的情形,它怎麽解决呢? 喔喔~原来是采用...

DAY11 - [JS] 经典的ToDoList

今日文章目录 ToDoList 需求 事前准备 参考资料 ToDoList 需求 Q: 需要有哪些...