手记

用jquery动手学做一个签到页面

这次我们来实现一个活动的签到页面以及相关的交互效果,具体实现后的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的原作者(虽然找不到名字了。。)!

20人推荐
随时随地看视频
慕课网APP