这次我们来实现一个活动的签到页面以及相关的交互效果,具体实现后的Demo效果可以查看链接——签到页面(打开速度有些慢,见谅)
素材和实例demo是在网上找的,我这边就一边把代码放上来,一边再把基本的实现方法跟大家分享一下。
首先是HTML布局方面,整体基本是用图片拼接起来,这点对于大家来说都是很简单的了,图片如下所示:
中间内容页右侧部分是签到按钮+公告栏,公告栏就不说了,上方的签到按钮是用通过改变DIV的背景图片位置(即CSS Spirite方法),来显示交互效果。
左侧是日期列表,用于显示已签到的次数,具体实现方法则是用一个ul列表,用jquery来改变li的数量(因为每个月的天数是不一样的,所以li的总数每个月是需要发生变化的的,因此不能设置成固定的),所以这个ul列表一开始是一个空的列表,至于签到后显示的弹窗则是用遮罩层来实现的。下面我把具体的代码放上来,大家可以参考一下。
HTML:
<body>
<div class="qiandao-warp">
<div class="qiandap-box">
<div class="qiandao-banner">
<img src="images/qiandao_banner.jpg" height="551" width="1120" alt="">
</div>
<div class="qiandao-con clear">
<div class="qiandao-left">
<div class="qiandao-left-top clear">
<div class="current-date">2016年1月6日</div>
<div class="qiandao-history qiandao-tran qiandao-radius" id="js-qiandao-history">我的签到</div>
</div>
<div class="qiandao-main" id="js-qiandao-main">
<ul class="qiandao-list" id="js-qiandao-list">
</ul>
</div>
</div>
<div class="qiandao-right">
<div class="qiandao-top">
<div class="just-qiandao qiandao-sprits" id="js-just-qiandao">
</div>
<p class="qiandao-notic">今日已领<span>0.1</span>元,请明日继续签到</p>
</div>
<div class="qiandao-bottom">
<div class="qiandao-rule-list">
<h4>签到规则</h4>
<p>首次签到获得0.05元现金奖励</p>
<p>连续签到每天增加0.01元现金奖励</p>
<p>连续签到16天及以上每天获得0.2元现金奖励</p>
</div>
<div class="qiandao-rule-list">
<h4>其他说明</h4>
<p>如果中间有一天间断未签到的,重先开始计算连续签到时间。</p>
<p>连续签到获得奖励后分享到QQ空间、微信朋友圈后再获得一次奖励,每天只限分享一次。</p>
<p>获得的奖励不能直接提现,只能投资后转让变现。</p>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 我的签到 layer start -->
<div class="qiandao-layer qiandao-history-layer">
<div class="qiandao-layer-con qiandao-radius">
<a href="javascript:;" class="close-qiandao-layer qiandao-sprits"></a>
<ul class="qiandao-history-inf clear">
<li>
<p>连续签到</p>
<h4>5</h4>
</li>
<li>
<p>本月签到</p>
<h4>17</h4>
</li>
<li>
<p>总共签到数</p>
<h4>28</h4>
</li>
<li>
<p>签到累计奖励</p>
<h4>30</h4>
</li>
</ul>
<div class="qiandao-history-table">
<table>
<thead>
<tr>
<th>签到日期</th>
<th>奖励</th>
<th>说明</th>
</tr>
</thead>
<table>
<tr>
<td>2016-1-6 14:23:45</td>
<td>0.20</td>
<td>连续签到19天奖励</td>
</tr>
<tr>
<td>2016-1-6 14:23:45</td>
<td>0.20</td>
<td>分享奖励</td>
</tr>
<tr>
<td>2016-1-6 14:23:45</td>
<td>0.20</td>
<td>连续签到19天奖励</td>
</tr>
<tr>
<td>2016-1-6 14:23:45</td>
<td>0.20</td>
<td>连续签到19天奖励</td>
</tr>
<tr>
<td>2016-1-6 14:23:45</td>
<td>0.20</td>
<td>连续签到19天奖励</td>
</tr>
<tr>
<td>2016-1-6 14:23:45</td>
<td>0.20</td>
<td>连续签到19天奖励</td>
</tr>
<tr>
<td>2016-1-6 14:23:45</td>
<td>0.20</td>
<td>连续签到19天奖励</td>
</tr>
<tr>
<td>2016-1-6 14:23:45</td>
<td>0.20</td>
<td>连续签到19天奖励</td>
</tr>
</table>
</table>
</div>
</div>
<div class="qiandao-layer-bg"></div>
</div>
<!-- 我的签到 layer end -->
<!-- 签到 layer start -->
<div class="qiandao-layer qiandao-active">
<div class="qiandao-layer-con qiandao-radius">
<a href="javascript:;" class="close-qiandao-layer qiandao-sprits"></a>
<div class="yiqiandao clear">
<div class="yiqiandao-icon qiandao-sprits"></div>您已连续签到<span>2</span>天
</div>
<div class="qiandao-jiangli qiandao-sprits">
<span class="qiandao-jiangli-num">0.55<em>元</em></span>
</div>
<a href="#" class="qiandao-share qiandao-tran">分享获取双倍收益</a>
</div>
<div class="qiandao-layer-bg"></div>
</div>
<!-- 签到 layer end -->
<script src="js/jquery-1.10.2.min.js"></script>
<script src="js/qiandao_js.js"></script>
</body>
CSS部分:
* {
margin: 0;
padding: 0
}
li {
list-style: none
}
img {
vertical-align: top
}
.clear {
clear: both
}
.clear:after {
clear: both;
display: table;
content: ''
}
.qiandao-sprits {
background-image: url(../images/qiandao_sprits.png);
background-repeat: no-repeat
}
.qiandao-tran {
-webkit-transition: all .3s ease-out;
-moz-transition: all .3s ease-out;
-o-transition: all .3s ease-out;
transition: all .3s ease-out;
-ms-transition: all .3s ease-out
}
.qiandao-radius {
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
-o-border-radius: 5px;
-ms-border-radius: 5px
}
.qiandao-warp {
height: 1306px;
background: url(../images/qiandao_warp_bg.jpg) no-repeat top center
}
.qiandap-box {
margin: 0 auto;
width: 70pc;
height: 1306px;
background-color: #4d56a3
}
.qiandao-con {
margin: 0 auto;
width: 1035px;
height: 684px;
background-image: url(../images/qiandao_con.jpg)
}
.qiandao-left {
float: left;
padding: 20px 42px 0 39px;
width: 603px
}
.qiandao-right {
float: right;
padding: 0 20px;
width: 290px
}
.current-date {
float: left;
padding-top: 5px;
padding-left: 55px;
color: #b25d06;
font-size: 18px
}
.qiandao-history {
float: right;
width: 92px;
height: 36px;
border-radius: 4px;
background-color: #b25d06;
color: #fff;
text-align: center;
font-size: 1pc;
line-height: 36px;
cursor: pointer
}
.qiandao-history:hover {
background-color: #9c4f01
}
.qiandao-top {
padding-top: 70px;
height: 13pc
}
.just-qiandao {
margin: 0 auto 20px;
width: 212px;
height: 67px;
cursor: pointer
}
.just-qiandao.actived, .just-qiandao:active {
background-position: 0 -68px
}
.qiandao-notic {
color: #b25d06;
text-align: center;
font-size: 18px
}
.qiandao-rule-list {
margin-bottom: 35px;
color: #8d8ebb;
font-size: 1pc;
line-height: 26px
}
.qiandao-rule-list h4 {
font-weight: bolder;
font-size: 1pc
}
.qiandao-main {
overflow: hidden;
width: 603px
}
.qiandao-list {
margin-top: 76px;
margin-right: -10px
}
.qiandao-list li {
position: relative;
float: left;
margin: 0 1px 1px 0;
width: 85px;
height: 85px;
background-image: url(../images/qiandao_day.png);
background-position: 0 0
}
.qiandao-list li.date1 {
background-position: -430px 0
}
.qiandao-list li.date2 {
background-position: -516px 0
}
.qiandao-list li.date3 {
background-position: 0 -86px
}
.qiandao-list li.date4 {
background-position: -86px -86px
}
.qiandao-list li.date5 {
background-position: -172px -86px
}
.qiandao-list li.date6 {
background-position: -258px -86px
}
.qiandao-list li.date7 {
background-position: -344px -86px
}
.qiandao-list li.date8 {
background-position: -430px -86px
}
.qiandao-list li.date9 {
background-position: -516px -86px
}
.qiandao-list li.date10 {
background-position: 0 -172px
}
.qiandao-list li.date11 {
background-position: -86px -172px
}
.qiandao-list li.date12 {
background-position: -172px -172px
}
.qiandao-list li.date13 {
background-position: -258px -172px
}
.qiandao-list li.date14 {
background-position: -344px -172px
}
.qiandao-list li.date15 {
background-position: -430px -172px
}
.qiandao-list li.date16 {
background-position: -516px -172px
}
.qiandao-list li.date17 {
background-position: 0 -258px
}
.qiandao-list li.date18 {
background-position: -86px -258px
}
.qiandao-list li.date19 {
background-position: -172px -258px
}
.qiandao-list li.date20 {
background-position: -258px -258px
}
.qiandao-list li.date21 {
background-position: -344px -258px
}
.qiandao-list li.date22 {
background-position: -430px -258px
}
.qiandao-list li.date23 {
background-position: -516px -258px
}
.qiandao-list li.date24 {
background-position: 0 -344px
}
.qiandao-list li.date25 {
background-position: -86px -344px
}
.qiandao-list li.date26 {
background-position: -172px -344px
}
.qiandao-list li.date27 {
background-position: -258px -344px
}
.qiandao-list li.date28 {
background-position: -344px -344px
}
.qiandao-list li.date29 {
background-position: -430px -344px
}
.qiandao-list li.date30 {
background-position: -516px -344px
}
.qiandao-list li.date31 {
background-position: 0 -430px
}
.qiandao-list li .qiandao-icon {
position: absolute;
top: 0;
left: 0;
z-index: 2;
display: none;
width: 85px;
height: 85px;
background: url(../images/qiandao_icon.png) no-repeat center center
}
.qiandao-list li.qiandao .qiandao-icon {
display: block
}
.qiandao-layer {
position: fixed;
top: 0;
bottom: 0;
left: 0;
z-index: 888;
display: none;
width: 100%
}
.qiandao-layer-bg {
width: 100%;
height: 100%;
background-color: #000;
opacity: .55;
filter: alpha(opacity=55)
}
.qiandao-layer-con {
position: absolute;
top: 50%;
left: 50%;
z-index: 999;
padding-top: 30px;
border: 3px #33b23f solid;
border-radius: 5px;
background-color: #fff
}
.qiandao-history-layer .qiandao-layer-con {
margin: -257px 0 0 -293px;
width: 586px;
height: 484px
}
.close-qiandao-layer {
position: absolute;
top: 13px;
right: 13px;
width: 1pc;
height: 1pc;
background-position: -228px -51px
}
.qiandao-history-inf {
margin-top: 25px;
color: #666;
text-align: center;
font-size: 14px
}
.qiandao-history-inf li {
float: left;
width: 25%
}
.qiandao-history-inf li h4 {
color: #33b23f;
font-size: 40px;
line-height: 50px
}
.qiandao-history-table {
overflow: hidden;
margin: 20px;
-webkit-border-radius: 5px 5px 0 0;
-moz-border-radius: 5px 5px 0 0;
border-radius: 5px 5px 0 0;
-o-border-radius: 5px 5px 0 0;
-ms-border-radius: 5px 5px 0 0
}
.qiandao-history-table table {
width: 100%;
color: #666;
text-align: center;
font-size: 1pc;
border-spacing: 0
}
.qiandao-history-table table th {
width: 33.3%;
background-color: #f2f2f2;
text-align: center;
line-height: 40px
}
.qiandao-history-table td {
width: 33.3%;
border-bottom: 1px #e5e5e5 dashed;
line-height: 34px
}
.qiandao-active .qiandao-layer-con {
margin: -232px 0 0 -211px;
width: 422px;
height: 434px
}
.yiqiandao {
margin: 36px 0 0 40px;
color: #666;
font-size: 14px;
line-height: 38px
}
.yiqiandao .yiqiandao-icon {
float: left;
margin: 0 25px;
width: 178px;
height: 38px;
background-position: -217px 0
}
.qiandao-jiangli {
position: relative;
margin: 45px auto;
width: 335px;
height: 170px;
background-position: 0 -146px
}
.qiandao-jiangli span {
position: absolute;
top: 58px;
left: 50px;
display: block;
width: 178px;
height: 106px;
color: #ff7300;
text-align: center;
font-weight: bolder;
font-size: 30px;
line-height: 106px
}
.qiandao-jiangli span em {
padding-left: 5px;
font-style: normal;
font-size: 1pc
}
.qiandao-share {
display: block;
margin: 60px auto 0;
width: 318px;
height: 3pc;
border-radius: 5px;
background-color: #4ab854;
color: #fff;
text-align: center;
text-decoration: none;
font-size: 18px;
line-height: 3pc
}
.qiandao-share:hover {
background-color: #3e9d46
}
接下来是JS代码:
$(function() {
var signFun = function() {
var dateArray = [1,4,5,7] // 自定义一个数组,用于显示在列表上事先已经签到的日期
var $dateBox = $("#js-qiandao-list"), //获取ul列表
$currentDate = $(".current-date"), //用于显示当前时间
$qiandaoBnt = $("#js-just-qiandao"), //获取右上侧签到按钮
_html = '',
_handle = true, //这个_handle是自定义的属性,用于表面右上侧的签到按钮状态,如果handle是true,则表面可以签到。
myDate = new Date(); //获取当前时间
$currentDate.text(myDate.getFullYear() + '年' + (myDate.getMonth() + 1) + '月' + myDate.getDate() + '日');
// 因为getMonth是从0开始计算的,myDate.getMonth()输出的结果是当前月份-1,所以实际使用时需要+1
var monthFirst = new Date(myDate.getFullYear(), (myDate.getMonth()), 1).getDay();
// 这个属性用于用于显示当前月份第一天是星期几,例如9月第一天是星期四,所以生成的li列表要从星期四开始算起,前面的四个li是空置的。
// 这里计算当前月份的第一天是星期几,不需要在getMonth上+1。如果是在括号里面加上引号的话,那就需要+1,这点大家可以试一下,具体原因我也不是很确定
var d = new Date(myDate.getFullYear(), myDate.getMonth() + 1, 0);
var totalDay = d.getDate(); //获取当前月的天数
for (var i = 0; i < 42; i++) {
_html += ' <li><div class="qiandao-icon"></div></li>';
//用于动态创建li列表,并且在每个li中都要生成一个div用于显示签到的那个状态(就是那个绿色的圈圈)
//生成的li和div大小都是一样的,并且div的层级要比li高,但是初始状态是display:none;在签到之后显示block,这样这个绿色圈圈就会覆盖在li上面就是我们看到的情况。
}
$dateBox.html(_html) //动态生成日历网格
var $dateLi = $dateBox.find("li");
for (var i = 0; i < totalDay; i++) {
$dateLi.eq(i + monthFirst).addClass("date" + (i + 1));
//这里可以看出monthFirst的作用,让列表从0+4个位置开始(当前9月份从星期四开始),并且给每个li添加Class,这个Class时在CSS忠设置好的,也是用的CSS Spirite
for (var j = 0; j < dateArray.length; j++) {
if (i == dateArray[j]) {
$dateLi.eq(i-1 + monthFirst).addClass("qiandao");
//两者进行匹配。如果相等则给当前li添加Class,即显示li里面的Div层
}
}
} //生成当月的日历且含已签到
$(".date" + myDate.getDate()).addClass('able-qiandao');
//这个是用于给当前li添加“可以签到”属性,下面的代码是假如当前li具备这个属性且右上侧的按钮处于可以点击状态,则可以直接在日历上点击进行签到
$dateBox.on("click", "li", function() {
if ($(this).hasClass('able-qiandao') && _handle) {
$(this).addClass('qiandao');
qiandaoFun();
}
})
$qiandaoBnt.on("click", function() {
if (_handle) {
qiandaoFun();
}
}); //点击签到按钮进行签到
function qiandaoFun() {
$qiandaoBnt.addClass('actived');
openLayer("qiandao-active", qianDao);
_handle = false;
}//签到函数,签到完成之后按钮显示已经签到,并且调用弹窗函数
function qianDao() {
$(".date" + myDate.getDate()).addClass('qiandao');
}//在列表上显示已经签到的状态
}();
function openLayer(a, Fun) {
$('.' + a).fadeIn(Fun)
} //定义一个弹窗函数
var closeLayer = function() {
$("body").on("click", ".close-qiandao-layer", function() {
$(this).parents(".qiandao-layer").fadeOut()
})
}() //关闭弹窗按钮
$("#js-qiandao-history").on("click", function() {
openLayer("qiandao-history-layer", myFun);
function myFun() {
return
} //已经签到的天数,点击显示弹窗
})
})
以上就是这个demo的全部源代码,其实这个demo最让人头疼的并不是JS代码部分,而是CSS,控制那么多Class真的不是一件简单的事情。要写出优美的代码真的是任重道远,在此也感谢下Demo的原作者(虽然找不到名字了。。)!