又一個H5投票頁面實現之旅

又一個H5投票頁面實現之旅

最近又作了個投票的H5活動頁面,此次跟以前的有點不太同樣。根據需求要用戶關注了微信公衆號以後才能進行投票。這樣就不是簡單的數據邏輯與數據交互了,須要跟微信服務器通信拿到用戶信息。javascript

之前的實現方式

之前的這類活動是一種比較弱的先後端分離,前端寫頁面、效果、處理數據交互以及邏輯。這些東西放在靜態服務器上。後端處理數據存儲等。這樣就實現了一種簡單的先後分離,作起來效率相對也教快一些。css

如今的狀況

此次其實其餘的也沒有什麼變化,而後就是在投票頁面須要交給後端去跳轉微信服務器拿到用戶信息。對於這樣的場景個人想法是有兩種方式:html

1. 讓後端來渲染這個頁面,用後端模板來作。這樣在開發和調試方面耦合性就比較高。
2. 前端用vue寫好全部的邏輯,頁面打包到一個js中實現。這樣耦合性就不是那麼高了,各自專一本身的模塊,效率也會提高許多。

固然鑑於時間要求以及後端原本就擁有的一套基礎設施,選擇了第二種方案。不管在效率和工做量上都有必定的減輕。雖然本身以爲這麼作徹底是一種大材小用,可是知足需求才是王道。說幹就幹唄!
上代碼:前端

<template>
  <div>
    <div class="container">
      <div class="header"><img :src="header" class="img"></div>
      <div class="content">
        <div class="main-body">
          <div class="top-bar">{{title}}獎項</div>
          <div class="main-wrapper t-block">
            <div class="main-content">
              <div class="line-height"><span>&nbsp;</span></div>
              <div class="detail-tilte detail-btn"><p>2017中國自貿試驗區十大{{title}}</p></div>
              <div class="presents-box details">
                <div class="arrow-up">&nbsp;</div>
                <div class="article">
                  <h2></h2>
                  <p></p>
                  <div class="vote-result" id="vote-result">投票</div>
                  <div class="clearfix"></div>
                </div>
              </div>
              <div class="share-box">
                <a class="share-btn" id="share-btn" href="javascript:;">拉票</a>
                <a class="back-btn" id="result-btn" href="./corp/20180109zimaoqu_vote/news_result.html" style="background-color: #eca317;">查看票數</a>
                <a class="back-btn" id="back-btn" href="javascript:history.back(-1);" style="margin: 10px auto 0;width: 100%;">返回</a>
                <div class="clearfix"></div>
              </div>
              <div class="rule">
                <p>投票規則:</p>
                <p>一、每人天天能夠對每一個獎項最多投出10票,選項可重複投票。</p>
                <p>二、投票時間爲2018.1.15   15:00至2018.1.21  21:00。</p>
              </div>
              <div class="footer"><img :src="footer"></div>
            </div>

          </div>  
        </div>
      </div>
    </div>

    <div class="mock">
      <img :src="intro_detail">
      <div id="qrcode"></div>
      <p class="shareText">掃描二維碼,分享給朋友</p>
    </div>

    <!-- 加載 -->
    <div class="loading">
      <img :src="loading">
    </div>

    <!-- 公衆號關注 -->
    <div class="nbd-code">
      <div class="close"><img :src="close"></div>
      <img :src="gongzonghao">
    </div>
  </div>
</template>

<script>
import jquery from 'jquery'

