猫眼电影案例template版
- 案例名称:猫眼电影
- 案例人员:杨标
- 案例平台:HTML+CSS+JavasScript+jQuery+template+iconfont+Ajax
- 完成时间:2019年9月19日
::: tip 提示
本案例可下载,项目线上预览效果为猫眼电影
:::
案例说明
该案例是一个综合性比较强的案例,将之前所学习的一些基本知识,JS数组,DOM操作,Ajax,模板引擎,缓存等都做了一次系统的练习
在案例里面,缓存使用的是localStorage
, 请求使用的是jQuery
里面的ajax
, 接口使用的是猫眼电影接口这里的地址
案例使用的插件比较多,现列举如下
- swiper.js 该插件主要是实现轮播图的效果,在本案例当中,我们例用这个插件完成了“正在热映”与“即将上映”的电影的切换效果,同时也完成了图片预览的时候的动态效果
- better-scroll.js 该插件是前端比较流行的一个插件,用于下拉刷新,滑动等。在本案例里面,我们使用这个插件完成了城市页的索引选取,同时还完成了票房页的下拉刷新功能
- template.js该插件是用于前端模板引擎的渲染功能
- layer.js该插件则用于消息交互,主要使用的是
layer.msg()
以及layer.alert()
方法,用于轻消息提示与弹窗消息提示 - clipboard.js 该插件是一个前端用于设置剪切板的插件,具体可查询官方网站clipboardjs中文网
以上插件在网络当中均可百度获取
需求分析
主页
- 左上角实现定位,只显示当前的城市名称,同时根据不同城市显示不同数据
- 正在热映与即将上映的电影显示出来
- 点击定位的地方以后弹出界面,选择城市
- 选择城市的界面必须实现索引化,点击右边的字母,实现滚动到当前
- 点击电影图片实现预览效果
影院页面
- 根据之前的主页定位,显示当前的城市的影院信息,按布局要求进行布局
票房页面
- 点击票房页面实现票房数据展示
- 当前票房页面下拉可刷新
- 票房页在每30分钟更新一次
电影详细页面
- 点击电影跳转当前电影的详细页面
- 布局要求符合规范
- 电影界面要实现可展开与可收缩
- 电影界面要实现播放预告片
- 点击播放的半透明背景,电影预告片不再播放
- 点击右上角收藏按钮,电影进行收藏
- 点击右上角分享按钮实现把当前地址栏的地址设置到剪切板
我的页面
- 展示收藏的电影
- 实现左滑删除
- 点击收藏的电影,跳转到电影的详细信息
效果图
-
主页
-
选择城市
-
点击图片预览
-
电影详细页
-
电影预告片播放
-
票房页
核心代码
该案例文件目录结构图如下所示
该案例文件较多,帮分为功能进行代码贴图
主页功能
该功能主要用于对电影的“正在热映”与“即将上映”进行完成
index.html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>猫眼电影</title>
<link rel="stylesheet" href="./js/swiper/css/swiper.css" type="text/css">
<link rel="stylesheet" href="./js/layer/theme/default/layer.css">
<link rel="stylesheet" href="./css/index.css" type="text/css">
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function () {
document.documentElement.style.fontSize = document.documentElement.clientWidth / 750 * 100 + "px";
})
</script>
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=TojRVDh1NKWiEGH4YgUmeSBTwuy8tCwt"></script>
</head>
<body>
<div id="app">
<div class="header">
猫眼电影
</div>
<div class="content">
<ul class="topNav">
<li class="positionCity">
<span class="currentCityName">武汉</span>
<span class="iconfont icon-icon_sanjiaoxing"></span>
</li>
<li class="active">正在热映</li>
<li>即将上映</li>
<li class="searchIcon">
<span class="iconfont icon-chaxun"></span>
</li>
</ul>
<div class="innerContent">
<div class="swiper-container movieSwiper">
<div class="swiper-wrapper">
<div class="swiper-slide">
<!-- 正在热映 -->
<div class="hotMovieList">
</div>
</div>
<div class="swiper-slide">
<div class="comingMovieList">
</div>
</div>
</div>
</div>
</div>
</div>
<ul class="tabBar">
<li data-url="index.html" class="active">
<span class="iconfont icon-dianying"></span>
<span>影片</span>
</li>
<li data-url="">
<span class="iconfont icon-yingyuana"></span>
<span>影院</span>
</li>
<li data-url="boxoffice.html">
<span class="iconfont icon-ranking"></span>
<span>票房</span>
</li>
<li data-url="">
<span class="iconfont icon-wode1"></span>
<span>我的</span>
</li>
</ul>
</div>
<!-- 城市列表 -->
<div class="cityListDiv">
<ul class="cityListItems">
<li>
<p class="backToIndex">返回</p>
</li>
</ul>
<!-- 给它一个索引 -->
<ul class="cityListIndex">
</ul>
</div>
<!-- 图片预览的轮播 -->
<div class="previewImageDiv">
<div class="swiper-container previewImageSwiper">
<div class="swiper-wrapper">
</div>
</div>
</div>
<template id="movieItemTemp">
{{each movieList item index}}
{{if item.comingTitle}}
<div class="comingTitle">{{item.comingTitle}}</div>
{{/if}}
<div class="movieItem" data-m_id="{{item.id}}">
<div class="left">
<img src="{{item.img.replace('w.h','128.180')}}" alt="">
</div>
<div class="center">
<div class="nm">{{item.nm}}</div>
{{if item.globalReleased}}
<div class="sc">评分:<span>{{item.sc}}</span></div>
{{else}}
<div class="sc"><span>{{item.wish}}</span>想看</div>
{{/if}}
<div class="">主演: {{item.star}}</div>
<div class="">{{item.showInfo}}</div>
</div>
<div class="right">
{{if item.globalReleased}}
<button type="button" class="btnBuy">购票</button>
{{else}}
<button type="button" class="btnPre">预售</button>
{{/if}}
</div>
</div>
{{/each}}
</template>
<!-- 城市列表的模板 -->
<script type="text/template" id="cityListDivTemp">
<%for(var i in cityListObj){%>
<li class="firstLetter" id="firstLetter_<%=i%>"><%=i%></li>
<%for(var j in cityListObj[i]){%>
<li data-cityid="<%=cityListObj[i][j].id%>"><%=cityListObj[i][j].nm%></li>
<%}%>
<%}%>
</script>
<!-- 城市索引的模板 -->
<template id="cityListIndexTemp">
{{each firstLetterArray item index}}
<li>{{item}}</li>
{{/each}}
</template>
<!-- 图片预览的模板 -->
<template id="previewImageTemp">
{{each imageList item index}}
<div class="swiper-slide">
<img src="{{item}}">
</div>
{{/each}}
</template>
</body>
<script src="./js/jquery.js" type="text/javascript"></script>
<script src="./js/template-web.js" type="text/javascript"></script>
<script src="./js/juqery.extend.js" type="text/javascript"></script>
<script src="./js/swiper/js/swiper.js" type="text/javascript"></script>
<script src="./js/bscroll.js" type="text/javascript"></script>
<script src="./js/layer/layer.js" type="text/javascript"></script>
<script src="./js/base.js" type="text/javascript"></script>
<script src="./js/index.js" type="text/javascript"></script>
</html>
index.css代码
CSS主要是一些常见的样式布局,使用rem
做为单位
@import "./comm.css";
.topNav{
display: flex;
height: .8rem;
}
.topNav>li{
flex: 1;
border-bottom: 2px solid #ececec;
display: flex;
justify-content: center;
align-items: center;
}
.topNav>li.active{
color: var(--pColor);
border-bottom-color: var(--pColor);
}
.content{
display: flex;
flex-direction: column;
overflow: auto;
}
.innerContent{
flex: 1;
overflow: auto;
}
.movieItem{
display: flex;
box-sizing: border-box;
padding: .1rem;
border-bottom:1px solid #ececee;
}
.movieItem>.left{
width: 1.8rem;
}
.movieItem>.left>img{
width: 100%;
height: auto;
display: block;
}
.movieItem>.right{
width: 1.4rem;
display: flex;
justify-content: center;
align-items: center;
}
.btnBuy,.btnPre{
width: 1.2rem;
height: .6rem;
border: none;
background-color: var(--pColor);
color: white;
border-radius: .1rem;
font-size: .24rem;
}
.btnPre{
background-color: #3c9fe6;
}
.movieItem>.center{
display: flex;
justify-content: space-between;
flex-direction: column;
font-size: .24rem;
flex: 1;
margin-left: .1rem;
}
.movieItem>.center>.nm{
font-size: .36rem;
font-weight: bold;
}
.movieItem>.center>.sc>span{
color: orange;
font-size: .36rem;
font-weight: bold;
}
/* 电影的轮播选项卡 */
.movieSwiper{
height: 100%;
width: 100%;
overflow: auto;
}
.movieSwiper .swiper-slide {
overflow: auto;
}
.comingTitle{
font-size: .28rem;
color: gray;
margin: .1rem;
}
/* 城市列表 */
.cityListDiv{
position: fixed;
left: 0px;
top: 0px;
right: 0px;
bottom: 0px;
background-color: #ececec;
z-index: 9999;
padding: 0px .2rem;
overflow: auto;
display: none;
}
.cityListDiv .cityListItems>li{
height: .7rem;
display: flex;
align-items: center;
border-bottom: 1px solid lightgray;
font-size: .24rem;
}
.cityListDiv ul li.firstLetter{
color: var(--pColor);
font-weight:bold;
font-size: .36rem;
}
/* 城市索引 */
.cityListIndex{
position: fixed;
right: .1rem;
top: .2rem;
bottom: .2rem;
width: .4rem;
background-color: rgba(0, 0, 0, 0.5);
border-radius: .2rem;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
z-index:99999;
}
.cityListIndex>li{
border: none;
color: white;
font-size: .24rem;
}
.cityListIndex>li.active{
color: var(--pColor);
font-weight: bold;
}
/* 定位的城市 */
.positionCity{
width: 2.4rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.searchIcon{
width: 1.4rem;
display: flex;
justify-content: center;
align-items: center;
font-weight: bold;
color: var(--pColor);
}
.backToIndex{
font-weight: bold;
color: var(--pColor);
margin-top: .2rem;
}
/* 图片预览 */
.previewImageDiv{
position: fixed;
left: 0px;
top: 0px;
right: 0px;
bottom: 0px;
z-index: 9999;
background-color: black;
display: none;
}
.previewImageSwiper{
width: 100%;
height: 100%;
}
.previewImageSwiper .swiper-slide{
display: flex;
justify-content: center;
align-items: center;
}
.previewImageSwiper .swiper-slide img{
width: 100%;
height: auto;
max-height: 100%;
}
在上面的CSS代码里面,我们可以看到,在最开始的地方,我们导入了一个公共的CSS文件comm.css
,该文件用于页面的公共样式 ,后期在其它的页面里面也进行了使用,所以我们单独的剥离出来
comm.css代码
@charset "utf-8";
@import "http://at.alicdn.com/t/font_1307637_63rtuwt8fef.css";
*{
margin: 0px;
padding: 0px;
list-style-type: none;
/* 移动端取消高亮效果 */
-webkit-tap-highlight-color: transparent;
}
body{
font-size: 16px;
}
#app{
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
}
:root{
--pColor:#E54847;
}
.header{
height: .9rem;
background-color: var(--pColor);
font-size: .36rem;
color: white;
font-weight: bold;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
/* 底部的tabBar */
.tabBar{
height: 1.1rem;
border-top: 1px solid lightgray;
display: flex;
justify-content: space-around;
background-color: white;
}
.tabBar>li{
display: flex;
flex-direction: column;
width: 1.1rem;
align-items: center;
font-size: .24rem;
}
.tabBar>li.active{
color: var(--pColor);
}
.tabBar>li>span.iconfont{
font-size: .64rem;
}
/* 中间的布局 */
.content{
flex: 1;
}
完成页面的静态布局以后,现在我们使用JS来完成控制与请求
index.js代码
该页代码比较长,请仔细阅读
//----------变量放这里--------
var baseURL = "https://www.softeem.xin";
var hotMovieList = []; //正在热映的电影
var comingMovieList = []; //即将上映的电影
var cityList = []; //城市列表
var firstLetterArray = []; //城市列表首字母
var cityListObj = {}; //城市列表对象
var mySwiper = null;
var cityListScroll = null; //城市列表的better-scroll
var currentCity={}; //当前城市的对象
var previewImageSwiper=null; //图片预览的轮播
var hotMovieListImage=[]; //正在热映的电影图片
var comingMovieListImage=[]; //即将上映的电影图片
Object.defineProperties(currentCity,{
currentCityId:{
get:function(){
return this._currentCityId;
},
set:function(newValue){
this._currentCityId=newValue;
//重新请求数据
loadComingMovie(newValue);
//更改缓存
localStorage.setItem("currentCityId",newValue);
}
},
currentCityName:{
get:function(){
return this._currentCityName;
},
set:function(newValue){
this._currentCityName=newValue;
$(".currentCityName").text(newValue);
//放到缓存里面去
localStorage.setItem("currentCityName",newValue);
}
}
});
//----------变量结束----------
$(function () {
currentCity.currentCityId=57;
currentCity.currentCityName="武汉";
getCurrentCity(); // 调用定位的方法
//------------加载城市列表----------------
if (localStorage.getItem("cityList")) {
cityList = JSON.parse(localStorage.getItem("cityList"));
dealCityData();
} else {
$.get(baseURL + "/maoyanApi/dianying/cities.json", function (data) {
cityList = data.cts;
localStorage.setItem("cityList", JSON.stringify(cityList));
dealCityData();
});
}
//加载正在热映的电影
loadHotMovie();
//初始化swiper
mySwiper = new Swiper(".movieSwiper", {
on: {
// 当轮播发生改变的时候触发
slideChange: function () {
$(".topNav>li").eq(this.activeIndex+1).addClass("active").siblings().removeClass("active");
}
}
});
//点击头部导航的时候,要切换选项卡
$(".topNav>li").click(function (event) {
var index = $(this).index();
mySwiper.slideTo(index-1);
});
//点击定位的时候,弹出选择城市的列表
$(".positionCity").click(function(){
$(".cityListDiv").show();
});
$(".backToIndex").click(function(){
$(".cityListDiv").hide();
});
//点击电影去跳电影详细页
$(".hotMovieList,.comingMovieList").on("click",".movieItem",function(){
var m_id=$(this).data("m_id");
location.href="detail.html?m_id="+m_id;
});
});
//处理城市数据
function dealCityData() {
//对城市数据进行排序
cityList.sort(function (v1, v2) {
if (v1.py < v2.py) {
return -1;
} else if (v1.py == v2.py) {
return 0;
} else {
return 1;
}
});
//得到去重以后的首字母
firstLetterArray = cityList.map(function (item, index, a) {
return item.py.substr(0, 1);
}).filter(function (item, index, a) {
return index == a.indexOf(item);
});
//构建城市列表对象
for (var i in firstLetterArray) {
// 属性名
var propertyName = firstLetterArray[i];
cityListObj[propertyName] = [];
for (var j in cityList) {
if (propertyName == cityList[j].py.substr(0, 1)) {
cityListObj[propertyName].push(cityList[j]);
}
}
}
//渲染城市列表
$(".cityListDiv>ul.cityListItems").appendTpl("cityListDivTemp", {
cityListObj: cityListObj
});
//渲染城市索引
$(".cityListIndex").renderTpl("cityListIndexTemp", {
firstLetterArray: firstLetterArray
});
//加载better-scroll插件
cityListScroll = new BScroll(".cityListDiv", {
click: true //允许click事件
});
//点击索引以后的效果
$(".cityListIndex").on("click", "li", function () {
$(this).addClass("active").siblings().removeClass("active");
var firstLetter = $(this).text().trim();
cityListScroll.scrollToElement(document.getElementById("firstLetter_" + firstLetter));
});
//点击城市信息以后
$(".cityListItems").on("click", "li", function () {
currentCity.currentCityId = $(this).data("cityid");
currentCity.currentCityName = $(this).text().trim();
//更改显示的城市名称
$(".cityListDiv").hide();
});
//点击正在热映图片,实现预览效果
$(".hotMovieList").on("click",".movieItem img",function(event){
event.stopPropagation();
//渲染模板
$(".previewImageSwiper .swiper-wrapper").renderTpl("previewImageTemp",{
imageList:hotMovieListImage
});
//调用swiper插件方法
dealPreviewImage();
$(".previewImageDiv").show();
});
$(".previewImageDiv").click(function(){
$(this).hide();
});
//即将上映
$(".comingMovieList").on("click",".movieItem img",function(event){
event.stopPropagation();
//渲染模板
$(".previewImageSwiper .swiper-wrapper").renderTpl("previewImageTemp",{
imageList:comingMovieListImage
});
//调用swiper插件方法
dealPreviewImage();
$(".previewImageDiv").show();
});
}
//封装即将上映的电影信息
function loadComingMovie(ci){
$.get(baseURL + "/maoyanApi/ajax/comingList", {
ci: ci,
token: "",
limit: 10
}, function (data) {
comingMovieList=data.coming;
$(".comingMovieList").renderTpl("movieItemTemp", {
movieList: data.coming
});
//去处理即将上映的电影的图片预览
//进一步的去获取预览的图片
var imageWidth=document.documentElement.clientWidth;
var imageHeight= parseInt(imageWidth/128*180);
comingMovieListImage = comingMovieList.map(function(item,index,a){
return item.img.replace("w.h",imageWidth+"."+imageHeight);
});
});
}
//定位的方法
function getCurrentCity(){
var myCity = new BMap.LocalCity();
myCity.get(function(result){
var _tempArr = cityList.filter(function(item,index,a){
return result.name.indexOf(item.nm)!=-1;
});
if(_tempArr.length>0){
//有数据
layer.msg("定位成功,当前城市:"+result.name);
currentCity.currentCityId=_tempArr[0].id;
currentCity.currentCityName=_tempArr[0].nm;
}
else{
layer.msg("定位失败");
}
});
}
//正在热映
function loadHotMovie(){
$.get(baseURL + "/maoyanApi/ajax/movieOnInfoList", function (data) {
hotMovieList = data.movieList;
$(".hotMovieList").renderTpl("movieItemTemp", {
movieList: hotMovieList
});
//进一步的去获取预览的图片
var imageWidth=document.documentElement.clientWidth;
var imageHeight= parseInt(imageWidth/128*180);
hotMovieListImage = hotMovieList.map(function(item,index,a){
return item.img.replace("w.h",imageWidth+"."+imageHeight);
});
});
}
function dealPreviewImage(){
previewImageSwiper = new Swiper(".previewImageSwiper");
}
在上面的代码里面,我们把每个方法解释如下
- dealPreviewImage() 该方法用于处理预览图片,因为预览图片的元素要使用swiper轮播图的效果
- loadHotMovie() 该方法用于加载正在热映的电影信息
- getCurrentCity() 该方法用于调用百度地图定位的方法,在方法的内部当成功以后在
cityList
里面找到定位城市的ID进行赋值- loadComingMovie(ci) 该方法是要根据城市ID获取当前城市即将上映的电影
- dealCityData() 该方法是处理城市信息的数据,首先将城市信息以拼音进行了排序 ,然后又获取了拼音的首字母,组成了一个数组
firstLetterArray
,再根据这个数组创建了一个以首字母为属性名的对象cityListObj
,将首字母相同的放在一个集合里面以上是该案例当中的几个方法的用处
注意方法的同时,还要注意变量,变量的定义在代码当中已经做了说明,但还需单独说明
currentCity
这个变量,它是一个对象,我们通过Object.defineProperties()
的方法对其进行了两个属性访问器的定义,其作用是希望在设置currentCityName
当前城市与currentCityId
当前城市ID的时候能够做出一些相应的联动操作,例如刷新页面,更新缓存,请求数据等相关操作
电影详细页
当用户点击电影详细信息的时候,我们可以根据电影的ID跳转到电影的详细页,注意在这个案例过程当中的跨页面传值 ,我们此处仍然使用的是URLSearchParams
这个对象来进行的跨页面传值
detail.html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>猫眼电影</title>
<link rel="stylesheet" href="./js/swiper/css/swiper.css" type="text/css">
<link rel="stylesheet" href="./js/layer/theme/default/layer.css">
<link rel="stylesheet" href="./css/detail.css" type="text/css">
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function () {
document.documentElement.style.fontSize = document.documentElement.clientWidth / 750 * 100 + "px";
})
</script>
</head>
<body>
<div id="app">
<div class="header">
<span class="leftBack iconfont icon-icon-test" onclick="history.back()"></span>
<span class="title">猫眼电影</span>
<div class="rightIcon">
<span class="iconfont icon-shoucang"></span>
<span class="iconfont icon-fenxiang" data-clipboard-text=""></span>
</div>
</div>
<div class="content">
<div class="detailMovieDiv">
</div>
</div>
</div>
<div class="mask">
<video controls src="" id="v1"></video>
</div>
<template id="detailMovieTemp">
<div class="movieBox">
<img src="{{detailMovie.img.replace('w.h','128.180')}}" class="bgImg" alt="">
<div class="innerMovieBox">
<div class="left">
<img src="{{detailMovie.img.replace('w.h','128.180')}}" alt="">
<span class="iconfont icon-bofang-yuanshijituantubiao"></span>
</div>
<div class="center">
<div class="nm">{{detailMovie.nm}}</div>
<div class="sc">
<span>{{detailMovie.sc}}</span>({{detailMovie.wish}}想看)
</div>
<div>
{{detailMovie.cat}}
</div>
<div>
{{detailMovie.dur}}分钟
</div>
<div>{{detailMovie.rt}}</div>
</div>
<div class="right">
<span class="iconfont icon-right-arrow"></span>
</div>
</div>
</div>
<button type="button" class="discountsBtn">特惠购票</button>
<!-- 电影简介 -->
<div class="dra hide">
{{detailMovie.dra}}
</div>
<div class="dra_control">
<span class="iconfont icon-icon_sanjiaoxing"></span>
</div>
</template>
</body>
<script src="./js/jquery.js" type="text/javascript"></script>
<script src="./js/template-web.js" type="text/javascript"></script>
<script src="./js/juqery.extend.js" type="text/javascript"></script>
<script src="./js/swiper/js/swiper.js" type="text/javascript"></script>
<script src="./js/bscroll.js" type="text/javascript"></script>
<script src="./js/layer/layer.js" type="text/javascript"></script>
<script src="./js/clipboard.min.js" type="text/javascript"></script>
<script src="./js/detail.js" type="text/javascript"></script>
</html>
detail.css代码
@import "./comm.css";
.header{
position: relative;
}
.leftBack{
position: absolute;
left: .2rem;
}
.rightIcon{
position: absolute;
right: .2rem;
}
.rightIcon>span.iconfont{
margin-left: .2rem;
}
.innerMovieBox{
display: flex;
}
.innerMovieBox .left{
width: 1.8rem;
position: relative;
}
.innerMovieBox .left>img{
width: 100%;
height: auto;
display: block;
}
.innerMovieBox .center{
flex: 1;
font-size: .24rem;
color: white;
display: flex;
flex-direction: column;
justify-content: space-between;
margin-left: .2rem;
}
.innerMovieBox .center .nm{
font-size: .44rem;
}
.innerMovieBox .center .sc>span{
color: orange;
font-size: .44rem;
}
.innerMovieBox .right{
width: 1rem;
display: flex;
justify-content: center;
align-items: center;
}
.innerMovieBox .right .iconfont{
color: white;
}
.movieBox{
position: relative;
overflow: hidden;
box-sizing: border-box;
padding: .2rem;
}
/* 背景图 */
.movieBox .bgImg{
position: absolute;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
filter: blur(16px);
z-index:-1;
}
.discountsBtn{
border: none;
width: 95%;
height: .7rem;
background-color: var(--pColor);
color:white;
border-radius: .1rem;
display: block;
margin: .2rem auto;
letter-spacing: 1em;
}
body{
background-color: #F4F4F4;
}
/* 电影简介 */
.dra{
background-color: white;
font-size: .24rem;
padding: .2rem;
line-height:2;
text-indent: 2em;
overflow: hidden;
}
.dra.hide{
max-height: 0.9rem;
}
.dra_control{
background-color: white;
border-bottom: 1px solid lightgray;
display: flex;
justify-content: center;
cursor: pointer;
}
.dra_control.up .iconfont{
transform: rotateZ(180deg);
}
/* 播放电影的图标 */
.innerMovieBox .left .icon-bofang-yuanshijituantubiao{
position: absolute;
right: .1rem;
bottom: .1rem;
color: white;
font-size: .6rem;
}
/* 背景遮罩 */
.mask{
position: fixed;
left: 0px;
top: 0px;
right: 0px;
bottom: 0px;
background-color: rgba(0, 0, 0, 0.8);
display: flex;
align-items: center;
display: none;
}
#v1{
width: 100%;
}
页面布局完成以后,接下来进行事件与数据的处理,该页面要处理的事件主要是右上角的点击收藏 与 点击分享事件,以及下面的详细信息展开页面
detail.js代码
var baseURL = "https://www.softeem.xin";
var detailMovie=null;
var fenxiangBtnObj=null;
$(function(){
//把当前的url赋值到分享的按钮里面去
$(".rightIcon .icon-fenxiang").attr("data-clipboard-text",location.href);
//当我们去点击.icon-fenxiang这个元素以后,会把data-clipboard-text属性的值设置到系统的剪切板
fenxiangBtnObj = new ClipboardJS('.icon-fenxiang');
fenxiangBtnObj.on("success",function(event){
layer.msg("地址复制成功,请发送给小伙伴吧");
});
$(".detailMovieDiv ").on("click",".dra_control",function(){
$(this).toggleClass("up");
$(this).prev(".dra").toggleClass("hide");
});
//拿到上一个页面传过来的数据
var searchParams=new URLSearchParams(location.search);
var m_id=searchParams.get("m_id");
if(m_id){
getDetail(m_id);
}
else{
layer.msg("未获取到信息参数");
}
$(".detailMovieDiv").on("click",".icon-bofang-yuanshijituantubiao",function(){
$("#v1").attr("src",detailMovie.videourl);
$(".mask").slideDown().css("display","flex");
});
$(".mask").click(function(){
$(this).slideUp();
$("#v1")[0].pause();
})
});
function getDetail(m_id){
$.get(baseURL+"/maoyanApi/ajax/detailmovie",{
movieId:m_id
},function(data){
detailMovie=data.detailMovie;
$(".detailMovieDiv").renderTpl("detailMovieTemp",{
detailMovie:data.detailMovie
});
$(".header>.title").text(detailMovie.nm);
});
}
在上面的代码过程当中,我们发现我们使用了一个插件ClipboardJS
,它是一个前端的复制功能插件,在之前的案例说明章节已经讲过。此处主要的作用上当用户点击右上角的分享图标以后,将当前页在贩URL地址设置在系统的剪切板上面
同时,我们在页面加载的时候使用了URLSearchParams
进行了参数的获取
票房页功能
该页面主要是对电影的票房做一个显示 ,主要完成的功能则是票房数据的获取,以及下拉刷新的实现
boxoffice.html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>猫眼电影</title>
<link rel="stylesheet" href="./js/swiper/css/swiper.css" type="text/css">
<link rel="stylesheet" href="./js/layer/theme/default/layer.css">
<link rel="stylesheet" href="./css/boxoffice.css" type="text/css">
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function () {
document.documentElement.style.fontSize = document.documentElement.clientWidth / 750 * 100 + "px";
})
</script>
</head>
<body>
<div id="app">
<div class="header">
票房
</div>
<div class="content">
</div>
<ul class="tabBar">
<li data-url="index.html">
<span class="iconfont icon-dianying"></span>
<span>影片</span>
</li>
<li data-url="">
<span class="iconfont icon-yingyuana"></span>
<span>影院</span>
</li>
<li data-url="boxoffice.html" class="active">
<span class="iconfont icon-ranking"></span>
<span>票房</span>
</li>
<li data-url="">
<span class="iconfont icon-wode1"></span>
<span>我的</span>
</li>
</ul>
</div>
<template id="boxofficeTemp">
<div>
<ul class="topInfo">
<li>{{boxoffice.queryDate}} 今天大般:
<span>{{boxoffice.totalBoxInfo}}万</span>
</li>
<li>
每30分钟更新一次,可下拉手动刷新
</li>
</ul>
<div class="boxInfoList">
<div class="t_header">
<div class="col" style="min-width: 1.8rem">片名</div>
<div class="col">实时票房<br>(万元)</div>
<div class="col">票房占比</div>
<div class="col">排片占比</div>
<div class="col">上座率</div>
</div>
{{each boxoffice.list item index}}
<div class="t_data">
<div class="col ">
<div class="nm">{{item.movieName}}</div>
<div>{{item.releaseInfo}} {{item.splitSumBoxInfo}}</div>
</div>
<div class="col">
{{item.boxInfo}}
</div>
<div class="col">{{item.splitBoxRate}}</div>
<div class="col">{{item.showRate}}</div>
<div class="col">{{item.avgSeatView}}</div>
</div>
{{/each}}
</div>
</div>
</template>
</body>
<script src="./js/jquery.js" type="text/javascript"></script>
<script src="./js/template-web.js" type="text/javascript"></script>
<script src="./js/juqery.extend.js" type="text/javascript"></script>
<script src="./js/swiper/js/swiper.js" type="text/javascript"></script>
<script src="./js/bscroll.js" type="text/javascript"></script>
<script src="./js/layer/layer.js" type="text/javascript"></script>
<script src="./js/base.js" type="text/javascript"></script>
<script src="./js/boxoffice.js" type="text/javascript"></script>
</html>
boxoffice.css代码
@import "./comm.css";
body{
background-color: #f4f4f4;
}
.content{
overflow: auto;
}
.topInfo{
font-size: .28rem;
box-sizing: border-box;
padding: .2rem;
}
.topInfo>li{
padding: .05rem 0;
}
.topInfo>li>span{
color: red;
}
.topInfo>li:last-child{
font-size: .24rem;
}
.boxInfoList{
font-size: .24rem;
}
.t_header{
display: flex;
background-color: rgba(255,0,0,.6);
color: white;
}
.boxInfoList .col{
min-height: 1.1rem;
flex: 1;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
.t_data{
display: flex;
}
.t_data .col:first-child{
display: flex;
flex-direction: column;
min-width: 1.8rem;
}
.t_data .nm{
font-weight: bold;
}
.t_data .col:first-child+.col{
color: red;
}
.boxInfoList .t_data:nth-child(odd){
background-color: white;
}
boxoffice.js代码
var baseURL="https://www.softeem.xin";
var boxoffice=null;
var contentBScroll=null;
$(function(){
getBoxOffice();
});
//获取票房信息
function getBoxOffice(){
$.get(baseURL+"/maoyanApi/box/promovie/api/box/second.json",function(data){
boxoffice=data.data;
$(".content").renderTpl("boxofficeTemp",{
boxoffice:boxoffice
});
layer.msg("请求成功");
contentBScroll=new BScroll(".content",{
pullDownRefresh:true
});
//监听下拉刷新的事件
contentBScroll.on("pullingDown",function(){
getBoxOffice();
});
});
}
setInterval(getBoxOffice,1000*60*30);
下拉刷新的代码主要体现在对插件
better-scroll
插件的使用
底部tabBar功能
在之前的截图里面,我们可以看到,下面的四个选项点击以后是要跳转页面的,它主要的功能是在base.js
这个文件里面,代码如下
//这是四个页面都会用到的JS方法
$(function(){
$("#app").on("click",".tabBar li",function(){
if(!this.classList.contains("active")){
var url=$(this).data("url");
if(url){
//说明url有值
location.href=url;
}
}
});
});
判断条件this.classList.contains("active")
是为了判断如果点击的就是当前页,则不做任何处理
案例总结
该案例是一个综合性极强的案例,其主要目的是记同学们慢慢接触完整的项目案例,其实能够对之前所学的基本知识做一个综合,巩固之前所学的技能,并引出后面的新技术
现将本案例技术点例举如下
- jQuery的DOM操作
- jQuery事件委托的绑定
- art-template的使用,以及jQuery扩展方法对art-template的支持,学会自定义扩展方法
- 数组的使用,数组的排序,遍历的基本方法,案例当中的forEach,filter等使用场景
- Ajax请求的掌握以及API文档的查看
- swiper.js插件的使用
- better-scroll.js插件的使用
- layer.js的插件使用
- clipboard.js插件的使用
- 缓存的使用
- 跨页面传值的使用
- 百度地图城市定位API的使用
- 移动端基础布局的练习
- Object对象里面的访问器属性回顾与使用场景说明
评论区