这一天我们把前面所学的知识做一个总结联系。
昨天,我们学习了一系列的获取鼠标坐标的方法,接下来我会用一个拖拽的案例给大家贯通一下。

html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>动态拖拽</title>
<style>
* {
padding: 0;
margin: 0;
}
.d {
width: 150px;
height: 150px;
background-color: aliceblue;
position: absolute; /* 必须设置定位 */
cursor: move; /* 鼠标悬停时显示拖拽图标 */
}
html,
body {
width: 100%;
height: 100%;
background-color: antiquewhite;
position: relative; /* 作为.d的定位父级 */
}
</style>
</head>
<body>
<div class="b">
<div class="d"></div>
</div>
</body>
<script>
let d = document.querySelector('.d');
let isDragging = false; // 标记是否正在拖拽
let offsetX, offsetY; // 鼠标在元素内的偏移量(关键)
// 1. 鼠标按下:开始拖拽,记录偏移量
d.onmousedown = (e) => {
isDragging = true;
// 获取元素相对于视口的位置
const rect = d.getBoundingClientRect();
// 计算鼠标在元素内的偏移量(鼠标位置 - 元素左上角位置)
offsetX = e.clientX - rect.left;
offsetY = e.clientY - rect.top;
}
// 2. 鼠标移动:实时更新元素位置(绑定在document上,避免鼠标移出元素后中断)
document.onmousemove = (e) => {
if (!isDragging) return; // 没在拖拽就不执行
// 计算元素新位置:鼠标当前位置 - 偏移量(保证鼠标在元素内的相对位置不变)
const newLeft = e.clientX - offsetX;
const newTop = e.clientY - offsetY;
// 更新元素位置(相对于定位父级body)
d.style.left = newLeft + 'px';
d.style.top = newTop + 'px';
}
// 3. 鼠标松开:结束拖拽
document.onmouseup = () => {
isDragging = false;
}
</script>
</html>
数组方法
some
some(function(原数元素,下标){}):检测数组中是否存在至少一个 符合条件的元素,返回 true 或 false。找到一个符合条件的元素后立即停止遍历。
every
every(function(原数元素,下标){}):检测数组中是否存在至少一个 符合条件的元素,返回 true 或 false。只要有一个元素不符合,立即返回 false。
需求:做一个全选反选的案例