export default {
  name: 'app',
  data() {
    return{
      header: './corp/20180109zimaoqu_vote/img/header_bg.png',
      footer: './corp/20180109zimaoqu_vote/img/footer.jpg',
      intro_detail: './corp/20180109zimaoqu_vote/img/intro_detail.png',
      loading: './corp/20180109zimaoqu_vote/img/loading.gif',
      close: './corp/20180109zimaoqu_vote/img/close.png',
      gongzonghao: './corp/20180109zimaoqu_vote/img/gongzonghao.png',
      params:{},
      type: {
        '11': '新聞',
        '12': '案例'
      },
      title: '新聞'
    }
  },
  mounted() {
    var $ = jquery;
    var that = this;
    var arr = (location.search.split('?')[1]).split('&');
    that.params = that.key_value(arr);
    that.title = that.type[that.params['reward_id']];
    var this_id = (that.params)['candidate_id'];
    var count = JSON.parse(localStorage.getItem('count'));

    //處理本地存儲
    var nowTime = new Date().getDate(),
        oldTime = JSON.parse(localStorage.getItem('time')),
        newArr = [];

    //iOS上
    oldTime = !!(navigator.userAgent).match(/\(i[^;]+;( U;)? CPU.+Mac OS X/) && (oldTime == 'null') ? null : oldTime;

    //固定時間間隔清除localStorage
    if(Math.abs(nowTime - oldTime) >= 1 || oldTime == null ) {
      localStorage.clear();
    }
    console.log(count)
    if(count == null) {
      var this_obj = {total: 0};
      this_obj[this_id] = 0;
      count = {};
      count[(that.params)['reward_id']] = this_obj;
      localStorage.setItem('time', JSON.stringify(nowTime));
    } else {
      var this_obj = count[(that.params)['reward_id']];
      if(this_obj == null) {
        this_obj = {total: 0};
        count[(that.params)['reward_id']] = this_obj;
      }
      this_obj[this_id] = this_obj[this_id] == undefined ? 0 :this_obj[this_id];
    }

    //是否爲0
    if(count[that.params['reward_id']][this_id] == undefined) {
      count[that.params['reward_id']][this_id] = 0;
    }

    var current = count[that.params['reward_id']][this_id] == 0 ||count[that.params['reward_id']][this_id] == undefined ?'投票':'已投'+count[that.params['reward_id']][this_id]+'票';

    $('#vote-result').text(current);

    if(that.params['reward_id'] == '11') {
      $('#back-btn').attr('href', './corp/20180109zimaoqu_vote/news.html');
      $('#result-btn').attr('href', './corp/20180109zimaoqu_vote/news_result.html');
    } else {
      $('#back-btn').attr('href', './corp/20180109zimaoqu_vote/case.html');
      $('#result-btn').attr('href', './corp/20180109zimaoqu_vote/case_result.html');
    }

    //判斷是否爲微信
    if($('.weichat').attr('tip') != '') {
      $('body').css('background-color', '#fff');
      $('body').html('<p style="text-align:center;">'+$('.weichat').attr('tip')+'</p>');
      return false;
    }
    
    $.ajax({
      type: 'get',
      url: './candidates/'+that.params['candidate_id']+'?tag=zimaoqu&reward_id='+that.params['reward_id'],
      success: function(res) {
        var html = '',
            data = res;

        $('.article h2').html(data.name);
        $('.article p').html(data.desc);
        //加載完成
        $('.loading').hide();
      }
    });

    //分享
    $('#share-btn').click(function() {
      $('body').scrollTop(0);
      $('.mock').show();
      $('.mock').css('height', $(document).height()+ 'px')
    });

    $('.mock').click(function() {
      $(this).hide();
    });

    //判斷是否關注
    $('.close').click(function() {
      $('.nbd-code').hide();
    });

    $('#vote-result').click(function() {
      if($('.subscribe').attr('flag') == 'true') {
        $('body').scrollTop(0);
        $('.nbd-code').show();
      } else {
        //投票判斷
        if(count[that.params['reward_id']]['total'] >= 10) {
          alert('您已不能再投。');
          return false;
        }
        count[that.params['reward_id']][this_id] += 1;
        count[that.params['reward_id']]['total'] += 1;
        current = count[that.params['reward_id']][this_id] == 0?'投票':'已投'+count[that.params['reward_id']][this_id]+'票';
        $('#vote-result').text(current);
        localStorage.setItem('count', JSON.stringify(count));

        //請求
        $.ajax({
          url: './votes?candidate_id='+that.params['candidate_id']+'&reward_id='+that.params['reward_id'],
          type: 'post',
          success: function() {
            console.log('投票成功')
          }
        });
      }
    })
  },
  methods: {
    key_value(arr) {
      //arr = ["candidate_id=304", "reward_id=11"];
      var obj = {};

      for(var i in arr) {
        let key = arr[i].split('=')[0];
        let value = arr[i].split('=')[1];
        obj[key] = value;
      }

      return obj;
    }
  }
}
</script>

這裏有幾點說明就是1.依然使用了jQuery,由於時間以及原來有這樣的邏輯代碼。最主要的是懶吧2.判斷是否在微信中進入這個頁面,是後臺返回一個值我去讀取而後操做vue

//判斷是否爲微信
  if($('.weichat').attr('tip') != '') {
    $('body').css('background-color', '#fff');
    $('body').html('<p style="text-align:center;">'+$('.weichat').attr('tip')+'</p>');
    return false;
  }

而後這裏有一個坑,由於出於移動端的網絡考慮。因此把存儲的問題放在前端存儲,讓用戶有個交互的感。在對null處理是,iOS和Android上的值還不同,iOS上是字符串,這個坑也是調了很久才發現。java

//iOS上
 oldTime = !!(navigator.userAgent).match(/\(i[^;]+;( U;)? CPU.+Mac OS X/) && (oldTime == 'null') ? null : oldTime;

結果以下圖
jquery

最終出來的結果雖然知足了需求,可是本身仍是以爲槽點不少。歡迎各位來噴O(∩_∩)O哈哈~ajax

相關文章
相關標籤/搜索