WeChat applet-global countdown + global pop-up prompt

Description of Requirement

1. Click the [Start] button on the timing page to start the countdown, and the timing will continue when you exit the page.
2. After the timing is over, a prompt will pop up (no matter which page you are currently in)

final effect

insert image description here
insert image description here

the code

1. Global definition
1. app.json: add the following

 "usingComponents": {
    
    "dialog":"/components/dialog/dialog"}

2. app.wxss: dialog.wxss needs to be imported, otherwise the custom pop-up window style will fail

@import "components/dialog/dislog.wxss";

3. app.js: implement countdown + set variable listener

App({
    
    
  globalData:{
    
    
    //倒计时相关的全局变量
    hour: 1,
    firstMinute: 0,
    lastMinute: 0,
    firstSecond: 0,
    lastSecond: 0,
    timer:null,
    isstart_flag: false, 
  },
   isShow:false,
    /**
     * 设置globalData中变量的监听器
     */
    setWatcher(watch) {
    
    
      let obj = this.globalData;
      Object.keys(obj).forEach(v => {
    
    
          this.observe(obj,v,watch); 
      })
  },
  /**
     * 设置isShow变量的监听器
     */
    setWatcher1(watch) {
    
    
      var val = this.isShow; // 给该属性设默认值
      Object.defineProperty(this, "isShow", {
    
    
          configurable: true,
          enumerable: true,
          set: function(value) {
    
    
              val = value;
              watch(val); // 赋值(set)时,调用对应函数
          },
          get: function() {
    
    
              return val;
          }
      })
  },
  /**
   * 监听属性 并执行监听函数
   */
   observe(obj, key,watchFun) {
    
    
     var val = obj[key]; // 给该属性设默认值
     Object.defineProperty(obj, key, {
    
    
         configurable: true,
         enumerable: true,
         set: function(value) {
    
    
             val = value;
             watchFun(key,val); // 赋值(set)时,调用对应函数
         },
         get: function() {
    
    
             return val;
         }
     })
    },
    //倒计时-具体实现由其他同事编写
    countDown() {
    
    
      var obj = this.globalData;
      var self = this;
      clearInterval(obj.timer)
      var h = 0;
      var m = 59,
      var s = 60;
      var timer = setInterval(function () {
    
    
        --s;
        if (s < 0) {
    
    
          --m;
          s = 59;
        }
        if (m < 0) {
    
    
          --h;
          m = 59
        }
        if (h < 0) {
    
    
          s = 0;
          m = 0;
        }
        if (h == 0 && m == 0 && s == 0) {
    
    
          self.isShow = true;
          clearInterval(obj.timer);
        }
        function checkTime(i) {
    
    
          if (i < 10) {
    
    
            i = '0' + i
          }
          return i;
        }
        s = checkTime(s);
        let n = checkTime(m)
        if (n.length >= 2) {
    
    
          m = n.slice(-2);
        }
        let strMinute = m.toString();
        let splMinute = strMinute.split("");
        let firstMinute = splMinute[0];
        let lastMinute = splMinute[1];
  
        let strSecond = s.toString();
        let splSecond = strSecond.split("");
        let firstSecond = splSecond[0];
        let lastSecond = splSecond[1];

        obj.hour = h;
        obj.firstMinute = firstMinute;
        obj.lastMinute = lastMinute;
        obj.firstSecond = firstSecond;
        obj.lastSecond = lastSecond;
      }, 1000);
      obj.timer = timer;
    },
})

2. Assembling pop-up window components

Note: Try not to repeat the class name with other pages

1、dialog.wxml

<view class='wx_dialog_container' hidden="{
   
   {!isShow}}">
    <view class='wx-mask'></view>
    <view class="alert1">
        <view class="white1">
            <view class="title1">提示</view>
            <view class="text2">计时结束</view>
            <view class="btn1" bindtap="_confirmEvent">我知道了</view>
        </view>
    </view>
</view>

2、dialog.wxss

