案例一: 轮播消息提示
-
说明: 做一个消息提示, 让消息的内容跟随数据动态发生改变
-
示例代码:
-
CSS部分
-
.tip-bar { display: inline-flex; flex-direction: row; align-items: center; height: 30px; background-color: rgba(0, 0, 0, 0.4); border-radius: 16px; } img { width: 30px; height: 30px; border-radius: 50%; margin-right: 5px; } span { font-size: 13px; color: white; margin-right: 8px; }
-
HTML结构
-
<div class="tip-bar"> <img src="https://bfs.biyao.com/group1/M01/A6/97/rBACYWBCHqyAFH5tAAANZXX5Eww646.png"/> <span>coder***对这件商品感兴趣</span> </div>
-
JS代码
-
<script> // 模拟从服务器中拿来的数据 let tipList = [ { icon: "https://bfs.biyao.com/group1/M01/A6/97/rBACYWBCHqyAFH5tAAANZXX5Eww646.png", title: "coder***对这件商品感兴趣", }, { icon: "https://bfs.biyao.com/group1/M01/A2/67/rBACVGA_iOuAYaTxAAAPbted3yE165.png", title: "123***814对这件商品感兴趣", }, { icon: "https://bfs.biyao.com/group1/M00/7F/4E/rBACYV16HseAP-PnAAAW9bbVoKE463.png", title: "刘**对这件商品感兴趣", }, ]; // 1.获取元素 var tipBar = document.querySelector(".tip-bar"); var imgEl = tipBar.querySelector("img"); var spanEl = tipBar.querySelector("span"); // 使用一个变量 记录当前展示到的索引位置 var currentIndex = 0; // 2.每三秒切换一次数据 setInterval(function () { // 给DOM设置对应索引的内容 imgEl.src = tipList[currentIndex].icon; spanEl.textContent = tipList[currentIndex].title; currentIndex++; // 当到达数组的长度时 将currentIndex恢复为0 if (currentIndex === tipList.length) { currentIndex = 0; } }, 3000); </script>
-
案例二: 关闭删除消息
-
说明: 点击叉号将对应导航栏删除
-
示例代码:
-
CSS代码
-
.top-bar { display: flex; flex-direction: row; align-items: center; height: 45px; width: 375px; background-color: black; /* 关键 */ overflow: hidden; transition: all 0.3s ease-out; } .delete { display: flex; flex-direction: row; justify-content: center; align-items: center; height: 100%; width: 30px; cursor: pointer; } .delete img { height: 10px; width: 10px; } .logo { height: 30px; width: 30px; margin-left: 3px; margin-right: 30px; cursor: pointer; } span { color: white; font-size: 14px; flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .btn { width: 94px; height: 100%; line-height: 45px; text-align: center; font-size: 14px; color: #fff; background-color: #f63515; }
-
HTML结构:
-
<div class="top-bar"> <div class="delete"> <img src="./img/delete.png" alt="" /> </div> <img class="logo" src="./img/logo.png" alt="" /> <span>打开京东App,购物更轻松</span> <div class="btn">立即打开</div> </div>
-
JS代码:
-
<script> // 1.获取元素 var topBar = document.querySelector(".top-bar"); var deleteEl = topBar.querySelector(".delete"); // 2.点击叉号删除导航栏 deleteEl.onclick = function () { topBar.remove(); }; </script>
-
案例三: 侧边栏的展示
-
说明: 鼠标经过添加动画将宽度调高-, 案例中的图片使用同一张精灵图, 且精灵图位置是有规律的, 我们选择通过js动态设置background-position
-
示例代码:
-
CSS代码
-
.tool-bar { position: fixed; top: 30%; right: 0; display: flex; flex-direction: column; align-items: center; width: 35px; } .item { position: relative; width: 35px; height: 35px; margin-bottom: 1px; background-color: #7a6e6e; border-radius: 3px 0 0 3px; } .icon { display: inline-block; width: 100%; height: 100%; cursor: pointer; background-image: url(./img/toolbars.png); } .name { position: absolute; z-index: -1; right: 35px; top: 0; width: 0; height: 35px; line-height: 35px; color: #fff; text-align: center; font-size: 12px; background-color: #7a6e6e; cursor: pointer; border-radius: 3px 0 0 3px; transition: width 0.2s ease; } .item:hover, .item:hover .name { background-color: #cd1926; }
-
HTML结构
-
<div class="tool-bar"> <div class="item"> <i class="icon"></i> <div class="name">购物车</div> </div> <div class="item"> <i class="icon"></i> <div class="name">收藏</div> </div> <div class="item"> <i class="icon"></i> <div class="name">限时活动</div> </div> <div class="item"> <i class="icon"></i> <div class="name">大礼包</div> </div> </div>
-
JS代码
-
<script> // 1.获取元素 var iconEls = document.querySelectorAll(".icon"); var itemEls = document.querySelectorAll(".item"); // 2.动态给icon设置background-position属性 for (var i = 0; i < iconEls.length; i++) { var iconEl = iconEls[i]; iconEl.style.backgroundPosition = `-48px -${i * 50}px`; } // 3.循环绑定mouseenter事件 for (var i = 0; i < itemEls.length; i++) { itemEls[i].onmouseenter = function () { var nameEl = this.children[1]; nameEl.style.width = "62px"; }; } // 4.循环绑定mouseleave事件 for (var i = 0; i < itemEls.length; i++) { itemEls[i].onmouseleave = function () { var nameEl = this.children[1]; nameEl.style.width = "0"; }; } </script>
-
案例四: 登录框的实现
-
说明: 实现删除输入框中的用户名和密码, 隐藏和显示密码, 要求用户名和密码都不为空才可以登录
-
示例代码:
-
CSS代码
-
.title { width: 304px; text-align: center; margin-bottom: -15px; } .error { display: flex; flex-direction: row; align-items: center; width: 304px; margin-top: 15px; margin-bottom: 8px; padding: 5px 0; background: #ffebeb; color: #e4393c; border: 1px solid #faccc6; } .hidden { visibility: hidden; } .err-icon { display: inline-block; width: 16px; height: 16px; margin-left: 10px; background: url(./img/css_sprites.png) no-repeat -114px -59px; } .err-msg { margin-left: 10px; margin-right: 10px; font-size: 12px; } .user-item, .password-item { display: flex; flex-direction: row; width: 304px; height: 38px; border: 1px solid #bdbdbd; position: relative; margin-bottom: 15px; } .user-icon, .pwd-icon { width: 38px; height: 38px; border-right: 1px solid #bdbdbd; background-image: url(./img/css_sprites.png); background-position: -58px -10px; } .user-icon { background-position: -10px -10px; } input { outline: none; border: none; flex: 1; padding: 10px 0 10px 12px; font-size: 14px; } .eye-icon { position: absolute; right: 27px; top: 15px; width: 25px; height: 15px; background: url(./img/css_sprites.png) -152px -18px no-repeat; cursor: pointer; } .u-clear, .p-clear { position: absolute; right: 6px; top: 12px; width: 14px; height: 14px; background: url(./img/css_sprites.png) -36px -154px no-repeat; cursor: pointer; } .u-clear:hover, .clear:hover { background: url(./img/css_sprites.png) -61px -154px no-repeat; } .login { border: 1px solid #cb2a2d; height: 32px; width: 304px; line-height: 32px; text-align: center; margin-top: 20px; color: white; font-size: 20px; letter-spacing: 6px; cursor: pointer; background: #e4393c; } .login:hover { background-color: #e4393ccc; }
-
HTML结构
-
<h2 class="title">登录页面</h2> <!-- 提示文本 --> <div class="error hidden"> <i class="err-icon"></i> <span class="err-msg">用户名或密码不能为空</span> </div> <!-- 用户名 --> <div class="user-item"> <label for="username" class="user-icon"></label> <input id="username" type="username" placeholder="邮箱/用户名/登录手机" /> <span class="u-clear"></span> </div> <!-- 密码 --> <div class="password-item"> <label for="password" class="pwd-icon"></label> <input id="password" type="password" placeholder="密码" /> <span class="eye-icon"></span> <span class="p-clear"></span> </div> <!-- 登录 --> <div class="login">登录</div>
-
JS代码
-
<script> // 1.获取元素 // 1.1获取用户框的元素 var uInputEl = document.querySelector("#username"); var uClearEl = document.querySelector(".u-clear"); // 1.2获取密码框的元素 var pInputEl = document.querySelector("#password"); var eyeIconEl = document.querySelector(".eye-icon"); var pClear = document.querySelector(".p-clear"); // 1.3获取登录的元素 var loginEl = document.querySelector(".login"); var errorEl = document.querySelector(".error"); // 2.监听事件 // 2.1监听用户框的事件 uClearEl.onclick = function () { if (uInputEl.value) uInputEl.value = ""; }; // 2.2监听密码框的事件 var isShow = true; eyeIconEl.onclick = function () { if (isShow) { pInputEl.type = "text"; } else { pInputEl.type = "password"; } isShow = !isShow; }; pClear.onclick = function () { if (pInputEl.value) pInputEl.value = ""; }; // 2.3监听登录的事件 loginEl.onclick = function () { if (!uInputEl.value || !pInputEl.value) { errorEl.classList.remove("hidden"); } else { errorEl.classList.add("hidden"); alert("登录成功"); } }; </script>
-
案例五: 王者的轮播图
-
说明
-
-
CSS引入reset代码
-
/* reset.css样式重置文件 */ /* margin/padding重置 */ body, h1, h2, h3, ul, ol, li, p, dl, dt, dd { padding: 0; margin: 0; } /* a元素重置 */ a { text-decoration: none; color: #333; } /* img的vertical-align重置 */ img { vertical-align: top; } /* ul, ol, li重置 */ ul, ol, li { list-style: none; } /* 对斜体元素重置 */ i, em { font-style: normal; }
-
CSS引入common代码
-
/* common.css公共的样式 */ /* body的公共样式 */ body { font: 14px/1.5 "Microsoft YaHei",Tahoma,"simsun",sans-serif; color: #333; } /* wrapper中间包裹的区域 */ .top_wrapper { width: 980px; margin: 0 auto; } .header_wrapper { width: 1300px; margin: 0 auto; } .main_wrapper { width: 1200px; margin: 0 auto; } /* 文字不换行显示3行代码 */ .nowrap_ellipsis { white-space: nowrap; text-overflow: ellipsis; overflow: hidden; } .news_type::before { display: inline-block; width: 32px; height: 16px; margin-right: 2px; line-height: 16px; text-align: center; font-size: 12px; border: 1px solid #f00; border-radius: 2px; } .news_type_hot::before { content: "热门"; color: #ff3636; border-color: #ff3636; } .news_type_notice::before { content: "公告"; color: #f4be19; border-color: #f4be19; } .news_type_news::before { content: "新闻"; color: #1e96ab; border-color: #1e96ab; } .news_type_match { display: inline-block; width: 52px; height: 23px; margin-right: 12px; border-radius: 10px; line-height: 23px; text-align: center; color: #999; font-size: 12px; background-color: #e3e3e3; } /* section_header */ .section_header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; } .section_header .header_left .title { font-size: 22px; color: #323235; padding-left: 30px; background: url(../img/main_sprite.png) no-repeat 0 -102px; } .section_header .header_left .title-icon-match { background-position: 0 -180px; } .section_header .header_left .title-icon-hero { background-position: 0 -139px; } .section_header .header_right { display: flex; align-items: center; } .section_header .header_right .more { display: block; padding-left: 22px; background: url(../img/main_sprite.png) no-repeat -252px 4px; } .section_header .header_right .more:hover { color: #f3c258; } /* tab-control样式 */ .tab_control { display: flex; align-items: center; height: 32px; line-height: 29px; background-color: #f5f5f5; } .tab_control > .item { flex: 1; color: #999; text-align: center; cursor: pointer; border-bottom: 3px solid transparent; } .tab_control > .item.item_wrap { flex: 0 auto; flex-grow: 0; padding: 0 27px; } .tab_control > .item:hover, .tab_control > .item.active { color: #333; border-bottom-color: #f3c258; } .tab_control > .line { width: 1px; height: 20px; background-color: #e1e1e1; } /* tab_keyword样式 */ .tab_keyword { display: flex; flex-wrap: wrap; margin-top: 12px; } .tab_keyword > .item { height: 24px; line-height: 24px; margin: 0 8px 10px 0; padding: 0 15px; color: #333; background-color: #f5f5f5; border: 1px solid #e5e5e5; border-radius: 10px; cursor: pointer; } .tab_keyword > .item:hover, .tab_keyword > .item.active { color: #fff; background-color: #f3c258; border-color: #f3c258; } /* icon_type */ .icon_type { display: inline-block; width: 24px; height: 24px; margin-right: 2px; /* vertical-align: middle; */ background: url(../img/main_sprite.png) no-repeat; } .icon_type_hot { background-position: -162px -67px; } .icon_type_fans { background-position: -135px -68px; } .icon_type_guard { background-position: -134px -5px; }
-
CSS代码
-
.main { height: 100px; } .news-section { display: flex; height: 342px; } .news-section .banner { width: 605px; background-color: #000; overflow: hidden; } .news-section .banner .image-list { display: flex; width: 604px; /* overflow: hidden; */ } .news-section .banner .image-list .item { flex-shrink: 0; width: 100%; } .news-section .banner .image-list .item a { display: block; } .news-section .banner .image-list .item a img { width: 100%; } .news-section .banner .title-list { display: flex; height: 44px; line-height: 44px; } .news-section .banner .title-list .item { flex: 1; text-align: center; } .news-section .banner .title-list .item a { display: block; font-size: 14px; color: #b1b2be; } .news-section .banner .title-list .item.active a, .news-section .banner .title-list .item a:hover { color: #f3c258; background-color: rgba(255, 255, 255, 0.15); } .news-section .news { flex: 1; background-color: purple; } .news-section .download { width: 236px; background-color: skyblue; } .news-section .download a { display: block; background: url(./img/main_sprite.png) no-repeat; } .news-section .download a.download-btn { height: 128px; background-position: 0 -219px; } .news-section .download a.guard-btn { height: 106px; background-position: 0 -350px; } .news-section .download a.experience-btn { height: 108px; background-position: 0 -461px; }
-
HTML结构
-
<div class="main main_wrapper"> <div class="news-section"> <div class="banner"> <ul class="image-list"> <li class="item"> <a href=""> <img src="./img/banner_01.jpeg" alt="" /> </a> </li> <li class="item"> <a href=""> <img src="./img/banner_02.jpeg" alt="" /> </a> </li> <li class="item"> <a href=""> <img src="./img/banner_03.jpeg" alt="" /> </a> </li> <li class="item"> <a href=""> <img src="./img/banner_04.jpeg" alt="" /> </a> </li> <li class="item"> <a href=""> <img src="./img/banner_05.jpeg" alt="" /> </a> </li> </ul> <ul class="title-list"> <li class="item active"> <a href="#">桑启的旅途故事</a> </li> <li class="item"> <a href="#">启示之音抢先 听</a> </li> <li class="item"> <a href="#">谁成为版本之子</a> </li> <li class="item"> <a href="#">观赛体验升级</a> </li> <li class="item"> <a href="#">季后赛开战</a> </li> </ul> </div> <div class="news"></div> <div class="download"> <a class="download-btn" href="#"></a> <a class="guard-btn" href="#"></a> <a class="experience-btn" href="#"></a> </div> </div> </div>
-
JS代码
-
<script> // 1.获取元素 var bannerEl = document.querySelector(".banner"); var titleListEl = document.querySelector(".title-list"); var activeItemEl = document.querySelector(".active"); var imageList = document.querySelector(".image-list"); // 定义一些变量保存状态 var currentIndex = 0; var timerId = null; // 2.监听事件 titleListEl.onmouseover = function (event) { var itemEl = event.target.parentElement; if (!itemEl.classList.contains("item")) return; // 获取当前itemEl所在的索引 for (var i = 0; i < titleListEl.children.length; i++) { if (itemEl === titleListEl.children[i]) break; } // 将当前索引保存起来 currentIndex = i; switchBanner(); }; // 3.添加定时器自动轮播 startTimer(); // 鼠标进入清除定时器 bannerEl.onmouseenter = function () { clearInterval(timerId); }; // 鼠标离开添加定时器 bannerEl.onmouseleave = function () { startTimer(); }; // 由于定时器和监听事件中有大量相似代码 我们可以抽离成一个函数 // 4.封装一个切换轮播的函数 function switchBanner() { // 处理active // 1.1删除之前的active activeItemEl.classList.remove("active"); // 1.2添加新的active var currentItemEl = titleListEl.children[currentIndex]; currentItemEl.classList.add("active"); // 1.3记录新的active activeItemEl = currentItemEl; // 1.4处理图片轮播 imageList.style.transform = `translateX(${-604 * currentIndex}px)`; imageList.style.transition = `all 300ms ease`; } // 5.封装一个添加定时器函数 function startTimer() { timerId = setInterval(function () { currentIndex++; if (currentIndex === titleListEl.children.length) currentIndex = 0; switchBanner(); }, 3000); } </script>
-
案例六: 书籍的购物车
-
说明: HTML固定的我们直接用HTML编写, 对于那些大量切有规律的可以通过JavaScript编写, 实现计算总价格, 删除功能
-
示例代码:
-
CSS代码
-
table { border-collapse: collapse; } thead { background-color: #f5f5f5; } th, td { border: 1px solid #aaa; padding: 8px 12px; text-align: center; }
-
HTML结构
-
<table> <thead> <tr> <th>编号</th> <th>书籍名称</th> <th>出版日期</th> <th>价格</th> <th>购买数量</th> <th>操作</th> </tr> </thead> <tbody></tbody> </table> <h2 class="price">总价格: ¥<span class="price-count">0</span></h2>
-
JS代码
-
<script> // 模拟服务器的数据 var books = [ { id: 1, name: "《算法导论》", date: "2006-09", price: 85.0, count: 3, }, { id: 2, name: "《UNIX编程艺术》", date: "2006-02", price: 59.0, count: 2, }, { id: 3, name: "《编程珠玑》", date: "2008-10", price: 39.0, count: 5, }, { id: 4, name: "《代码大全》", date: "2006-03", price: 128.0, count: 8, }, ]; // 1.获取元素 var tbodyEl = document.querySelector("tbody"); // 2.动态添加tr以及具体数据 for (var i = 0; i < books.length; i++) { // 2.1创建tr var trowEl = document.createElement("tr"); // 2.2在trowEl中放具体的数据 book = books[i]; for (var key in book) { // 2.3创建td var tdEl = document.createElement("td"); // 2.3在tdEl中放具体的数据 var value = book[key]; if (key === "price") value = "¥" + value; tdEl.textContent = value; trowEl.append(tdEl); } // 2.4创建一个td和删除按钮 var deleteTdEl = document.createElement("td"); var deleteBtnEl = document.createElement("button"); deleteBtnEl.textContent = "删除"; deleteTdEl.append(deleteBtnEl); trowEl.append(deleteTdEl); // 2.5监听删除按钮的点击 deleteBtnEl.onclick = function () { // 删除对应的tr var deleteTrowEl = this.parentElement.parentElement; // 拿到删除行所在的索引 var deleteTrIndex = deleteTrowEl.sectionRowIndex; deleteTrowEl.remove(); // 删除对应books中的数据 books.splice(deleteTrIndex, 1); // 重新计算一次价格 calcTotalPrice(); }; tbodyEl.append(trowEl); } // 3.计算总价格 var priceCountEl = document.querySelector(".price-count"); calcTotalPrice(); // 4.封装一个计算总价格的函数 function calcTotalPrice() { var totalPrice = 0; for (var i = 0; i < books.length; i++) { totalPrice += books[i].count * books[i].price; } priceCountEl.textContent = totalPrice; } </script>
-
cument.createElement(“td”);
var deleteBtnEl = document.createElement(“button”);
deleteBtnEl.textContent = “删除”;
deleteTdEl.append(deleteBtnEl);
trowEl.append(deleteTdEl);
// 2.5监听删除按钮的点击
deleteBtnEl.onclick = function () {
// 删除对应的tr
var deleteTrowEl = this.parentElement.parentElement;
// 拿到删除行所在的索引
var deleteTrIndex = deleteTrowEl.sectionRowIndex;
deleteTrowEl.remove();
// 删除对应books中的数据
books.splice(deleteTrIndex, 1);
// 重新计算一次价格
calcTotalPrice();
};
tbodyEl.append(trowEl);
}
// 3.计算总价格
var priceCountEl = document.querySelector(".price-count");
calcTotalPrice();
// 4.封装一个计算总价格的函数
function calcTotalPrice() {
var totalPrice = 0;
for (var i = 0; i < books.length; i++) {
totalPrice += books[i].count * books[i].price;
}
priceCountEl.textContent = totalPrice;
}
</script>
```