DOM尺寸
获取元素偏移量
针对于参考父级 的 顶部与左侧 的距离
offsetParent
获取到元素的参考父级
offsetLeft / offsetTop
- 获取的事元素左边的偏移量和上边的偏移量
- offsetLeft 该元素相对于参考父级的左侧偏移量
- offsetTop 该元素相对于参考父级的上侧偏移量
- 获取到的是一个数字, 没有 px 单位
获取元素尺寸
visibility: hidden 元素在页面占位
offsetWidth 和 offsetHeight
- offsetWidth: 获取元素内容 + padding + border 的宽度
- offsetHeight: 获取元素内容 + padding + border 的高度
clientWidth 和 clientHeight
- clientWidth 获取元素内容 + padding 的宽度
- clientHeight 获取元素内容 + padding 的高度
获取浏览器窗口尺寸
可视区域的尺寸(不包含滚动条)
- document.documentElement.clientWidth: 浏览器可视窗口的宽度
- document.documentElement.clientHeight: 浏览器可视窗口的高度
浏览器窗口尺寸(含滚动条)
- window.innerWidth: 浏览器窗口的宽度
- window.innerHeight: 浏览器可视窗口的高度
实例(分页,瀑布流)
利用数据, 创建一个合理的字符串, 然后利用这个字符串进行页面渲染
/**
* 分页的功能
*
* 1. 刚打开页面
* 1.1 截取部分数据, 渲染页面
* 1.2 调整页码
* 1.3 调整上下页按钮的样式
*
* 2. 点击上一页
* 2.1 判断能不能去上一页
* 2.2 截取部分数据, 渲染页面
* 2.3 调整页码
* 2.4 调整上下页按钮的样式
*
* 3. 点击下一页
* 3.1 判断能不能去下一页
* 3.2 截取部分数据, 渲染页面
* 3.3 调整页码
* 3.4 调整上下页按钮的样式
*
* 4. 切换每页展示数据的数量
* 4.1 调整每页展示的数量
* 4.2 截取部分数据, 渲染页面
* 4.3 调整页码
* 4.4 调整上下页按钮的样式
*
* 逻辑:
* 0. 创建一个渲染函数
* 0.1 截取部分数据
* 0.2 调整页码
* 0.3 调整按钮样式
*
* 1. 初次打开页面
* 1.1 直接调用
*
* 2. 点击上一页按钮
* 2.1 判断能不能去上一页
* 2.2 调整当前页
* 2.3 调用渲染函数
*
* 3. 点击下一页按钮
* 3.1 判断能不能去下一页
* 3.2 调整当前页
* 3.3 调用渲染函数
*
* 4. 切换每页展示数量
* 4.1 切换展示的数量
* 4.2 调用渲染函数
*/
具体实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.header,
.footer {
width: 1200px;
margin: 0 auto;
background-color: skyblue;
display: flex;
justify-content: center;
align-items: center;
font-size: 50px;
height: 120px;
color: #fff;
}
.footer {
height: 300px;
}
ul,
li {
list-style: none;
}
ul {
width: 1200px;
display: flex;
flex-wrap: wrap;
margin: 0 auto;
justify-content: space-between;
padding-top: 10px;
}
li {
width: 290px;
border: 1px solid #333;
margin-bottom: 10px;
padding: 5px;
box-sizing: border-box;
}
li>img {
width: 278px;
display: block;
}
.pagination {
width: 1200px;
margin: 10px auto;
height: 50px;
display: flex;
align-items: center;
}
.pagination>.prev,
.pagination>.next {
width: 50px;
height: 30px;
cursor: pointer;
background-color: orange;
font-size: 24px;
color: #fff;
display: flex;
justify-content: center;
align-items: center;
}
.pagination>.disable {
cursor: not-allowed;
background-color: #ccc;
}
.pagination>.total {
font-size: 30px;
font-weight: 700;
margin: 0 20px;
}
.pagination>select {
font-size: 22px;
padding-left: 20px;
margin-left: 30px;
}
</style>
</head>
<body>
<div class="header">顶部导航</div>
<div class="pagination">
<span class="prev"><</span>
<span class="total">1 / 100</span>
<span class="next">></span>
<select>
<option value="4">4</option>
<option value="8">8</option>
<option value="12">12</option>
<option value="16">16</option>
</select>
</div>
<ul>
</ul>
<div class="footer">底部导航</div>
<script src="./dm_list.js"></script>
<script>
// console.log(list)
// 0. 获取标签
var total = document.querySelector('.total')
var prev = document.querySelector('.prev')
var next = document.querySelector('.next')
var select = document.querySelector('select')
// 0. 创建全局变量 (在当前 JS 中, 任何一个地方都能使用)
var currentNum = 1 // 默认在 第一页
var pageSize = 4 // 默认每页展示 4 条数据
var totalNum = 0 // 计算总页码
// 0. 创建一个渲染函数
function bindHtml() {
/**
* 0.1 截取部分数据, 渲染页面
*
* 假设 当前是第 1 页 每页展示 4 条
* 页码 === 1 => [0]~[3]
* 页码 === 2 => [4]~[7]
* 页码 === 3 => [8]~[11]
*
* 我们假设 当前页的数字存储在 currentNum 中, 每页展示多少条的数字存储在 pageSize 中
*
* 第一版
* 开始下标: (currentNum - 1) * pageSize
* 结束下标: currentNum * pageSize - 1
*
* 但是 我们用的截取的方法参数有一个特点: 包前不包后, 所以开始下标不变, 结束下标 需要 + 1
*
* 第二版
* 开始下标: (currentNum - 1) * pageSize
* 结束下标: currentNum * pageSize - 1 + 1
*
* 所以最终的优化版本
*
* 第三版
* 开始下标: (currentNum - 1) * pageSize
* 结束下标: currentNum * pageSize
*/
var newArr = list.slice((currentNum - 1) * pageSize, currentNum * pageSize)
var htmlStr = ""
for (var i = 0; i < newArr.length; i++) {
htmlStr += `
<li>
<img src="${newArr[i].pic}" alt="">
<p>${newArr[i].name}</p>
<p>城市: ${newArr[i].city}</p>
<p>地址: ${newArr[i].address}</p>
<p>价格: ${newArr[i].price}</p>
<p>时间: ${newArr[i].showTime}</p>
</li>
`
}
document.querySelector('ul').innerHTML = htmlStr
// 0.2 调整页码
totalNum = Math.ceil(list.length / pageSize)
total.innerHTML = currentNum + ' / ' + totalNum
// 0.3 调整按钮样式
prev.className = currentNum === 1 ? 'prev disable' : 'prev'
next.className = currentNum === totalNum ? 'next disable' : 'next'
}
// 1. 初次打开页面 直接调用
bindHtml()
// 2. 点击上一页
prev.onclick = function () {
// 2.1 判断能不能去上一页
if (currentNum === 1) return
// 2.2 调整页码
currentNum--
// 2.3 重新渲染
bindHtml()
}
// 3. 点击下一页
next.onclick = function () {
// 3.1 判断能不能去下一页
if (currentNum === totalNum) return
// 3.2 调整页码
currentNum++
// 3.3 重新渲染
bindHtml()
}
// 4. 切换每页展示多少条
select.onchange = function () {
// console.log('选择框的内容改变了', select.value - 0)
currentNum = 1
// 修改每页展示多少条
pageSize = select.value - 0
// 重新渲染页面
bindHtml()
}
</script>
</body>
</html>
瀑布流
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.header,
.footer {
width: 1200px;
margin: 0 auto;
background-color: skyblue;
display: flex;
justify-content: center;
align-items: center;
font-size: 50px;
height: 120px;
color: #fff;
}
.footer {
height: 300px;
}
ul,
li {
list-style: none;
}
ul {
width: 1200px;
display: flex;
flex-wrap: wrap;
margin: 0 auto;
justify-content: space-between;
padding-top: 10px;
}
li {
width: 290px;
border: 1px solid #333;
margin-bottom: 10px;
padding: 5px;
box-sizing: border-box;
}
li>img {
width: 278px;
display: block;
}
.loadding {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
display: none;
}
</style>
</head>
<body>
<div class="header">顶部导航</div>
<ul></ul>
<div class="loadding">
<img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fhbimg.b0.upaiyun.com%2F42c725b3935a1ce3e32897b9995c1b6a2e921d335690-Ck6vZO_fw658&refer=http%3A%2F%2Fhbimg.b0.upaiyun.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1669994288&t=3e6b58c142daa3e4fef899cd7b6e9a0b"
alt="">
</div>
<div class="footer">底部导航</div>
<script src="./dm_list.js"></script>
<script>
/**
* 瀑布流: 是目前主流的一个前端分页方式
*
* 1. 打开页面渲染一套数据
*
* 2. 当页面滚动到某一个位置的时候, 重新请求新的数据
*
* 逻辑:
* 封装一个渲染函数
* 首次打开页面的时候调用
* 当页面滚动到某一个位置的时候, 重新调用渲染函数, 拼接上新的数据
*
*
* 我们规定 每页固定展示 8 条数据, 因为要首次渲染的时候, 撑满首页
*/
var myUl = document.querySelector('ul')
var loadding = document.querySelector('.loadding')
// 0. 全局变量
var currentNum = 1 // 表示当前页
var pageSize = 8 // 表示每页展示多少条 (这个变量不会被更改)
var totalNum = Math.ceil(list.length / pageSize) // 计算总页码
var flag = true // 作为一个开关变量, 用于控制是否请求新数据
// 0. 封装渲染函数
function bindHtml() {
var newArr = list.slice((currentNum - 1) * pageSize, currentNum * pageSize)
var htmlStr = ""
for (var i = 0; i < newArr.length; i++) {
htmlStr += `
<li>
<img src="${newArr[i].pic}" alt="">
<p>${newArr[i].name}</p>
<p>城市: ${newArr[i].city}</p>
<p>地址: ${newArr[i].address}</p>
<p>价格: ${newArr[i].price}</p>
<p>时间: ${newArr[i].showTime}</p>
</li>
`
}
// 因为瀑布流需要的是拼接数据, 所以此处不应该使用 = , 而是使用 +=
myUl.innerHTML += htmlStr
}
// 1. 首次打开页面的时候调用
bindHtml()
// 2. 给页面添加滚动事件
window.onscroll = function () {
// 2.1 如果当前页 === 总页码 代表没有下一页了, 所以这个事件可以不执行了
if (currentNum === totalNum) return
/**
* 2.2 如果代码能够执行到这个位置, 说明还有数据
*
* 但是需要在 UL 的底边到达 页面的可视区域的时候, 在加载新数据
*
*
* 页面卷去的高度 + 浏览器可视区域的高度 > UL 顶部偏移量 + UL 的高度 满足这个条件 加载新数据
*
* 页面卷去的高度 + 浏览器可视区域的高度 <= UL 顶部偏移量 + UL 的高度 满足这个条件 不需要加载新数据 直接 return
*/
// 页面卷去的高度
var docHeight = document.documentElement.scrollTop
// 浏览器可视区域的高度
var winHeight = document.documentElement.clientHeight
// UL 顶部偏移量
var ULTop = myUl.offsetTop
// UL 的高度
var ULHeight = myUl.offsetHeight
if (docHeight + winHeight <= ULTop + ULHeight) return
// 2.3 如果代码执行到这里, 说明后续还有数据, 并且到了加载新数据的时候了
// 2.3.1 查看开关变量, 是否允许我们请求
if (!flag) return
// 2.3.2 开始请求数据前, 关闭开关变量, 直到这一次请求完毕的时候, 才能重新发起请求
flag = false
// 数据请求前 打开 loadding
loadding.style.display = 'flex'
console.log('此时请求了 1 次新数据')
setTimeout(function () {
currentNum++
bindHtml()
loadding.style.display = 'none'
// 2.3.3 此时这一次请求已经完毕了, 可以打开开关, 允许我们发送第二次请求, 加载新的数据
flag = true
}, 2000)
}
</script>
</body>
</html>