.wx-mask{
position: fixed;
z-index: 9998;
top: 0;
right: 0;
left: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.3);
}
.wx-dialog{
position: fixed;
z-index: 9999;
width: 80%;
max-width: 600rpx;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
background-color: #FFFFFF;
text-align: center;
border-radius: 3px;
overflow: hidden;
}
.wx-dialog-title{
font-size: 18px;
padding: 15px 15px 5px;
}
.wx-dialog-content{
padding: 15px 15px 5px;
min-height: 40px;
font-size: 16px;
line-height: 1.3;
word-wrap: break-word;
word-break: break-all;
color: #999999;
}
.wx-dialog-footer{
display: flex;
align-items: center;
position: relative;
line-height: 45px;
font-size: 17px;
}
.wx-dialog-footer::before{
content: '';
position: absolute;
left: 0;
top: 0;
right: 0;
height: 1px;
border-top: 1px solid #D5D5D6;
color: #D5D5D6;
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
}
.wx-dialog-btn{
display: block;
-webkit-flex: 1;
flex: 1;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
position: relative;
}
.wx-dialog-footer .wx-dialog-btn:nth-of-type(1){
color: #353535;
}
.wx-dialog-footer .wx-dialog-btn:nth-of-type(2){
color: #3CC51F;
}
.wx-dialog-footer .wx-dialog-btn:nth-of-type(2):after{
content: " ";
position: absolute;
left: 0;
top: 0;
width: 1px;
bottom: 0;
border-left: 1px solid #D5D5D6;
color: #D5D5D6;
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
-webkit-transform: scaleX(0.5);
transform: scaleX(0.5);
}
.alert1{
  width:100%;
  height:100%;
  background:rgba(41,36,33,0.5);
  position:fixed;
  top:0;
  left:0;
  z-index:99999;
  display:flex;
  justify-content:center;
  align-items:center;
}
.white1{
  width:608rpx;
  height:362rpx;
  background-color:#fff;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:space-between;
  font-size:28rpx;
  border-radius:20rpx;
  padding:5% 3%;
}
.white1 .title1{
  font-size: 40rpx;
}
.white1 .text2{
  font-size: 30rpx;
  color: #a1a3a6;
  margin-bottom: 60rpx;
}
.btn1{
  width: 100%;
  height: 60rpx;
  border-top: 2rpx solid #eee;
  text-align: center;
  line-height: 60rpx;
  color: #45b97c;
  font-size: 30rpx;
}

3、dialog.json

{
    
    
  "component": true,       
  "usingComponents": {
    
    }     
}

4、dialog.js

const app = getApp();
Component({
    
    
  options: {
    
    
    multipleSlots: true, // 在组件定义时的选项中启用多slot支持
    addGlobalClass: true
  },
  /**
   * 组件的属性列表
   * 用于组件自定义设置
   */
  properties: {
    
    
  },

  /**
   * 私有数据,组件的初始数据
   * 可用于模版渲染
   */
  data: {
    
    
    // 弹窗显示控制
    isShow:false
  },

  lifetimes:{
    
    
    attached: function () {
    
    
      const self = this;
      self.setData({
    
    
        isShow: app.isShow,
      })
      
    },
  },

  pageLifetimes:{
    
    
    show(){
    
    
      const self = this;
      app.setWatcher1(self.watchBack2.bind(self))
    }
  },

  /**
   * 组件的方法列表
   * 更新属性和数据的方法与更新页面数据的方法类似
   */
  methods: {
    
    
    watchBack2(value){
    
    
      this.setData({
    
    
        isShow:value,
      })
    },
     /*
     * 内部私有方法建议以下划线开头
     * triggerEvent 用于触发事件
     */
    _confirmEvent(){
    
    
      app.isShow = false;
      this.setData({
    
    
        isShow: false
      })
    }
  }
})

3. Realization of the countdown page

1、startCountDown.wxml