html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="checkbox">全选<br>
<input type="checkbox" class="c">1 <br>
<input type="checkbox" class="c">2<br>
<input type="checkbox" class="c">3<br>
<input type="checkbox" class="c">4
</body>
<script>
let q = document.querySelector('input')
let cs = document.querySelectorAll('.c')
q.onclick = ()=>{
cs.forEach(item=>item.checked = q.checked)
}
cs.forEach(item=>{
item.onclick = ()=>{
q.checked = Array.from(cs).every(e=>e.checked)
}
})
</script>
</html>
动态添加表格数据
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="checkbox">全选<br>
<input type="checkbox" class="c">1 <br>
<input type="checkbox" class="c">2<br>
<input type="checkbox" class="c">3<br>
<input type="checkbox" class="c">4
</body>
<script>
let q = document.querySelector('input')
let cs = document.querySelectorAll('.c')
console.log(cs.keys());
q.onclick = ()=>{
cs.forEach(item=>item.checked = q.checked)
}
cs.forEach(item=>{
item.onclick = ()=>{
q.checked = Array.from(cs).every(e=>e.checked)
}
})
</script>
</html>
瀑布流
reduce
reduce 是数组中最灵活的方法之一,核心功能是将数组元素通过回调函数 "累积" 为一个单一值(这个值可以是数字、对象、数组等任意类型)。它的逻辑类似 "滚雪球":从初始值开始,每一步都用当前元素更新累积结果,最终得到一个汇总值。
1. 回调函数(必选)
每次遍历数组时执行的函数,接收 4 个参数:
accumulator(累加器):上一次回调的返回值(或初始值),是 "累积的结果"。currentValue:当前正在处理的数组元素。currentIndex(可选):当前元素的索引(从 0 开始)。array(可选):原数组本身。
回调函数的返回值会作为下一次的 accumulator,直到数组遍历结束,最终返回的 accumulator 就是 reduce 的结果。
2. 初始值(可选)
- 若提供初始值:
accumulator初始化为该值,从数组第一个元素开始遍历。 - 若不提供初始值:
accumulator初始化为数组第一个元素 ,从第二个元素开始遍历。
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
* {
padding: 0;
margin: 0;
}
.header {
background-color: yellow;
height: 200px;
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 10px;
}
.content {
display: flex;
width: 100%;
flex-wrap: wrap;
justify-content: space-around;
background-color: antiquewhite;
}
.t {
margin: 10px;
/* height: 220px; */
width: 23%;
/* background-color: rgb(192, 93, 44); */
text-align: center;
}
.t img {
width: 150px;
}
.floor {
height: 100px;
display: flex;
justify-content: center;
align-items: center;
background-color: aliceblue;
}
.loading {
display: flex;
justify-content: center;
}
.loading img {
display: none;
}
</style>
<body>
<div class="header">
<h1>halo影视院</h1>
</div>
<div class="content">
<!-- <div class="t">
<img src="https://ts1.tc.mm.bing.net/th/id/R-C.676ee92824bbf8834ad26e12fefee497?rik=1F%2fTkzSGixqpLw&riu=http%3a%2f%2fimg.touxiangkong.com%2fuploads%2fallimg%2f2021111619%2fjqvmt4ltlzy.jpg&ehk=OJaxSBn%2f%2f8c5LFYAIlqXRyJk9AT5YEcUQnwQBdK77jM%3d&risl=&pid=ImgRaw&r=0" alt="">
<p>1111</p>
<p>1111</p>
</div>
<div class="t">
<img src="https://ts1.tc.mm.bing.net/th/id/R-C.676ee92824bbf8834ad26e12fefee497?rik=1F%2fTkzSGixqpLw&riu=http%3a%2f%2fimg.touxiangkong.com%2fuploads%2fallimg%2f2021111619%2fjqvmt4ltlzy.jpg&ehk=OJaxSBn%2f%2f8c5LFYAIlqXRyJk9AT5YEcUQnwQBdK77jM%3d&risl=&pid=ImgRaw&r=0" alt="">
<p>1111</p>
<p>1111</p>
</div>
<div class="t">
<img src="https://ts1.tc.mm.bing.net/th/id/R-C.676ee92824bbf8834ad26e12fefee497?rik=1F%2fTkzSGixqpLw&riu=http%3a%2f%2fimg.touxiangkong.com%2fuploads%2fallimg%2f2021111619%2fjqvmt4ltlzy.jpg&ehk=OJaxSBn%2f%2f8c5LFYAIlqXRyJk9AT5YEcUQnwQBdK77jM%3d&risl=&pid=ImgRaw&r=0" alt="">
<p>1111</p>
<p>1111</p>
</div>
<div class="t">
<img src="https://ts1.tc.mm.bing.net/th/id/R-C.676ee92824bbf8834ad26e12fefee497?rik=1F%2fTkzSGixqpLw&riu=http%3a%2f%2fimg.touxiangkong.com%2fuploads%2fallimg%2f2021111619%2fjqvmt4ltlzy.jpg&ehk=OJaxSBn%2f%2f8c5LFYAIlqXRyJk9AT5YEcUQnwQBdK77jM%3d&risl=&pid=ImgRaw&r=0" alt="">
<p>1111</p>
<p>1111</p>
</div>
<div class="t">
<img src="https://ts1.tc.mm.bing.net/th/id/R-C.676ee92824bbf8834ad26e12fefee497?rik=1F%2fTkzSGixqpLw&riu=http%3a%2f%2fimg.touxiangkong.com%2fuploads%2fallimg%2f2021111619%2fjqvmt4ltlzy.jpg&ehk=OJaxSBn%2f%2f8c5LFYAIlqXRyJk9AT5YEcUQnwQBdK77jM%3d&risl=&pid=ImgRaw&r=0" alt="">
<p>1111</p>
<p>1111</p>
</div>
<div class="t">
<img src="https://ts1.tc.mm.bing.net/th/id/R-C.676ee92824bbf8834ad26e12fefee497?rik=1F%2fTkzSGixqpLw&riu=http%3a%2f%2fimg.touxiangkong.com%2fuploads%2fallimg%2f2021111619%2fjqvmt4ltlzy.jpg&ehk=OJaxSBn%2f%2f8c5LFYAIlqXRyJk9AT5YEcUQnwQBdK77jM%3d&risl=&pid=ImgRaw&r=0" alt="">
<p>1111</p>
<p>1111</p>
</div>
<div class="t">
<img src="https://ts1.tc.mm.bing.net/th/id/R-C.676ee92824bbf8834ad26e12fefee497?rik=1F%2fTkzSGixqpLw&riu=http%3a%2f%2fimg.touxiangkong.com%2fuploads%2fallimg%2f2021111619%2fjqvmt4ltlzy.jpg&ehk=OJaxSBn%2f%2f8c5LFYAIlqXRyJk9AT5YEcUQnwQBdK77jM%3d&risl=&pid=ImgRaw&r=0" alt="">
<p>1111</p>
<p>1111</p>
</div>
<div class="t">
<img src="https://ts1.tc.mm.bing.net/th/id/R-C.676ee92824bbf8834ad26e12fefee497?rik=1F%2fTkzSGixqpLw&riu=http%3a%2f%2fimg.touxiangkong.com%2fuploads%2fallimg%2f2021111619%2fjqvmt4ltlzy.jpg&ehk=OJaxSBn%2f%2f8c5LFYAIlqXRyJk9AT5YEcUQnwQBdK77jM%3d&risl=&pid=ImgRaw&r=0" alt="">
<p>1111</p>
<p>1111</p>
</div> -->
</div>
<div class="loading">
<img src="./1.gif" alt="">
</div>
<div class="floor">
<h2>我是底线哦~</h1>
</div>
</body>
<script src="./dm_list.js"></script>
<script>
let oCon = document.querySelector('.content');
let loadingImg = document.querySelector(".loading>img")
let currentNum = 1;//当前页码
let pageNum = 8;
let total = Math.ceil(list.length / pageNum)
let flag = false//给加载一个标识,避免重复加载
function getContent() {
let arr = list.slice((currentNum - 1) * pageNum, pageNum*currentNum)
console.log((currentNum - 1) * pageNum+" "+pageNum*currentNum);
// console.log(arr);
// console.log(list.length);
oCon.innerHTML += arr.reduce((pre, cur) => pre +
`<div class="t">
<img src="${cur.pic}" alt="">
<p>${cur.address}</p>
<p>${cur.name}</p>
</div>`
, '');//第二个参数为空的效果是第一个pre作为第一个返回值
}
getContent()
window.onscroll = (e)=>{
if(flag) return
if(currentNum>total){//到最后一页了,就不再加载了
loadingImg.style.display = 'none'
// console.log(currentNum+"===="+total);
return;
}
flag = true//标记正在加载数据
//滚动事件
//
let currentHeight = innerHeight//可见到的浏览器高度,也就是一屏的高度
let currentTop = document.documentElement.scrollTop//滚动的高度
let lastHeight = document.documentElement.scrollHeight//元素总高度,整个网页的高度
if(currentHeight+currentTop>=lastHeight/2){
loadingImg.style.display = 'block'
setTimeout(()=>{
console.log('-----'+currentNum);
currentNum++;
getContent();
flag = false;
loadingImg.style.display = 'none'
},2000)
}
}
</script>
</html>
dm_list.js:
html
var list = [{ "id": 625153951363, "name": "2020西太湖国际音乐节", "showTime": "2020.09.19-09.20", "price": "199-399", "city": "常州", "address": "常州西太湖中国花卉博览景区北门", "pic": "https://img.alicdn.com/bao/uploaded/https://img.alicdn.com/imgextra/i3/2251059038/O1CN01zJEpaN2GdSG1Xvo8y_!!2251059038.jpg" }, { "id": 624506842658, "name": "2020舟山东海音乐节", "showTime": "2020.09.04-09.06", "price": "200-680", "city": "舟山", "address": "舟山市朱家尖南沙景区沙滩", "pic": "https://img.alicdn.com/bao/uploaded/i4/2251059038/O1CN01L70FVl2GdSG2wpwyE_!!0-item_pic.jpg" }, { "id": 623216520608, "name": "中国•磐安 2020氧气山水音乐节", "showTime": "2020.08.22 周六 16:30", "price": "280", "city": "金华", "address": "金华磐安花溪风景区", "pic": "https://img.alicdn.com/bao/uploaded/https://img.alicdn.com/imgextra/i3/2251059038/O1CN01ECp69h2GdSFpoUPAm_!!2251059038.jpg" }, { "id": 624345993344, "name": "2020"一生中最爱"七夕演唱会", "showTime": "2020.08.25 周二 19:30", "price": "180-580", "city": "北京", "address": "糖果TANGO-雍和宫店三层", "pic": "https://img.alicdn.com/bao/uploaded/i3/2251059038/O1CN01WGNYBE2GdSFqXJgII_!!0-item_pic.jpg" }, { "id": 624170605605, "name": "东海五渔节之敢潮音乐节", "showTime": "2020.08.22 周六 18:00", "price": "198-228", "city": "舟山", "address": "舟山嵊泗五龙乡听海广场(原黄沙村船厂)", "pic": "https://img.alicdn.com/bao/uploaded/https://img.alicdn.com/imgextra/i1/2251059038/O1CN01eV5pR32GdSFxJUb0v_!!2251059038.jpg" }, { "id": 624000957041, "name": "【聚光灯】周四周日爆笑脱口秀剧场", "showTime": "2020.08.13-09.27", "price": "99", "city": "上海", "address": "健力士醇黑坊", "pic": "https://img.alicdn.com/bao/uploaded/i3/2251059038/O1CN01s9Jlz32GdSFv79hIO_!!0-item_pic.jpg" }, { "id": 623838540974, "name": "2020真世界摇滚演出", "showTime": "2020.08.29 周六 20:30", "price": "120", "city": "北京", "address": "糖果TANGO-雍和宫店三层", "pic": "https://img.alicdn.com/bao/uploaded/i2/2251059038/O1CN01HWbQXk2GdSFxARpRD_!!0-item_pic.jpg" }, { "id": 624699066028, "name": "开心麻花首部悬疑惊悚喜剧《醉后赢家》", "showTime": "2020.08.25-09.06", "price": "80-1080", "city": "北京", "address": "地质礼堂剧场", "pic": "https://img.alicdn.com/bao/uploaded/https://img.alicdn.com/imgextra/i2/2251059038/O1CN01Vv1mQO2GdSFvnmIDs_!!2251059038.png" }, { "id": 625219995330, "name": "开心麻花经典爆笑舞台剧《乌龙山伯爵》", "showTime": "2020.08.25-08.30", "price": "80-1080", "city": "北京", "address": "北京展览馆剧场", "pic": "https://img.alicdn.com/bao/uploaded/i3/2251059038/O1CN01znXuKj2GdSG6ACMMb_!!0-item_pic.jpg" }, { "id": 623454281510, "name": "开心麻花重磅新戏《贼想得到你》", "showTime": "2020.08.12 周三", "price": "80-1280", "city": "上海", "address": "上汽上海文化广场", "pic": "https://img.alicdn.com/bao/uploaded/i1/2251059038/O1CN013YAyeY2GdSFnXwgnQ_!!0-item_pic.jpg" }, { "id": 625314963280, "name": "开心麻花重磅新戏《贼想得到你》", "showTime": "2020.08.15-08.21", "price": "100-1180", "city": "上海", "address": "虹桥艺术中心", "pic": "https://img.alicdn.com/bao/uploaded/i3/2251059038/O1CN01Qb8wyX2GdSG30DCl4_!!0-item_pic.jpg" }, { "id": 622815888793, "name": "开心麻花上海首部原创爆笑舞台剧《皇帝的新娘》", "showTime": "2020.08.12-08.16", "price": "80-1180", "city": "上海", "address": "上戏实验剧院", "pic": "https://img.alicdn.com/bao/uploaded/i2/2251059038/O1CN01uie4Gf2GdSFlp1Rvv_!!0-item_pic.jpg" }, { "id": 624443634831, "name": "孟京辉戏剧作品《我爱xxx》", "showTime": "2020.08.13-08.16", "price": "100-380", "city": "北京", "address": "蜂巢剧场", "pic": "https://img.alicdn.com/bao/uploaded/https://img.alicdn.com/imgextra/i3/2251059038/O1CN01LwdJRL2GdSFtDPtRL_!!2251059038.jpg" }, { "id": 624095704875, "name": "【8月8日-16日场次周年特惠低至四折】太阳马戏X绮幻之境 - 8月", "showTime": "2020.08.12-08.30", "price": "360-3460", "city": "杭州", "address": "杭州新天地太阳剧场", "pic": "https://img.alicdn.com/bao/uploaded/i3/2251059038/O1CN01iyWOwU2GdSG2iMBsM_!!0-item_pic.jpg" }, { "id": 624163106935, "name": "高达5公里定向挑战赛", "showTime": "2020.09.26 周六", "price": "108-388", "city": "上海", "address": "世纪公园", "pic": "https://img.alicdn.com/bao/uploaded/https://img.alicdn.com/imgextra/i3/2251059038/O1CN01y2n1PI2GdSFtLmEtu_!!2251059038.jpg" }, { "id": 622064265074, "name": "2020 FORMULA1 中国大奖赛(礼包&福袋)", "showTime": "2020.07.04-12.31", "price": "120-270", "city": "上海", "address": "上汽国际赛车场(上海国际赛车场)", "pic": "https://img.alicdn.com/bao/uploaded/https://img.alicdn.com/imgextra/i2/2251059038/O1CN01ZHrnGM2GdSFbZjdUV_!!2251059038.jpg" }, { "id": 623662985515, "name": "2020ChinaJoy电竞赛事荟萃", "showTime": "2020.07.31-10.30", "price": "0", "city": "北京", "address": "请到大麦APP和优酷APP观看", "pic": "https://img.alicdn.com/bao/uploaded/i4/2251059038/O1CN01RpgBQ82GdSFoMD7h8_!!0-item_pic.jpg" }, { "id": 618307700815, "name": "2020 FORMULA1 中国大奖赛(服装)", "showTime": "2020.05.19-12.31", "price": "248-620", "city": "上海", "address": "上汽国际赛车场(上海国际赛车场)", "pic": "https://img.alicdn.com/bao/uploaded/i2/2251059038/O1CN01scI6Ly2GdSFEYDh7P_!!0-item_pic.jpg" }, { "id": 613334933912, "name": "2020 FORMULA1 中国大奖赛(周边衍生品)", "showTime": "2020.03.11-12.31", "price": "35-160", "city": "上海", "address": "上汽国际赛车场(上海国际赛车场)", "pic": "https://img.alicdn.com/bao/uploaded/https://img.alicdn.com/imgextra/i3/2251059038/O1CN01ZusbUY2GdSENL0iIN_!!2251059038.jpg" }, { "id": 613323173822, "name": "2020 FORMULA1 中国大奖赛(帽品)", "showTime": "2020.03.11-12.31", "price": "200-335", "city": "上海", "address": "上汽国际赛车场(上海国际赛车场)", "pic": "https://img.alicdn.com/bao/uploaded/https://img.alicdn.com/imgextra/i3/2251059038/O1CN01azreXu2GdSF9rIkGV_!!2251059038.jpg" }, { "id": 613940057617, "name": "加速北京跳伞俱乐部高空跳伞体验", "showTime": "2020.08.05-08.31", "price": "2980", "city": "北京", "address": "北京市平谷区马坊镇通航产业基地", "pic": "https://img.alicdn.com/bao/uploaded/https://img.alicdn.com/imgextra/i1/2251059038/O1CN01Ns9MZj2GdSFIp2udB_!!2251059038.png" }, { "id": 624453755826, "name": "《你是演奏家2 · 超级金贝鼓》", "showTime": "2020.08.21-08.23", "price": "180-380", "city": "上海", "address": "美琪大戏院", "pic": "https://img.alicdn.com/bao/uploaded/i4/2251059038/O1CN016u70M62GdSFrTL5GP_!!0-item_pic.jpg" }, { "id": 624211844323, "name": "正版授权·大型儿童实景舞台剧《奥特曼宇宙之光》", "showTime": "2020.09.05 周六", "price": "180-580", "city": "海口", "address": "海南省歌舞剧院", "pic": "https://img.alicdn.com/bao/uploaded/https://img.alicdn.com/imgextra/i2/2251059038/O1CN01ybwkiZ2GdSFy9894v_!!2251059038.jpg" }, { "id": 624672730925, "name": "全国正版授权大型互动式儿童舞台剧 海底小纵队2---火山大冒险", "showTime": "2020.11.15 周日", "price": "80-480", "city": "上海", "address": "黄浦剧场-中剧场", "pic": "https://img.alicdn.com/bao/uploaded/i1/2251059038/O1CN01mfDv5t2GdSFwbhzvt_!!0-item_pic.jpg" }, { "id": 624868314578, "name": "大船文化·加拿大原版音乐启蒙全场互动亲子剧《你是演奏家2·超级金贝鼓》", "showTime": "2020.09.06 周日", "price": "180-380", "city": "天津", "address": "津湾大剧院大剧场", "pic": "https://img.alicdn.com/bao/uploaded/https://img.alicdn.com/imgextra/i4/2251059038/O1CN01l16ZUE2GdSFzGWSPx_!!2251059038.png" }, { "id": 624450522367, "name": "大船文化·法国艺术启蒙魔术剧《美术馆奇妙夜·星夜》中文版", "showTime": "2020.09.06 周日", "price": "120-280", "city": "南京", "address": "江苏大剧院--综艺厅", "pic": "https://img.alicdn.com/bao/uploaded/i3/2251059038/O1CN01FMizHi2GdSG0AINxP_!!2-item_pic.png" }, { "id": 623125350409, "name": "大船文化 法国艺术启蒙魔术剧《美术馆奇妙夜·星夜》中文版", "showTime": "2020.08.27-08.30", "price": "80-480", "city": "上海", "address": "上汽上海文化广场", "pic": "https://img.alicdn.com/bao/uploaded/https://img.alicdn.com/imgextra/i4/2251059038/O1CN01CiAVft2GdSFpIawAw_!!2251059038.jpg" }, { "id": 623975390263, "name": "正版授权大型实景舞台剧《奥特曼:宇宙之光》(杭州站)", "showTime": "2020.12.13 周日", "price": "68-480", "city": "杭州", "address": "杭州剧院", "pic": "https://img.alicdn.com/bao/uploaded/https://img.alicdn.com/imgextra/i4/2251059038/O1CN01fUBSCY2GdSFsbnPPh_!!2251059038.jpg" }]