JS 30 是由加拿大的全端工程师 Wes Bos 免费提供的 JavaScript 简单应用课程,课程主打 No Frameworks
、No Compilers
、No Libraries
、No Boilerplate
在30天的30部教学影片里,建立30个JavaScript的有趣小东西。
另外,Wes Bos 也很无私地在 Github 上公开了所有 JS 30 课程的程序码,有兴趣的话可以去 fork 或下载。
实作出能够按住滑鼠左右拖曳的水平卷轴。
卷轴(div.items
)由内部的25个div.item
共同组成。
<div class="items">
<div class="item item1">01</div>
<div class="item item2">02</div>
<div class="item item3">03</div>
<!--中间省略...-->
<div class="item item23">23</div>
<div class="item item24">24</div>
<div class="item item25">25</div>
</div>
宣告常数slider
取得卷轴(div.items
)元素。
宣告变数isDown
作为判断滑鼠是否有被按住的 flag,给定预设值是 false。
宣告变数startX
用来放入之後取得的移动起始点座标。
宣告变数scrollLeft
用来取得div.items
下方 scrollbar 的位置,最左方是 0。
const slider = document.querySelector('.items');
let isDown = false; //flag variable
let startX;
let scrollLeft;
当滑鼠被按住(mousedown) : 把isDown
设为true
。
当滑鼠离开 slider 的范围(mouseleave) : 把isDown
设为false
,因为离开 slider 范围不应再有拖拉的效果(不执行mousemove
里面的内容)。
当放开滑鼠(mouseup) : 把isDown
设为false
,因为mouseup
代表已放开滑鼠。
当滑鼠在 slider 里移动(mousemove) : 先判断滑鼠是否被按住,若没被按住(isDown = false
)则直接跳出方法不往下执行。
slider.addEventListener('mousedown', () => {
isDown = true;
});
slider.addEventListener('mouseleave', () => {
isDown = false;
});
slider.addEventListener('mouseup', () => {
isDown = false;
});
slider.addEventListener('mousemove', () => {
if(!isDown) return; //stop the function from running
});
接下来在按住滑鼠时,在 slider 上添加.active
这个 class,而在滑鼠离开 slider 范围或放开滑鼠时,移除 slider 上的.active
。
.active
这个 CSS class 选择器,用来设定拖拉卷轴时产生的效果,例如处於拖拉状态,卷轴(.items
)会比原来的大小略为放大一点。
event.preventDefault()
用来取消DOM
的预设功能,在这里是避免被 browser 认为想要选取文字之类的。
slider.addEventListener('mousedown', () => {
isDown = true;
slider.classList.add('active');
});
slider.addEventListener('mouseleave', () => {
isDown = false;
slider.classList.remove('active');
});
slider.addEventListener('mouseup', () => {
isDown = false;
slider.classList.remove('active');
});
slider.addEventListener('mousemove', () => {
if(!isDown) return; //stop the function from running
e.preventDefault();
});
在 slider 里面按住滑鼠(mousedown),首先要做的是取得滑鼠在整个 HTML 文件的座标(会随着卷轴移动改变),所以先呼叫e.pageX
。那为什麽还要减去slider.offserLeft
呢? 因为我们要取得的是在 slider 里面的 x 座标,而 slider 刚好有左 margin,所以要减掉offsetLeft
修正再放回startX
(滑鼠在 slider 里的 x 座标)。
宣告常数scrollLeft
放入按住滑鼠时 slider 下方 scrollbar 的位置。
slider.addEventListener('mousedown', (e) => {
//省略...
//know where we click on the slider
startX = e.pageX - slider.offsetLeft;// if the slider has the margin left then we should correct it
scrollLeft = slider.scrollLeft;
console.log(startX);
console.log(scrollLeft);
});
在mousemove event handler
里,宣告常数x
不断更新滑鼠在 slider 内移动的座标,跟上面一样要把 e.pageX 减去 slider.offsetLeft 作 slider 有左 morgin 时的修正。
常数walk
放入移动时的x座标减去起始点的x座标作为移动下方 scrollbar 的依据,把算出来的值乘上3是为了让 scrollbar 移动的距离更加大、明显。
最後,为了让移动时更加顺畅,把先前取得的 scrollLeft 减去 walk,指定卷轴移动的位置和距离大小,这里一定要用减的,因为移动方向和算出来的值刚好差负号。
举例来说按住滑鼠向左拉,此时的卷轴应该要往右(+)移动,但算出的 walk 会是负的,所以要再加上-
号修正。
slider.addEventListener('mousemove', (e) => {
//省略...
const x = e.pageX - slider.offsetLeft;
const walk = (x - startX)*3;
slider.scrollLeft = scrollLeft - walk;
});
Element.scrollLeft
HTMLElement.offsetLeft
MouseEvent.pageX
JS一秒区分clientX,offsetX,screenX,pageX之间关系
<<: Day12 安装外接磁碟机与磁碟片 - 取得 Lua shell script 的参数列
上次我们测试Flask API已经成功了, 但里面的参数例如时间等都是直接写死在程序码里, 但正常来...
设计大纲 昨天设计的「方案」区块的背景设计是单纯一个长方形+背景颜色+阴影。今天想来做点不一样的,所...
如果怕手机关掉东西就不见了 来使用 AsyncStorage 将状态存到手机也就是 local s...
kong的安装我同样会透过operator的方式进行,相信经过了这几天应该很多人都感受到operat...
上一篇介绍了Parking,题目是说在一条很长的道路上,选择任意位子停车,要输出走去各点并回到停车处...