为了提高用户体验,网站有时需要多种浏览模式。现在特邀请你为蓝桥官网设计具有经典、浏览和工具三种布局模式。使用户可以根据具体情况选择合适的模式,以便更好地浏览网页内容。 本题需要在已提供的基础项目中使用 JS 完善代码实现布局的切换。
本题已经内置了初始代码,打开实验环境,目录结构如下:
├── css
├── images
├── index.html
├── effect.gif
└── js
└── index.js
其中:
css
是样式文件夹。images
是图片文件夹。index.html
是主页面。effect.gif
是最终完成效果图。js/index.js
是待补充代码的 js 文件。在浏览器中预览 index.html
页面效果如下:
完善
js/index.js
的 TODO 部分的代码,实现被点击的模式元素(class=layout-option
)处于激活状态,即添加一个类名(active
),其他(class=layout-option
)移除激活状态,即移除类名(active
)。 最终效果可参考文件夹下面的 gif 图,图片名称为effect.gif
(提示:可以通过 VS Code 或者浏览器预览 gif 图片)。
js/index.js
文件外的任何内容。appendParamsToURL
函数功能进行检测,请保证函数的通用性,不能仅对测试数据有效。// 获取元素
const layoutContainer = document.getElementById('layoutContainer'); // 布局元素
const layoutOptions = document.querySelectorAll('.layout-option'); // 三个模式元素
const switching = document.getElementById('switching'); // 模式按钮
// 显示模式
switching.addEventListener('click', function () {
mode.style.display = 'flex'; // 设置显示为flex布局
});
// 遍历选项
layoutOptions.forEach(function (option) {
// 经典模式,浏览模式,工具模式点击事件
option.addEventListener('click', function () {
// TODO:待补充代码
// 移除所有模式元素的 active 类名
layoutOptions.forEach(function (opt) {
opt.classList.remove('active');
});
// 给当前点击的元素添加 active 类名
this.classList.add('active');
// TODO:END
// 以下代码无需修改
// 根据不同选项进行布局处理
if (this === layoutOptions[0]) {
// Classic mode
tool.style.display = "none"; // 隐藏工具
layoutContainer.classList.add('two-column-layout'); // 添加两列布局类
layoutContainer.classList.remove('three-column-layout'); // 移除三列布局类
} else if (this === layoutOptions[1]) {
// Browse mode
tool.style.display = "none"; // 隐藏工具
layoutContainer.classList.add('three-column-layout'); // 添加三列布局类
layoutContainer.classList.remove('two-column-layout'); // 移除两列布局类
} else if (this === layoutOptions[2]) {
// Tool mode
tool.style.display = 'flex'; // 显示工具
}
mode.style.display = 'none'; // 隐藏布局容器
});
});
<!DOCTYPE html>
<html>
<head>
<title>布局切换</title>
<link rel="stylesheet" href="./css/style.css">
</head>
<body>
<div class="navbar">
<a href="#">首页</a>
<a href="#">关于我们</a>
<a href="#">服务</a>
<a href="#">联系我们</a>
<div class="search-container">
<input type="text" class="search-box" placeholder="输入关键词搜索...">
</div>
<div class="icons">
<img id="switching" src="./images/icon.svg" alt="">
<img src="./images/setting.svg" alt="">
</div>
</div>
<div id="tool">
<div class="search-container">
<input type="text" class="search-box" placeholder="输入关键词搜索...">
</div>
<div class="quick-nav">
<ul class="list">
<li class="header">快捷导航</li>
<li class="item">蓝桥云课-web课程</li>
<li class="item">蓝桥云课-java课程</li>
<li class="item">蓝桥云课-测试课程</li>
<li class="item">蓝桥云课官网</li>
<li class="item">蓝桥云课-个人主页</li>
<li class="item">蓝桥云课</li>
</ul>
</div>
</div>
<div class="layout-list" id="mode">
<figure>
<img id="one" class="layout-option active" src="./images/classic.svg" alt="">
<figcaption>经典模式 <img src="./images/select.svg" alt=""></figcaption>
</figure>
<figure>
<img id="two" class="layout-option" src="./images/browse.svg" alt="">
<figcaption>浏览模式 <img src="./images/select.svg" alt=""></figcaption>
</figure>
<figure>
<img id="three" class="layout-option" src="./images/tool.svg" alt="">
<figcaption>工具模式 <img src="./images/select.svg" alt=""></figcaption>
</figure>
</div>
<div id="layoutContainer" class="two-column-layout">
<div class="column">
<h2>栏目1</h2>
<p>这是栏目1的内容。</p>
</div>
<div class="column">
<h2>栏目2</h2>
<p>这是栏目2的内容。</p>
</div>
<div class="column">
<h2>栏目3</h2>
<p>这是栏目3的内容。</p>
</div>
</div>
<script src="./js/index.js"></script>
</body>
</html>
1. 文档声明和头部:
<!DOCTYPE html>
声明这是一个 HTML5 文档。<head>
部分包含了页面的标题 <title>布局切换</title>
和一个外部样式表的链接 <link rel="stylesheet" href="./css/style.css">
,用于引入页面的样式。2. 导航栏:
<div class="navbar">
是导航栏容器,包含了多个导航链接 <a>
,如 “首页”、“关于我们” 等,以及一个搜索框和一些图标。<div class="search-container">
中,包含一个 <input type="text" class="search-box">
。<div class="icons">
中,其中一个图标有 id="switching"
,用于触发布局切换。3. 工具区域:
<div id="tool">
是工具区域,包含一个搜索框和一个快捷导航列表。快捷导航列表 <ul class="list">
包含多个 <li>
元素,分别是导航项。4. 布局选项区域:
<div class="layout-list" id="mode">
是布局选项区域,包含三个 <figure>
元素,每个 <figure>
中包含一个图标和一个 <figcaption>
描述。图标有 class="layout-option"
,用于选择不同的布局模式。5. 布局容器:
<div id="layoutContainer" class="two-column-layout">
是主要的布局容器,初始有 two-column-layout
类,包含三个 <div class="column">
子元素,每个子元素代表一个栏目。6. 脚本引入:
<script src="./js/index.js"></script>
引入了一个外部 JavaScript 文件,用于实现布局切换的交互功能。const layoutContainer = document.getElementById('layoutContainer'); // 布局元素
const layoutOptions = document.querySelectorAll('.layout-option'); // 三个模式元素
const switching = document.getElementById('switching'); // 模式按钮
// 显示模式
switching.addEventListener('click', function () {
mode.style.display = 'flex'; // 设置显示为flex布局
});
// 遍历选项
layoutOptions.forEach(function (option) {
// 经典模式,浏览模式,工具模式点击事件
option.addEventListener('click', function () {
// 移除所有模式元素的 active 类名
layoutOptions.forEach(function (opt) {
opt.classList.remove('active');
});
// 给当前点击的元素添加 active 类名
this.classList.add('active');
// 根据不同选项进行布局处理
if (this === layoutOptions[0]) {
// Classic mode
tool.style.display = "none"; // 隐藏工具
layoutContainer.classList.add('two-column-layout'); // 添加两列布局类
layoutContainer.classList.remove('three-column-layout'); // 移除三列布局类
} else if (this === layoutOptions[1]) {
// Browse mode
tool.style.display = "none"; // 隐藏工具
layoutContainer.classList.add('three-column-layout'); // 添加三列布局类
layoutContainer.classList.remove('two-column-layout'); // 移除两列布局类
} else if (this === layoutOptions[2]) {
// Tool mode
tool.style.display = 'flex'; // 显示工具
}
mode.style.display = 'none'; // 隐藏布局容器
});
});
1. 获取元素:
document.getElementById
和 document.querySelectorAll
方法获取页面中的元素,如布局容器 layoutContainer
、布局选项 layoutOptions
和模式按钮 switching
。2. 显示模式按钮点击事件:
switching
按钮添加点击事件监听器,当点击时,将 mode
元素(布局选项区域)的 display
属性设置为 flex
,使其显示出来。3. 布局选项点击事件:
layoutOptions
,为每个选项添加点击事件监听器。active
类名,然后给当前点击的选项添加 active
类名。tool
,为布局容器添加 two-column-layout
类,移除 three-column-layout
类。tool
,为布局容器添加 three-column-layout
类,移除 two-column-layout
类。tool
。mode
。1. 全局样式
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
*
是通用选择器,它会选中页面中的所有元素。padding: 0;
和 margin: 0;
去除了所有元素的内边距和外边距,保证页面布局从一个统一的基准开始。box-sizing: border-box;
使元素的宽度和高度包含内边距和边框,但不包含外边距,这样在设置元素大小时更容易控制。2. 主体样式
body {
font-family: Arial, sans-serif;
margin: 20px;
background-color: #f5f5f5;
display: flex;
justify-content: center;
align-items: center;
}
font-family
指定了页面文字的字体,优先使用 Arial 字体,如果没有则使用系统默认的无衬线字体。margin: 20px;
给页面主体添加了 20px 的外边距。background-color: #f5f5f5;
设置页面的背景颜色为浅灰色。display: flex;
、justify-content: center;
和 align-items: center;
使页面主体内容在水平和垂直方向上都居中显示。3. 文章样式
article {
position: relative;
width: 800px;
max-width: calc(100vw - 200px);
min-height: 100vh;
border-radius: 6px;
background-color: #fff;
padding: 16px 32px;
box-shadow: 0 0 0 1px rgba(23, 23, 23, 0.05);
}
position: relative;
为 article
元素设置相对定位,作为其子元素绝对定位的参考。width: 800px;
设定文章宽度为 800px。max-width: calc(100vw - 200px);
确保文章最大宽度不超过视口宽度减去 200px。min-height: 100vh;
使文章的最小高度为视口高度。border-radius: 6px;
给文章添加 6px 的圆角。background-color: #fff;
设置文章的背景颜色为白色。padding: 16px 32px;
为文章添加内边距。box-shadow
为文章添加一个细微的边框阴影效果。4. 操作图标样式
.operates {
position: absolute;
left: 0;
top: 100px;
transform: translateX(calc(0px - 100% - 40px));
display: flex;
flex-direction: column;
}
.operates>svg {
width: 28px;
height: 28px;
margin-bottom: 40px;
cursor: pointer;
fill: #000;
}
.operates>svg:first-of-type:hover {
fill: #d23131;
}
.operates>svg:nth-of-type(2):hover {
fill: #ffc128;
}
.operates>svg:nth-of-type(3):hover {
fill: #0070ff;
}
.operates
类用于包裹操作图标,position: absolute;
使其相对于 article
元素进行绝对定位。transform: translateX(calc(0px - 100% - 40px));
将操作图标向左移动到文章左侧。display: flex;
和 flex-direction: column;
使图标垂直排列。.operates>svg
选中所有直接子元素为 svg
的元素,设置图标大小、底部间距、鼠标指针样式和填充颜色。:hover
伪类为不同位置的图标设置鼠标悬停时的填充颜色。5. 段落和标题样式
p {
line-height: 1.5;
color: rgb(23, 23, 23);
}
h1 {
text-align: center;
line-height: 3;
}
h2 {
line-height: 2;
text-align: right;
color: rgb(64, 64, 64);
}
p
标签设置了行高和文字颜色。h1
标签设置了标题居中显示和行高。h2
标签设置了副标题右对齐显示、行高和文字颜色。6. 分享对话框样式
.my-dialog {
position: fixed;
top: 0;
left: 0;
z-index: 99;
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, .6);
display: flex;
justify-content: center;
align-items: center;
display: none;
}
.my-dialog>.block {
width: 400px;
height: fit-content;
padding: 24px 64px;
border-radius: 16px;
background: #fff;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
}
.block>a {
color: #000;
word-break: break-all;
line-height: 2;
margin-bottom: 16px;
}
.block>button {
width: 60%;
height: 40px;
padding: 8px 12px;
border-radius: 6px;
background-color: rgb(59, 73, 223);
font-size: 16px;
color: #fff;
line-height: 1;
cursor: pointer;
border: none;
outline: none;
}
.block>button:hover {
background-color: rgb(47, 58, 178);
}
.my-dialog
类用于创建分享对话框,position: fixed;
使其固定在页面上,display: none;
初始时隐藏对话框。.my-dialog>.block
类设置对话框的内容区域样式,包括宽度、内边距、圆角和背景颜色。.block>a
类设置分享链接的样式,包括文字颜色、换行方式和行高。.block>button
类设置复制按钮的样式,包括宽度、高度、背景颜色、文字颜色和鼠标指针样式。:hover
伪类为复制按钮设置鼠标悬停时的背景颜色。四、工作流程▶️ 1. 页面加载:页面加载时,导航栏、工具区域、布局选项区域和布局容器等元素根据 HTML 和 CSS 样式进行渲染。布局选项区域初始隐藏,布局容器初始为两栏布局。 2. 点击模式按钮:用户点击导航栏中的模式按钮(
id="switching"
),触发 JavaScript 中的点击事件,显示布局选项区域(id="mode"
)。 3. 选择布局模式:用户点击布局选项区域中的一个图标(class="layout-option"
),触发点击事件:
active
类名,然后给当前点击的选项添加 active
类名,更新视觉效果。4. 布局更新:布局容器根据所选模式更新其布局样式,显示相应的栏目布局。