<view class="Container">
    <view class="nz_container">
        <view class="time">
            <view class="time_item">{
   
   {hour}}</view>
            <view class="time_items">:</view>
            <view class="time_item">{
   
   {firstMinute}}</view>
            <view class="time_item">{
   
   {lastMinute}}</view>
            <view class="time_items">:</view>
            <view class="time_item">{
   
   {firstSecond}}</view>
            <view class="time_item">{
   
   {lastSecond}}</view>
        </view>
    </view>
    <view class="start_btn" wx:if="{
   
   {isstart_flag}}" bindtap="reSet">重置</view>
    <view class="start_btn" wx:else bindtap="startCountDown">开始</view>
    <!-- 弹窗 -->
    <view class="dialog"> 
      <dialog id='dialog'>
      </dialog>
    </view>
</view>

2、startCountDown.wxss

page{
    width:100%;
    height:100%;
    background-color:#eee;
    overflow:hidden;
}
.nz_container{
    width:100%;
    height:394rpx;
    background: #FFFFFF;
    border-radius: 6rpx;
    margin-top:1.2%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}
.time{
    width:422rpx;
    height:88rpx;
}
.time_item{
    width: 70rpx;
    height: 88rpx;
    background: #F0FAF8;
    border: 2rpx solid #149C89;
    border-radius: 6rpx;
    font-family: PingFangSC-Medium;
    font-size: 56rpx;
    color: #333333;
    letter-spacing: 3.5rpx;
    text-align: center;
    font-weight: 500;
    margin-left:2%;
    margin-right:2%;
}
.time_items{
    font-size:60rpx;
}
.changetime_btn{
    width:422rpx;
    height:68rpx;
    border: 1px solid #149C89;
    border-radius: 34rpx;
    margin-top: 5%;
    display: flex;
    justify-content: center;
    align-items: center;
}
.changetime_btn image{
    width:32rpx;
    height:28rpx;
}
.start_btn{
    width: 690rpx;
    height: 104rpx;
    background: #149C89;
    border-radius: 55rpx;
    text-align: center;
    line-height: 104rpx;
    font-family: PingFangSC-Semibold;
    font-size: 40rpx;
    color: #FFFFFF;
    letter-spacing: 0;
    font-weight: 600;
    margin: 6% auto;
}
.dialog{
  position: fixed;
  top:40%;
  left: 40%;
  z-index: 9999;
}

3、startCountDown.js

var app = getApp();
Page({
    
    
  data: {
    
    
    hour: 1,
    firstMinute: 0,
    lastMinute: 0,
    firstSecond: 0,
    lastSecond: 0,
    timer:null,
    isstart_flag: false,
  },

  /**
     * 生命周期函数--监听页面加载
     */
    onLoad: function (options) {
    
    
      const that = this;
        //设置全局变量监听器
        app.setWatcher(this.watchBack);
        that.setData({
    
    
          hour: app.globalData.hour,
          firstMinute: app.globalData.firstMinute,
          lastMinute: app.globalData.lastMinute,
          firstSecond: app.globalData.firstSecond,
          lastSecond: app.globalData.lastSecond,
          timer: app.globalData.timer,
          isstart_flag:app.globalData.isstart_flag,
        })
    },
    watchBack(variable,value){
    
    
      const that = this;
      that.setData({
    
    
        [variable]:value,
      })
    },

  //开始倒计时
  startCountDown() {
    
    
    app.globalData.isstart_flag = true;
    app.countDown();
  },
  //重置倒计时
  reSet() {
    
    
    const that = this;
    clearInterval(app.globalData.timer);
    app.globalData.hour = 1;
    app.globalData.firstMinute = 0;
    app.globalData.lastMinute = 0;
    app.globalData.firstSecond = 0;
    app.globalData.lastSecond = 0;
    app.globalData.isstart_flag = false;
  },
  onUnload() {
    
    
    const that = this;
    // clearInterval(app.globalData.timer);
  }
})

4. Pop-up prompts can pop up on every page

No easier way has been found yet. . .

1. Add to the wxml of each page

<view class="dialog"> 
      <dialog id='dialog'>
      </dialog>
    </view>

2. Add to the wxss of each page:

.dialog{
  position: fixed;
  top:40%;
  left: 40%;
  z-index: 9999;
}

Guess you like

Origin blog.csdn.net/qq_42622871/article/details/127283194