主要内容:
- ① 通过js提升图片页面加载速度(懒加载原理)。
- ② 元素浮动和位置让出。
- ③ 左右浮动和免受影响。
- ④ 高度塌陷及各种解决办法。
- ⑤ 典型三列页面的实现(定位模式、浮动模式、圣杯模式、Grid模式)。
1、通过js提升图片页面加载速度
直接加载图片会导致页面加载速度放慢。于是可以先放一些用来占位的小图。然后等到图在页面中出现了(结合scroll这块来判断),再用js加载成正式的图。
<body>
<img src="temp.jpg" alt="" data-src="thief.png" />
<img src="temp.jpg" alt="" data-src="thief.png" />
<img src="temp.jpg" alt="" data-src="thief.png" />
</body>
<script>
// 视口大小: 窗口大小
const viewHeight = document.documentElement.clientHeight;
// 监听文档对象的滚动事件
document.addEventListener("scroll", showImg);
// 初始化
window.addEventListener("load", showImg);
// 回调
function showImg() {
// 获取所有图片
let imgs = document.querySelectorAll("img");
// 遍历每一张图片,判断当前的图片是否进入到用户的可视区域
imgs.forEach(function (img) {
let imgTop = img.offsetTop;
// 滚动高度 = 视口高度 + 滚动距离
let scrTop = viewHeight + document.documentElement.scrollTop;
// 图片已进入可视区
if (imgTop < scrTop) {
img.src = img.dataset.src;
}
});
}
</script>
2、元素浮动和位置让出
- 元素浮动之后从文档流中脱离出来(会释放它原来在文档流中占据的空间)
- 后面的元素会自动填充它出让出来的空间大小
- 浮动元素只会影响到它后面的元素布局,对前面没有影响
- 行内元素用于最终内容的载体, 不能充当容器/当父级,不能设置或设置了宽高也是无效的。例如a、p元素等
- 任何元素,一旦浮动都自动转为块级元素
3、左右浮动和免受影响
float: left;
float: right;
clear: both;(免受前面浮动元素的影响)
当然也有:
clear:left; clear:right;
4、高度塌陷及解决办法
什么是高度塌陷:父元素在文档流中高度默认是被子元素撑开的,当子元素脱离文档流以后,将无法撑起父元素的高度,也就会导致父元素的高度塌陷。
/* 解决方案1: 给父元素也添加一个高度。缺点是无法随浮动元素的高度变化而变化*/
.container {
height: 150px;
}
/* 解决方案2: 把父元素也浮动起来 */
.container {
float: left;
}
.box {
float: left;
}
/* 解决方案3: 添加一个专用元素用于清浮动 */
div.clear {
clear: both;
}
/* 解决方案4: 通过添加一个伪元素来解决 */
.container::after {
content: "";
display: block;
clear: both;
}
/* 解决方案5: 最简单的解决方案,用到BFC(块级格式化上下文) */
.container {
/* overflow: hidden; */
overflow: auto;
}
5、典型三列页面的实现(定位模式、浮动模式、圣杯模式、Grid模式)
方法1:定位模式
<!--body中的块元素-->
<div class="container">
<div class="left">左侧</div>
<div class="main">内容区</div>
<div class="right">右侧</div>
</div>
<!--css中的左右定位等-->
<style>
/* 主体用定位 */
.container {
width: 960px;
margin: 10px auto;
/* background-color: #ccc; */
min-height: 600px;
/* 转为定位元素,做为定位父级 */
position: relative;
}
.container > .left {
width: 200px;
background-color: wheat;
min-height: 600px;
position: absolute;
top: 0;
left: 0;
}
.container > .right {
width: 200px;
background-color: wheat;
min-height: 600px;
position: absolute;
top: 0;
right: 0; /*这块是以右侧为锚定点来进行定位*/
}
.container > .main {
background-color: lightgreen;
min-height: 600px;
width: 540px;
position: absolute;
top: 0;
left: 210px;
}
</style>
方法2:浮动模式
<style>
/* 主体用定位 */
.container {
width: 960px;
margin: 10px auto;
/* background-color: #ccc; */
min-height: 600px;
/* 防止浮动元素的高度塌陷 */
overflow: hidden;
}
.container > .left {
width: 200px;
background-color: wheat;
min-height: 600px;
float: left;
}
.container > .right {
width: 200px;
background-color: wheat;
min-height: 600px;
float: right;
}
.container > .main {
background-color: lightgreen;
min-height: 600px;
width: 540px;
float: left;
margin-left: 10px;
}
</style>
方法3:圣杯模式
先将两边做好,然后中间自动填充。
<div class="container">
<!-- 圣杯布局要求主体内容优先渲染 -->
<div class="main">内容区</div>
<div class="left">左侧</div>
<div class="right">右侧</div>
</div>
<style>
.container {
border: 5px dashed;
overflow: hidden;
}
.container > * {
min-height: 400px;
}
/* 左右固定 */
.container > .left,
.container > .right {
width: 200px;
background-color: cyan;
}
/* 中间样式 */
.container > .main {
width: 100%;
background-color: wheat;
}
/* 所有子元素浮动起来 */
.container > * {
float: left;
}
/* 使用内边距把左右二边的位置挤出来 */
.container {
/* padding-left: 200px;
padding-right: 200px; */
padding: 0 200px;
}
.container > .left {
margin-left: -100%;
/* 使用相对定位将它复位 */
position: relative;
top: 0;
right: 200px;
}
.container > .right {
margin-left: -200px;
/* 使用相对定位将它复位 */
position: relative;
top: 0;
left: 200px;
}
</style>
方法4:Grid模式
<body>
<div class="header">页眉</div>
<div class="left">左侧</div>
<div class="main">主体</div>
<div class="right">右侧</div>
<div class="footer">页脚</div>
</body>
<style>
body {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: 40px 500px 40px;
gap: 10px;
}
/* 参考线 */
body > * {
outline: 1px dashed red;
background-color: lightcyan;
}
.header,
.footer {
grid-column-end: span 4;
}
</style>
6、操练:使用定位与浮动完成典型三列页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0px;
padding: 0px;
box-sizing: border-box;
}
li {
list-style: none;
}
a {
text-decoration: none;
color: white;
}
.head, .foot{
height: 40px;
background-color: darkgoldenrod;
width: 960px;
text-align: center;
line-height: 40px;
margin: auto;
}
.head ul li{
float: left;
/* line-height: 40px; */
padding:0 20px;
}
.head ul li:hover{
background-color: darkgrey;
color: red;
}
.head ul li{
float: left;
}
.container{
margin: 10px auto;
min-height: 600px;
position: relative;
width: 960px;
}
.container> .left{
width: 200px;
background-color: rosybrown;
min-height: 600px;
position: absolute;
top: 0;
left: 0;
}
.container> .right{
width: 200px;
background-color: rosybrown;
min-height: 600px;
position: absolute;
top: 0;
right: 0;
}
.middle{
background-color: skyblue;
min-height: 600px;
width: 540px;
position: absolute;
top: 0;
left: 210px;
}
</style>
</head>
<body>
<div class="head">
<ul>
<li><a href="">凡界</a></li>
<li><a href="">妖界</a></li>
<li><a href="">仙界</a></li>
<li><a href="">无界</a></li>
</ul>
</div>
<br>
<div class="container">
<div class="left">左妖怪</div>
<div class="middle">中凡人</div>
<div class="right">右神仙</div>
</div>
<div class="foot">空间无限转,时间常年流</div>
</body>
</html>