项目需求:自适应页面,兼容安卓,IOS和PC。要求页面显示视频列表,点击列表中的图片和标题就可以播放视频,视频列表每页5条,能翻页。
本项目由于是需要大量的数据渲染以及后期的数据填充,所以决定使用模板引擎。
同时使用了boostrap作为部分UI框架。
使用Layer作为视频弹窗。
先说模板引擎及渲染
1.头部tab切换按钮如下:
<!--导航栏start-->
<nav class="container">
<ul class="country">
<li class="active selected" id="Americia">美国</li>
<li id="England">英国</li>
<li id="Canada">加拿大</li>
<li id="Austrilia">澳大利亚</li>
<li id="NewZealand">新西兰</li>
<li id="Europe">欧洲</li>
<li id="Asia">亚洲</li>
</ul>
</nav>
2.模板引擎引用的是腾讯的art_Template.
<script src="lib/template-web.js"></script>
模板引擎结构如下:
<!--模板引擎start-->
<script id="template" type="text/html">
<div class="item clearfix">
<div class="reload pull-left">
<div class="playreload">
<img class="reloadimg" src="<%=items.imgsrc%>" alt="" />
<div class="mengban"></div>
<img class="play" src="img/play.png" alt="" />
</div>
</div>
<div class="info pull-left">
<div class='top'>
<span class="classify"><%=items.classify%></span>
<span class="title"> <%=items.title%></span>
<span class="time">
<span class="glyphicon glyphicon-time "></span>
<span class="pubdate "><%=items.pubdate%></span>
</span>
</div>
<p class='intro text-overflow'>
<%=items.intro%>
</p>
<div class="bot">
<span class="jia">嘉</span>
<span class="name"><%=items.name%></span>
<span>
</span>
<span class="zhi">职</span>
<span class="position"><%=items.position%></span>
<span class="click-rite"></span>
</div>
</div>
</div>
</script>
<!--模板引擎end-->
该模板引擎很好的保证了页面原结构,即使我这样的初学者也可以使用它。
注意它的官方如下:art-template官方文档
标准语法:
`{{value}}
{{data.key}}
{{data['key']}}
{{a ? b : c}}
{{a || b}}
{{a + b}}`
原始语法:
<%= value %>
<%= data.key %>
<%= data['key'] %>
<%= a ? b : c %>
<%= a || b %>
<%= a + b %>
直接按照原来的结构然后按照模板的语法进行修改就是了。
3. JS处理:
window.onload = function() {
var data;
$.ajax({
dataType: 'json',
url: 'data.json',
data: data,
type: 'get',
success: function(data, key) {
//转化为js对象
var jsArr = data;
//遍历JSON对象,将JSON对象转化为数组
for(var key in jsArr) {};
//点击国家按钮显示指定内容
$("body").on("click", ".country>li", function(e) {
$(this).addClass('active').siblings().removeClass('active');
//获取当前tab中鼠标停在的table栏的索引
var index = $(this).index();
//根据这个索引切换,下面的展示
$("li").eq(index).addClass("selected").siblings().removeClass("selected");
//获取当前点击项目的ID
var indexId = $(this).attr('id');
//新建数组,将当前点击项的id赋值给当前要显示的数组作为KEY值,就获取的当前显示项的数据
var jsArri = jsArr[this.id];
if(jsArri === undefined || jsArri.length == 0) {
$('.medialist').html('<img class="no-content" style="" src="img/no_content.png" alt="" />');
$('#page').hide();
} else {
$('#page').show();
}
// 分页
$('#page').html("");
var pageData = jsArri.length;
$(function() {
var count = pageData; //设置总条数
var pageSize = 5; //每页显示的条数
var pageCount = Math.ceil(count / pageSize); //能显示几页
var currentPage = 1; //默认显示第一页
//做个分页按钮
for(var i = 1; i <= pageCount; i++) {
var pageN = '<span class="pageName" selectPage="' + i + '">' + i + '</span>'
$('#page').append(pageN);
}
//默认显示第一页
$('.medialist').html('');
for(i = (currentPage - 1) * pageSize; i < pageSize * currentPage; i++) {
var obj = {
items: jsArri[i]
};
var result = template('template', obj);
$('.medialist').append(result);
$('#page span:first-child').addClass('choosed')
};
//显示选择页的内容
$('.pageName').click(function() {
var selectPage = $(this).attr('selectPage');
$('#page').children('span').removeClass('choosed');
$('#page').children('span').eq(selectPage - 1).addClass('choosed');
$('.medialist').html('');
// 判断是否是最后一页
if(selectPage == pageCount) {
for(i = (selectPage - 1) * pageSize; i < pageData; i++) {
var obj = {
items: jsArri[i]
};
var result = template('template', obj);
$('.medialist').append(result);
}
} else {
for(i = (selectPage - 1) * pageSize; i < pageSize * selectPage; i++) {
var obj = {
items: jsArri[i]
};
console.log(obj);
var result = template('template', obj);
console.log(result);
$('.medialist').append(result);
}
}
});
})
//点击预览图显示弹窗
$(".reload,.title").on("click", function() {
//取得当前点击的预览图的下标
var indexB = $(this).parent().parent().parent().index();
//将预览图的下标作为当前显示的国家数据的中的urlpc值
var urlpc = jsArri[indexB].urlpc;
var title = jsArri[indexB].title;
if(navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i)) {
//Layer弹窗开始
layer.open({
type: 2,
title: title,
area: ['320px', '240px'],
shade: 0.6,
closeBtn: 0,
shadeClose: true,
content: urlpc,
});
} else {
//Layer弹窗开始
layer.open({
type: 2,
title: title,
area: ['640px', '360px'],
shade: 0.6,
closeBtn: 0,
shadeClose: true,
content: urlpc,
});
layer.msg('点击任意处可关闭', function() {
time: 500
})
//Layer弹窗结束
}
});
});
//加载第一项美国
$("#Americia").trigger("click");
}
})
JS这里的思路解析
JS是重点项目,在这里遇到了很多问题。
1.需要PHP对JSON进行转换【注意:这段方法可以用js代替,所以可把这段php文件删除】
代码就这一行:
<?php
echo file_get_contents("data.json")
?>
还需要注意,使用PHP必须要开虚拟机,因为php是后台语言。否则浏览器会报json格式错误。
这里的file_get_contents()方法只是获取数据,加上echo是输出的意思。
2.然后再AJAX中,就可以直接引入php文件:【注意:这段方法可以用js代替】
url: 'artTemp.php',
一般用get方式
type: 'get',
Get是向服务器发索取数据的一种请求,而Post是向服务器提交数据的一种请求.通常我们请求数据用get,保存密码用post.
数据请求成功后对数据进行处理:
success:function()
{ ...... }
【1、2中用JS代替的方法】
这里如果要用PHP的话,需要用到虚拟机,以及对php有基本的了解;其实可以用jquery来代替,让ajax直接获取data.json:
var data;
$.ajax({
dataType:'json',
url:'data.json',
data:data,
type: 'get',
success: function(data, key) {
//转化为js对象
var jsArr = data;
这里要注意首先需要在ajax之前var 一个data变量,然后再ajax获取到data.json后将值传入data变量:
data:data,
同时,在success中的:var jsArr =JSON.parse(data)就可以直接换成var jsArr = data。因为
JSON.parse() 方法用来解析JSON字符串,构造由字符串描述的JavaScript值或对象。
在这里还需设置dataType:json;因为在jquery文档中有这么一句:
这样就不需要在用JSON.parse()方法了。关于这一点,这篇文章有说明:
How to Use JSON Data with PHP or JavaScript
这里马上说的JSON.parse就可以不用了↓↓↓↓
3.将data数据转化为JSON对象
使用JSON.parse()方法:
var jsArr = JSON.parse(data);
4.将JSON对象转化为数组
然后再遍历JSON对象,将JSON转化为数组:
for(var key in jsArr) {
console.log(jsArr[key])
};
5.点击国家按钮显示对应内容
然后是点击事件,点击指定的国家显示相应的视频内容列表:
//此处使用的是事件委托,将li的点击委托给body.
$("body").on("click", ".country>li", function(e) {
//给当前点击项添加active样式,先给自己添加样式,再干掉其他人的样式。
$(this).addClass('active').siblings().removeClass('active');
//获取当前tab中鼠标停在的table栏的索引
var index = $(this).index();
//根据这个索引切换,下面的展示 $("li").eq(index).addClass("selected").siblings().removeClass("selected");
//获取当前点击项目的ID
var indexId = $(this).attr('id');
//【重要】新建数组,将当前点击项的id赋值给当前要显示的数组作为KEY值,就获取的当前显示项的数据
console.log(jsArr[this.id])
var jsArri = jsArr[this.id];
//此处由于json中的数据不完整,还导致我看错了,一直点击没有数据的按钮,然后提示undefind....
接下俩还需要根据请求到的数据,如果 数据为空,就显示提示图片:没有内容;如果有数据,显示内容。
判断:
if(jsArri === undefined || jsArri.length == 0) {
$('.medialist').html('<img class="no-content" style=""
src="img/no_content.png" alt="" />');
$('#page').hide();
} else {
$('#page').show();
}
然后是对内容进行分页显示
此处稍微复杂,我用的是自己编写的分页工具,应为各种插件和需求不相符。
首先对分页工具进行清空
$('#page').html("");
设置变量pagedata,将当前请求到的国家内的 数据长度赋值给它,就求到了请求到的数据有几条
var pageData = jsArri.length;
进行分页:
$(function() {
var count = pageData; //设置总条数
var pageSize = 5; //每页显示的条数
var pageCount = Math.ceil(count / pageSize); //能显示几页
var currentPage = 1; //默认显示第一页
//做个分页按钮
for(var i = 1; i <= pageCount; i++) {
var pageN = '<span class="pageName" selectPage="' + i + '">' + i + '</span>'
$('#page').append(pageN);
这样就显示出基本的分页列表了。
}
//默认显示第一页
清空视频列表
$('.medialist').html('');
由于数据index从0开始算,所以要用i=当前显示的数字-1.
for(i = (currentPage - 1) * pageSize; i < pageSize * currentPage; i++) {
var obj = {
items: jsArri[i]
};
在循环中渲染模板引擎
var result = template('template', obj);
$('.medialist').append(result);
给第一页分页添加样式
$('#page span:first-child').addClass('choosed')
};
//显示选择页的内容
$('.pageName').click(function() {
选取到当前被点击的分页数字
var selectPage = $(this).attr('selectPage');
给其他分页数字去掉选中样式
$('#page').children('span').removeClass('choosed');
给当前选中的分页数字添加样式
$('#page').children('span').eq(selectPage - 1).addClass('choosed');
清空
$('.medialist').html('');
// 判断是否是最后一页
如果是最后一页,只需要渲染最后几条数据:
if(selectPage == pageCount) {
for(i = (selectPage - 1) * pageSize; i < pageData; i++) {
var obj = {
items: jsArri[i]
};
var result = template('template', obj);
$('.medialist').append(result);
}
} else {
//如果不是最后一页,就是中间的页面,就直接计算出是那几条数据进行渲染。
for(i = (selectPage - 1) * pageSize; i < pageSize * selectPage; i++) {
var obj = {
items: jsArri[i]
};
console.log(obj);
var result = template('template', obj);
console.log(result);
$('.medialist').append(result);
}
}
});
})
至此,已经完显示了json中的数据。
还有一点,由于渲染数据是由点击上面的按钮实现的,所以在页面加载后默认的第一项美国是不显示的,所以需要美国的内容显示,就要在页面加载完毕后模拟点击事件,此处使用trigger()方法:
$("#Americia").trigger("click");
这样就可以页面加载后第一页显示默认的国家栏目的数据啦,如果想第一页显示其他国家的数据,直接替换ID即可。
接下来的部分会演示如何利用Layer插件播放视频。
4.点击视频预览图播放视频
首先当然是要给预览图的标签注册点击事件:
这里可以用事件委托
$(".title").on("click", function() { ...... }
然后再在点击事件中获取当前点击项的index:
var indexB = $('.item').find('img').index($(this));
也可以这么写:
var indexB = $(this).parent().parent().index()
这个更容易理解,找当前被点击元素的父元素的父元素,再取他的index,因为每个父元素都有唯一一个img,所以就得到了index!
5.实现点击图片和标题均可播放视频:
要想实现点击图片和标题都可以播放视频,那么必须给他们绑定同一个事件。
jquery为多个选择器绑定同一个事件方法:
("#start,#end").on("click",function(){
alert("The paragraph was clicked.");
});
所以此处可以使用这个方法:
$(".reload,.title").on("click",function() { }
但是在接下来的取indexB值的时候遇到了问题:$('.reloadimg')和 $('.title')他们的路径不一样,如何然他们取得index值相同呢?
这里就必须要对元素进行相对定位,找出他们的共同祖先元素,让我们往模板的结构里看:
<div class="item clearfix">
<div class="reload pull-left">
<img class="reloadimg" src="<%=items.imgsrc%>" alt="" />
<div class="mengban"></div>
<img class="play" src="img/play.png" alt="" />
</div>
<div class="info pull-left">
<div class='top'>
<span class="classify"><%=items.classify%></span>
<span class="title"> <%=items.title%></span>
<span class="time">
<span class="glyphicon glyphicon-time "></span>
<span class="pubdate "><%=items.pubdate%></span>
</span>
</div>
<p class='intro text-overflow'>
<%=items.intro%>
</p>
<div class="bot">
<span class="jia">嘉</span>
<span class="name"><%=items.name%></span>
<span>
</span>
<span class="zhi">职</span>
<span class="position"><%=items.position%></span>
<span class="click-rite"></span>
</div>
</div>
</div>
从这里可以看出他们的公共祖先元素自然就是$(".item")啦,所以,怎样让他们用一行代码就同时找到他们的公共祖先元素?而且是点击他们中的任意一项都能找到?我们自然想到了刚才的这种办法:
var indexB = $(this).parent().parent().index()
这里的$(this)指代的是当前项,既可以表示$(".img"),又可以表示$(".title"),但是从结构上看,$(".img")只用向上找两层就可以找到item,但是$(".title")却需要往上找三层才可以找到item,怎么办?
我们可以给$(".img")再套一个div:
<div class="item clearfix">
<div class="reload pull-left" >
<div class="playreload">
<img class="reloadimg" src="<%=items.imgsrc%>" alt="" />
<div class="mengban"></div>
<img class="play" src="img/play.png" alt="" />
</div>
</div>
<div class="info pull-left">
<div class='top'>
<span class="classify"><%=items[i].classify%></span>
<span class="title"><%=items[i].title%></span>
<span class="pubdate pull-right"><%=items[i].pubdate%></span>
<span class="glyphicon glyphicon-time pull-right"></span>
</div>
<p class='intro text-overflow'>
<%=items[i].intro%>
</p>
<div class="bot">
<span class="jia">嘉</span>
<span class="name"><%=items[i].name%></span>
<span class="zhi">职</span>
<span class="position"><%=items[i].position%></span>
<span class="glyphicon glyphicon-eye-open"></span>
<span class="click-rite">888</span>
</div>
</div>
</div>
这样他们是不是就在同一层级了?
然后用:
var indexB = $(this).parent().parent().parent().index();
就可以获取到当前点击项和另一项的共同index啦!
然后将预览图的下标作为当前显示的国家数据中的urlpc值
var urlpc = jsArri[indexB].urlpc;
var title = jsArri[indexB].title;
最后使用layer插件:
在此奉上 layer弹出层插件官方演示文档
这里还需要判断客户端:
if(navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i)) {
//Layer弹窗开始
layer.open({
type: 2,
title: title,
area: ['320px', '240px'],
shade: 0.6,
closeBtn: 0,
shadeClose: true,
content: urlpc,
});
} else {
//Layer弹窗开始
layer.open({
type: 2,
title: title,
area: ['640px', '360px'],
shade: 0.6,
closeBtn: 0,
shadeClose: true,
content: urlpc,
});
layer.msg('点击任意处可关闭', function() {
time: 500
})
//Layer弹窗结束
}
OK,已经可以实现点击预览图显示对应的视频了!
同时别忘了给美国追加click事件,不然第一页的数据不显示,因为显示隐藏是通过click操作的:
//加载第一项美国
$("#Americia").trigger("click");
至此已经完成业务逻辑的重要部分,css移动端就不用说了,套boostrap就是,有疑问请评论。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。