一、需求描述
标题“多尺寸图片左右切换功能”,概括的不知道是否恰当,具体是需求如下。
- 一次点击按钮,向左或向右移动一个图片。
- 切换到尽头时不显示按钮
- 页面有三个尺寸
可以一睹为快,看一下最终效果。
二、切图代码
1)HTML代码
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<link rel="stylesheet" href="http://static9.pplive.cn/pub/flagment/v_20150114110035/header.min.css" />
<!--页面初始化CSS和页面公用头部的css-->
<link rel="stylesheet" href="css/vipgrowth.css">
<!--新增样式的css,名称可根据具体需求修改-->
<script type="text/javascript" src="http://static9.pplive.cn/vip/201508/center/v_20150901140940/js/jquery-1.9.1.min.js"></script>
<script>
window.onresize = function() {
var winWidth = document.body.clientWidth;
if (winWidth <= 1230) {
body.className = "grid-1010";
} else if (winWidth <= 1410) {
body.className = "grid-1230";
} else if (winWidth > 1410) {
body.className = "grid-1410";
} else {
alert("do not know!");
}
}
</script>
</head>
<body id="body">
<script>
//初始化状态显示样式判断,放在body后面
var winWidth = document.body.clientWidth;
if (winWidth <= 1230) {
body.className = "grid-1010";
} else if (winWidth <= 1410) {
body.className = "grid-1230";
} else if (winWidth > 1410) {
body.className = "grid-1410";
} else {
alert("do not know!");
}
</script>
<div class="vg-body">
<!--任务成长值 开始-->
<div class="vg_title">
<p>任务成长值</p>
</div>
<div class="vg_task">
<div class="arrowbtn-left"></div>
<div class="arrowbtn-right"></div>
<div class="vg_tasklist">
<ul class="cf" id="switchPic">
<li>
<img src="images/task_year.png">
<div class="rightinfo">
<h3>开通年费会员</h3>
<p>奖励成长值<span>200</span>点</p>
<a href="javascript:;">已完成></a>
</div>
<div class="task_hover">
<p class="task_desc">一次性开通年费会员(12个月及以上)</p>
<p class="task_limittimes">月限<span>1</span>次</p>
<a href="javascript:;" class="done">已完成</a>
</div>
</li>
<li>
<img src="images/task_lianxubaoyue.png">
<div class="rightinfo">
<h3>开通连续包月</h3>
<p>奖励成长值<span>10</span>点</p>
<a href="javascript:;">去完成></a>
</div>
<div class="task_hover">
<p class="task_desc">一次性开通年费会员(12个月及以上)</p>
<p class="task_limittimes">月限<span>1</span>次</p>
<a href="javascript:;">去完成></a>
</div>
</li>
<li>
<img src="images/task_year.png">
<div class="rightinfo">
<h3>升级成为SVIP</h3>
<p>奖励成长值<span>10</span>点</p>
<a href="javascript:;">去完成></a>
</div>
<div class="task_hover">
<p class="task_desc">一次性开通年费会员(12个月及以上)</p>
<p class="task_limittimes">月限<span>1</span>次</p>
<a href="javascript:;">去完成></a>
</div>
</li>
<li>
<img src="images/task_year.png">
<div class="rightinfo">
<h3>关注微信公众号</h3>
<p>奖励成长值<span>10</span>点</p>
<a href="javascript:;">去完成></a>
</div>
<div class="task_hover">
<p class="task_desc">一次性开通年费会员(12个月及以上)</p>
<p class="task_limittimes">月限<span>1</span>次</p>
<a href="javascript:;">去完成></a>
</div>
</li>
<li>
<img src="images/task_year.png">
<div class="rightinfo">
<h3>任务555555555</h3>
<p>奖励成长值<span>10</span>点</p>
<a href="javascript:;">去完成></a>
</div>
<div class="task_hover">
<p class="task_desc">一次性开通年费会员(12个月及以上)</p>
<p class="task_limittimes">月限<span>1</span>次</p>
<a href="javascript:;">去完成></a>
</div>
</li>
<li>
<img src="images/task_year.png">
<div class="rightinfo">
<h3>任务666666666</h3>
<p>奖励成长值<span>10</span>点</p>
<a href="javascript:;">去完成></a>
</div>
<div class="task_hover">
<p class="task_desc">一次性开通年费会员(12个月及以上)</p>
<p class="task_limittimes">月限<span>1</span>次</p>
<a href="javascript:;">去完成></a>
</div>
</li>
<li>
<img src="images/task_year.png">
<div class="rightinfo">
<h3>任务7777777</h3>
<p>奖励成长值<span>10</span>点</p>
<a href="javascript:;">去完成></a>
</div>
<div class="task_hover">
<p class="task_desc">一次性开通年费会员(12个月及以上)</p>
<p class="task_limittimes">月限<span>1</span>次</p>
<a href="javascript:;">去完成></a>
</div>
</li>
</ul>
</div>
</div>
<!--任务成长值 结束-->
</div>
</body>
<script>
//task growth
var switchPic = (function() {
/*
now:当前第几个li
linum:总共几个li
shownum:要展示几个li
w_li:li的宽度
marginR_li:li的右边距
*/
var now = 1;
var linum, shownum, offset, w_li, marginR_li, pre, next, wrap;
function init(o) {
pre = o.preBtn;
next = o.nextBtn;
wrap = o.wrap;
bindBtn();
}
function btnShow() {
getInfo();
if (linum <= shownum) { //如果li总个数小于要展示的个数,pre和next都不显示
pre.hide();
next.hide();
} else if (now == 1) { //初始化,只显示next
pre.hide();
next.show();
} else if (now == linum - shownum + 1) { //到最后一组,只显示pre
pre.show();
next.hide();
} else { //中间pre,next都显示。
pre.show();
next.show();
}
}
function getInfo() {
linum = $("#switchPic").find("li").size();
if ($("#body").hasClass("grid-1010")) {
shownum = 3;
w_li = wrap.find("li").outerWidth(); //算上了border的宽度
marginR_li = parseInt(wrap.find("li").css("marginRight"));
offset = w_li + marginR_li;
} else if ($("#body").hasClass("grid-1230")) {
shownum = 4;
w_li = wrap.find("li").outerWidth(); //算上了border的宽度
marginR_li = parseInt(wrap.find("li").css("marginRight"));
offset = w_li + marginR_li;
} else if ($("#body").hasClass("grid-1410")) {
shownum = 4;
w_li = wrap.find("li").outerWidth(); //算上了border的宽度
marginR_li = parseInt(wrap.find("li").css("marginRight"));
offset = w_li + marginR_li;
}
}
function bindBtn() {
btnShow();
next.on("click", function() {
now++;
btnShow();
wrap.stop(true).animate({
"margin-left": -(now - 1) * offset
});
});
pre.on("click", function() {
now--;
btnShow();
wrap.stop(true).animate({
"margin-left": -(now - 1) * offset
});
});
$(window).resize(function() {
now = 1;
btnShow();
wrap.animate({
"margin-left": 0
});
});
}
return {
init: init
}
})();
switchPic.init({
preBtn: $(".arrowbtn-left"),
nextBtn: $(".arrowbtn-right"),
wrap: $("#switchPic")
});
</script>
</html>
2)CSS代码
@charset "utf-8";
html,body{
background-color: #f6f5f5;
}
.vg-body{
width: 1390px;
margin:0 auto;
}
/*任务成长值*/
.vg_title{
font-size: 24px;
line-height: 24px;
padding:20px 0;
color:#464646;
}
.vg_task{
background-color: #fff;
position: relative;
}
.vg_task .arrowbtn-left,.vg_task .arrowbtn-right{
position: absolute;
top:70px;
width: 16px;
height: 20px;
cursor: pointer;
}
.vg_task .arrowbtn-left{
left: 40px;
background:url(../images/arrow-left.png) no-repeat;;
}
.vg_task .arrowbtn-right{
right: 40px;
background:url(../images/arrow-right.png) no-repeat;;
}
.vg_tasklist{
width: 1200px;
overflow: hidden;
margin:0 auto;
}
.vg_tasklist ul{width: 999%;}
.vg_tasklist li{
width: 258px;
height: 130px;
float: left;
border:1px solid #c8c8c8;
margin:15px 53px 15px 0;
position: relative;
}
.vg_tasklist li .task_hover{
position: absolute;
left: -1px;
top: -1px;
width: 212px;
padding:20px 25px 20px 23px;
height: 90px;
border-bottom: 2px solid #e65a5a;
overflow: hidden;
background-color: #f0f0f0;
display: none;
}
.vg_tasklist li:hover .task_hover{
display: block;
}
.task_hover .task_desc{
font-size: 16px;
line-height: 20px;
color:#646464;
}
.task_hover .task_limittimes{
font-size: 14px;
color: #787878;
float: left;
padding-top: 12px;
}
.vg_tasklist li img{
float: left;
margin: 22px 8px 20px 20px;
}
.vg_tasklist li .rightinfo{
width: 136px;
float: left;
text-align: center;
}
.rightinfo h3{
font-size: 16px;
color: #646464;
padding-top: 15px;
}
.rightinfo p{
font-size: 14px;
line-height: 26px;
color: #787878;
}
.rightinfo a,.task_hover a{
display: block;
text-align: center;
width: 96px;
height: 30px;
line-height: 30px;
border:2px solid #e65a5a;
border-radius: 5px;
font-size: 16px;
font-weight: 700;
color: #e65a5a;
}
.task_hover a.done,.task_hover a.done:hover{
background-color: #b4b4b4;
color: #fff;
border-color: #b4b4b4;
cursor: default;
}
.rightinfo a{
margin: 12px auto 0;
}
.task_hover a{
float: right;
margin-top: 18px;
margin-right: -4px;
}
.task_hover a:hover{
text-decoration: none;
background-color: #e65a5a;
color: #fff;
}
/*grid-1230*/
.grid-1230 .vg-body{
width: 1210px;
}
.grid-1230 .vg_tasklist{
width: 1090px;
}
.grid-1230 .vg_tasklist li{
margin-right: 16px;
}
.grid-1230 .vg_task .arrowbtn-left{
left: 33px;
}
.grid-1230 .vg_task .arrowbtn-right{
right: 33px;
}
.grid-1230 .vg_growth_table {
padding:24px 30px;
}
/*grid-1010*/
.grid-1010 .vg-body{
width: 990px;
}
.grid-1010 .vg_tasklist{
width: 850px;
}
.grid-1010 .vg_tasklist li{
margin-right: 35px;
}
.grid-1010 .vg_task .arrowbtn-left{
left: 30px;
}
.grid-1010 .vg_task .arrowbtn-right{
right: 30px;
}
.grid-1010 .vg_growth_table {
padding:24px;
}
3)切图分析
根据切好的图,向右切换的时候,margin需要向左移动的距离为(li的width+2*border+margin-right)。
width+2*border在jquery中可用用outerWidth()获取。
margin-right的值在jquery中用css("marginRight")获取。
三、Javascript交互部分
1)思路
总共就一个响应事件,就是点击按钮,以next按钮为例。点按钮发生了哪些事件。点击按钮—》ul产生位移—》更新按钮状态。或者点击按钮—》更新按钮状态—》ul产生位移。顺序可以改变
第一步:分析ul产生位移的过程。
抽象2个变量
now:表示当前页面第一个展示位展示的是第几个li,默认为1,向右切换now++,向左切换now--。
offset:表示i的width+2*border+margin-right。
这样点击按钮时的响应就变成了设置margin-left为-(now-1)*offset。
因为页面有三个尺寸,所以点击按钮时ul产生位移时需要根据尺寸计算出offset的值。
第二步,分析更新按钮状态的过程。
分析一下这句话“切换到尽头时不显示按钮”,页面默认只显示向右的按钮,切换到到最左边只显示向左的按钮,中间过程两个按钮都要显示。
抽象出几个变量:
linum:总共有几个li,一次切换一个。
shownum:页面需要展示几个li。
now:当前页面第一个展示位展示的是第几个li,默认为1,向右切换now++,向左切换now--。
分析几种情况:
- 如果li的总数小于要展示的数,即linum<shownum,pre和next按钮都不显示。
- 初始化,判断now为1,只显示next按钮。
- 展示到最后shownum个li的时候,即判断now==linum-shownum+1时,只显示next按钮。
- 否则pre和next按钮都显示。
因为页面有三个尺寸,所以点击按钮更新按钮状态时需要根据尺寸计算出shownum的值。
第三步:提取方法
把第一步和第二步中涉及通过尺寸获取信息的部分封装成一个函数。getInfo。
第二步更新按钮状态的封装成一个函数。btnShow。
第一步中给按钮绑定事件的过程封装成一个函数。bindBtn。
同时要注意,页面缩放的时候,需要重置一些状态。
2)Javascript代码
<script>
//task growth
var switchPic = (function() {
/*
now:当前第几个li
linum:总共几个li
shownum:要展示几个li
w_li:li的宽度
marginR_li:li的右边距
*/
var now = 1;
var linum, shownum, offset, w_li, marginR_li, pre, next, wrap;
function init(o) {
pre = o.preBtn;
next = o.nextBtn;
wrap = o.wrap;
bindBtn();
}
function btnShow() {
getInfo();
if (linum <= shownum) { //如果li总个数小于要展示的个数,pre和next都不显示
pre.hide();
next.hide();
} else if (now == 1) { //初始化,只显示next
pre.hide();
next.show();
} else if (now == linum - shownum + 1) { //到最后一组,只显示pre
pre.show();
next.hide();
} else { //中间pre,next都显示。
pre.show();
next.show();
}
}
function getInfo() {
linum = $("#switchPic").find("li").size();
if ($("#body").hasClass("grid-1010")) {
shownum = 3;
w_li = wrap.find("li").outerWidth(); //算上了border的宽度
marginR_li = parseInt(wrap.find("li").css("marginRight"));
offset = w_li + marginR_li;
} else if ($("#body").hasClass("grid-1230")) {
shownum = 4;
w_li = wrap.find("li").outerWidth(); //算上了border的宽度
marginR_li = parseInt(wrap.find("li").css("marginRight"));
offset = w_li + marginR_li;
} else if ($("#body").hasClass("grid-1410")) {
shownum = 4;
w_li = wrap.find("li").outerWidth(); //算上了border的宽度
marginR_li = parseInt(wrap.find("li").css("marginRight"));
offset = w_li + marginR_li;
}
}
function bindBtn() {
btnShow();
next.on("click", function() {
now++;
btnShow();
wrap.stop(true).animate({"margin-left": -(now - 1) * offset});
});
pre.on("click", function() {
now--;
btnShow();
wrap.stop(true).animate({"margin-left": -(now - 1) * offset});
});
$(window).resize(function() {
now = 1;
btnShow();
wrap.animate({"margin-left": 0});
});
}
return {init: init}
})();
switchPic.init({
preBtn: $(".arrowbtn-left"),
nextBtn: $(".arrowbtn-right"),
wrap: $("#switchPic")
});
</script>
四、提示
在写动画的时候,用了
wrap.stop(true).animate()
把当前元素涉及的所有动画都停止了,让后再触发。否则当页面快速resize,快速点击按钮多次,会产生“动画积累”,触发了下一个动画,之前的动画还没完,就会有一个延迟,影响用户体验。
stop()参数说明:
$(selector).stop(stopAll,goToEnd)
- stopAll,可选,规定是否停止被选元素的所有加入队列的动画。
- goToEnd,可选,规定是否允许完成当前的动画。该参数只能在设置了stopAll参数时使用。
具体用法:
- stop(true)等价于stop(true,false): 停止被选元素的所有加入队列的动画。
- stop(true,true):停止被选元素的所有加入队列的动画,但允许完成当前动画。
- stop()等价于stop(false,false):停止被选元素当前的动画,但允许完成以后队列的所有动画。
- stop(false,true):立即结束当前的动画到最终效果,然后完成以后队列的所有动画。
在此提供一个小 demo,可以帮助理解stop()各个参数。
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>stop的用法案例</title>
<style type="text/css">
#animater {
width: 150px;
background: activeborder;
border: 1px solid black;
/*为了移动,需设置此属性*/
position: relative;
}
</style>
<script src="http://code.jquery.com/jquery-3.1.0.js" integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk=" crossorigin="anonymous"></script>
<script type="text/javascript">
$(function() {
$("#start").click(function() {
$("#box").animate({
height: 300
}, "slow");
$("#box").animate({
width: 300
}, "slow");
$("#box").animate({
height: 100
}, "slow");
$("#box").animate({
width: 100
}, "slow");
});
// 点击不同的button执行不同的操作
$('#button1').click(function() {
//默认参数是false,不管写一个false还是两个false还是没写false效果一样
$('#box').stop();
});
$('#button2').click(function() {
//第二个参数默认false
$('#box').stop(true);
});
$('#button3').click(function() {
$('#box').stop(false, true);
});
$('#button4').click(function() {
$('#box').stop(true, true);
});
})
</script>
</head>
<body>
<p>
<input type='button' value='开始测试' id='start'>
</p>
<div id="button">
<input type="button" id="button1" value="stop()" />
<input type="button" id="button2" value="stop(true)" />
<input type="button" id="button3" value="stop(false,true)" />
<input type="button" id="button4" value="stop(true,true)" />
</div>
<div id="box" style="background:#98bf21;height:100px;width:100px;position:relative">stop运动参数测试</div>
</body>
</html>
转载于:多尺寸图片左右切换功能前端实现