1. 程式人生 > >微信小程式scroll-view(滾動元件)與onPullDownRefresh(下拉重新整理)

微信小程式scroll-view(滾動元件)與onPullDownRefresh(下拉重新整理)

一.官方api描述  在滾動 scroll-view 時會阻止頁面回彈,所以在 scroll-view 中滾動,是無法觸發 onPullDownRefresh

 查閱大量資料以後發現一共有三種方式:

1.使用view代替scroll-view,從而觸發onPullDownRefresh

2.在scroll-view標籤上新建一個隱藏的view標籤,使用scroll-view標籤中bindscrolltoupper(滾動到頂部/左邊,會觸發事件)顯示view標籤,做動畫模擬上拉重新整理

3.scroll-view標籤下新增一個view標籤能與onPullDownRefresh結合使用(我猜用的這種)

二.方法程式碼如下:
wxml:

<scroll-view scroll-y="true" bindscrolltoupper="upper" bindscrolltolower="lower" scroll-with-animation="true" scroll-into-view="{{scrollTopTX}}" class = "ball" ><!---改 llp-----> <view class='{{dropDown?"list":""}}' > <view style='width:100%;height:100%' bindtouchmove='{{dropDown?"downTouchmove":""}}'
>   <!-- 每一行 -->   <view class="row" wx:for="{{allContentList}}" wx:key="key" id="row{{index+1}}">     <!-- 日期 -->     <view class="datetime" wx:if="{{item.create_time != ''}}">{{item.times}}</view>     <!-- 頭像與內容文字 -->     <view class="body" style="flex-flow: {{item.myself == 0 ? 'row' : 'row-reverse'}}">       <view class="avatar-container">         <image class="avatar" v:if="" src="{{item.head_img_url}}" />       </view>         <!-- 畫三角箭頭 -->       <view class="triangle" wx:if="{{item.msg_type != 'image'}}" style="{{item.myself == 1 ? 'right: 140rpx; background: #7ECB4B' : 'left: 140rpx;'}}"></view>       <view class="content" style="{{item.myself == 1 ? 'background: #7ECB4B' : ''}};{{item.msg_type == 'image' ? 'background: none' : ''}}">         <image class="picture" wx:if="{{item.msg_type == 'image'}}" src="{{item.msg}}" mode="widthFix" bindtap="preview" data-src="{{item.msg}}" />         <view wx:else="{{item.msg_type == 'text'}}">{{item.msg}}</view>       </view>     </view>   </view> </view> </view> </scroll-view>

wxss:

@import "../../modules/chat-input/chat-input.wxss"; /** 聊天視窗樣式 * 54px為回覆框高度,js同 */ page{ height: 100%; } /*載入*/ .list { overflow:auto; margin:auto; position:absolute; top:0; bottom:0; left:0; right:0; }
/*聊天記錄*/ .ball{ width : 100%; height: 92%; margin-bottom: 100rpx; white-space:nowrap; } /*單元行*/ .row { display: flex; flex-direction: column; margin: 0 30rpx; }
/*日期*/ .datetime {   font-size: 10px;   padding: 10px 0;   color: #999;   text-align: center; }
/*主體*/ .body {   display: flex;   flex-direction: row;   align-items: flex-start;   justify-content: flex-start;   width: 100%;   margin-top: 10px; }

/*頭像容器*/ .body.avatar-container {   width: 20%; }
/*頭像*/ .body .avatar {   width: 80rpx;   height: 80rpx; background:#fff;   border-radius: 50%;   margin: 0 20rpx; }
/*文字訊息*/ .body .content {   font-size: 30rpx;   background: #fff;   border-radius: 20rpx;   padding:0 24rpx;   line-height: 80rpx;   margin-bottom: 10px; }
/* 三角箭頭 */ .body .triangle {   background: white;   width: 20rpx;   height: 20rpx;   margin-top: 26rpx;   transform: rotate(45deg);   position: absolute; }
/*圖片訊息*/ .picture {   width: 160px; }
/*回覆框*/ .reply {   display: flex;   flex-direction: row;   justify-content: flex-start;   align-items: center;   position: fixed;   bottom: 0;   width: 100%;   height: 54px;   border-top: 1px solid rgb(215, 215, 215);   background: rgb(245, 245, 245); }
.reply .voice-image {   width: 25px;   height: 25px;   margin-left: 3%; }
/*文字輸入或語音錄入*/ .reply .opration-area {   flex: 1;   padding: 8px; }
/*回覆文字框*/ .reply input {   background: rgb(252, 252, 252);   height: 36px;   border: 1px solid rgb(221, 221, 221);   border-radius: 6px;   padding-left: 3px; }
/*選取圖片*/ .reply .choose-image {   width: 25px;   height: 25px;   margin-right: 3%; }
/*按住說話button*/ .voice-button {   height: 36px;   color: #818181;   font-size: 14px;   line-height: 36px; }
/*懸浮提示框*/ .hud-container {   position: fixed;   width: 150px;   height: 150px;   left: 50%;   top: 50%;   margin-left: -75px;   margin-top: -75px; }
/*背景層*/ .hud-background {   position: absolute;   width: 100%;   height: 100%;   background: #999;   opacity: .8;   z-index: 11;   border-radius: 10px; }
/*懸浮框主體*/ .hud-body {   position: relative;   width: 100%;   height: 100%;   z-index: 19;   display: flex;   flex-direction: column;   justify-content: space-between;   align-items: center; }
/*圖示*/ .hud-body image {   margin-top: 20px;   width: 80px;   height: 80px; }
/*文字*/ .hud-body .tip {   color: #fff;   text-align: center;   width: 90%;   line-height: 34px;   margin: 0 auto;   margin-bottom: 10px;   width: 90%; }
.hud-body .warning {   background: #cc3333;   border-radius: 5px; } ::-webkit-scrollbar{/*隱藏滾動條*/ width: 0; height: 0; color: transparent; }   js: // chat.js // var app = getApp(); var user_id = user_id var sender_id = sender_id var socketOpen = false; var frameBuffer_Data, session, SocketTask; var url = 'ws://www.yzhm8.com:8080'; import Toast from "../../utils/toast"; let chatInput = require('../../modules/chat-input/chat-input'); let utils = require('../../utils/util'); /** * 聊天輸入元件展示頁面 */ Page({
/** * 頁面的初始資料 */ data: { lastX: 0, //滑動開始x軸位置 lastY: 0, //滑動開始y軸位置 text: "沒有滑動", currentGesture: 0, //標識手勢 textMessage: '', allContentList: [], chatItems: [], scroll_height: wx.getSystemInfoSync().windowHeight - 54, page_index: 0, mode: true, cancel: false, status: 0, toView: '', msg: '', receiver_ids: '', sender_ids: '', scrollTopTX: 'a4',//滾動位置 dropDown:true,//切換滾動與重新整理 dropDown_id:false//只允許重新整理一次 }, //滑動移動事件 handletouchmove: function (event) { var currentX = event.touches[0].pageX var currentY = event.touches[0].pageY var tx = currentX - this.data.lastX var ty = currentY - this.data.lastY var text = "" //左右方向滑動 if (Math.abs(tx) > Math.abs(ty)) { if (tx < 0) text = "向左滑動" else if (tx > 0) text = "向右滑動" } //上下方向滑動 else { if (ty < 0) text = "向上滑動" else if (ty > 0) text = "向下滑動" }
//將當前座標進行儲存以進行下一次計算 this.data.lastX = currentX this.data.lastY = currentY this.setData({ text: text, }); },
//滑動開始事件 handletouchtart: function (event) { this.data.lastX = event.touches[0].pageX this.data.lastY = event.touches[0].pageY }, //滑動結束事件 handletouchend: function (event) { this.data.currentGesture = 0; this.setData({ text: "沒有滑動", }); }, Refresh: function () { var arr = res.data; for (var i = 0; i < arr.length; i++) { console.log(arr[i].content) arr[i].content = i } this.Refresh() }, /** * 生命週期函式--監聽頁面載入 */ onLoad(options) { var that = this; var read_id = options.user_id var read_id = options.user_id;
if (options.user_id == undefined) { wx.redirectTo({ url: '/pages/Login/login', }) return; } console.log(195, options) that.setData({ // avatar:options.avatar_url,/*改 llp*/ // sender_id: sender_id, user_id: wx.getStorageSync('user_id'), avatar_url: wx.getStorageSync('avatar'), receiver_ids: read_id.split(",")[0], sender_ids: read_id.split(",")[1] }) wx.getStorage({///////////////////////////////////////取////////////////////////////////////// key: 'key01', success(res) { console.log(207, res) var arr = []; for (var i = 0; i < res.data.length; i++) { var myself = ''; if (res.data[i].sender_id == that.data.user_id) { myself = 1; } else { myself = 0; } var itile = { myself: myself, head_img_url: that.data.avatar_url, msg: res.data[i].content, msg_type: 'text', myid: res.data[i].receiver_id, uid: res.data[i].sender_id, } arr.push(itile) } console.log('arr', arr) that.setData({ allContentList: arr, dropDown: false, }) setTimeout(function () {/*改 llp*/ console.log('1111111111111111', arr.length) that.setData({ scrollTopTX: 'row' + arr.length }) }, 100) }, }) // wx.request({ // url: 'https://ztmp.jjyg8.com/api/InstantMessaging/query_chat', // data:{ // sender_id:sender_id, // receiver_id:user_id, // type:2 // }, // success: function (Tenarticle) { // console.log(Tenarticle,"Tenarticle") // wx.setStorage({ // key: 'Tenarticle', // data: Tenarticle.data // }) // } // }) this.initData(); // wx.getStorage({ // key: 'Tenarticle', // success(Tenarticle) { // for(var t=0;t<Tenarticle.data.length;t++){ // that.data.allContentList.unshift({ // msg: Tenarticle.data[t].content, // uid: Tenarticle.data[t].sender_id, // myid: Tenarticle.data[t].receiver_id, // states: Tenarticle.data[t].states, // times:Tenarticle.data[t].times, // msg_type:"text", // head_img_url: that.data.avatar_url&&that.data.avatar, // myself:1&&0 // }) // }
// } // })
},
// 頁面載入完成 onReady: function () { var that = this; var that_data = that.data var user_id = user_id SocketTask.onOpen(res => { socketOpen = true; console.log('監聽 WebSocket 連線開啟事件。', res) }) SocketTask.onClose(onClose => { console.log('監聽 WebSocket 連線關閉事件。', onClose) // socketOpen = false; this.webSocket() }) SocketTask.onError(onError => { console.log('監聽 WebSocket 錯誤。錯誤資訊', onError) socketOpen = false }) wx.onSocketMessage(onMessage => { console.log('監聽WebSocket接受到伺服器的訊息事件。伺服器返回的訊息', onMessage) var onMessage_data = onMessage.data var s = onMessage_data.substr(0, 1) var onMessage_s = onMessage_data.substr(2) if (s == 0) { wx.request({ url: 'https://ztmp.jjyg8.com/api/InstantMessaging/bind', header: { 'content-type': 'application/x-www-form-urlencoded' },
data: { uid: that.data.user_id, client_id: onMessage_s }, method: "POST", })
} else { that.data.allContentList.push({ myself: 0, head_img_url: that.data.avatar, msg_type: 'text', msg: this.data.onMessage.content, myid: that_data.user_id, uid: that_data.sender_ids,/*改 llp*/ }); that.setData({ allContentList: that.data.allContentList, dropDown: false, }) setTimeout(function () {/*改 llp*/ console.log('1111111111111111') that.setData({ scrollTopTX: 'row' + that.data.allContentList.length }) }, 100) that.scrollToBottom(); console.log(that.data.allContentList) }
// if (onMessage_data.cmd == 1) { // that.setData({ // link_list: text // }) // console.log(text, text instanceof Array)
// if (text instanceof Array) { // for (var i = 0; i < text.length; i++) { // text[i] // } // } else {
// }
// } }) }, onShow: function (e) { if (!socketOpen) { this.webSocket() } }, webSocket: function () { // 建立Socket SocketTask = wx.connectSocket({ url: url, data: 'data', header: { 'content-type': 'application/json' }, method: 'post', success: function (res) { console.log('WebSocket連線建立', res) }, fail: function (err) { wx.showToast({ title: '網路異常!', }) console.log(err) }, }) }, initData() { let that = this; let systemInfo = wx.getSystemInfoSync(); chatInput.init(this, { systemInfo: systemInfo, minVoiceTime: 1, maxVoiceTime: 60, startTimeDown: 56, format: 'mp3', //aac/mp3 sendButtonBgColor: 'mediumseagreen', sendButtonTextColor: 'white', extraArr: [{ picName: 'choose_picture', description: '照片' }, { picName: 'take_photos', description: '拍攝' }], // tabbarHeigth: 48 });
that.setData({ pageHeight: systemInfo.windowHeight, }); wx.setNavigationBarTitle({ title: '好友' }); that.textButton(); that.extraButton(); // that.voiceButton(); }, textButton() { var that = this; var that_data = that.data console.log(that) console.log(that_data) //console.log(user_id) chatInput.setTextMessageListener(function (e) { let msg = e.detail.value; if (msg == '') { wx.showToast({ title: '總要寫點什麼吧' }); return; }
var message = { myself: 1, head_img_url: that.data.avatar_url, msg_type: 'text', msg: msg, myid: that_data.user_id, uid: that_data.sender_id, } console.log(that.data) if (socketOpen) { that.data.allContentList.push(message); that.setData({ dropDown: false, }) setTimeout(function () {/*改 llp*/ console.log('1111111111111111') that.setData({ scrollTopTX: 'row' + that.data.allContentList.length }) }, 100) sendSocketMessage( wx.request({ url: 'https://ztmp.jjyg8.com/api/InstantMessaging/send',
data: { uid: message.uid, sendname: 10101, img: '11111', content: msg, sendid: message.myid }, success: function (res) { console.log(res.data) that.setData({ items: res.data }) }, }),

// msg: msg, // // myid: 100, // uid: 100, ) if (that.row == 1) { wx.request({ url: 'https://ztmp.jjyg8.com/api/InstantMessaging/Message_warehousing', data: { receiver_id: message.uid, sender_id: message.myid, content: message.msg, states: 2, } }) } // wx.sendSocketMessage({ // data: message, // }) that.setData({ allContentList: that.data.allContentList, dropDown: false, msg: '' // 清空輸入框文字 }) setTimeout(function () {/*改 llp*/ console.log('1111111111111111') that.setData({ scrollTopTX: 'row' + that.data.allContentList.length }) }, 100) that.scrollToBottom(); } }) }, extraButton() { let that = this; chatInput.clickExtraListener(function (e) { console.log(e); let itemIndex = parseInt(e.currentTarget.dataset.index); // if (itemIndex === 2) { // that.myFun(); // return; // } wx.chooseImage({ count: 1, // 預設9 sizeType: ['compressed'], sourceType: itemIndex === 0 ? ['album'] : ['camera'], success: function (res) { let tempFilePath = res.tempFilePaths[0]; wx.uploadFile({ url: 'https://oss.jjyg8.com', filePath: tempFilePaths[0], name: 'file', formData: { name: tempFilePaths[0], key: "img/${filename}", policy: "eyJleHBpcmF0aW9uIjoiMjAyMC0wMS0wMVQxMjowMDowMC4wMDBaIiwiY29uZGl0aW9ucyI6W1siY29udGVudC1sZW5ndGgtcmFuZ2UiLDAsMTA0ODU3NjAwMF1dfQ==", OSSAccessKeyId: "LTAIn3MQVumdpEws", success_action_status: "200", signature: "6NqEga8RuDFjBox9jMfCel1GjZE=", }, success: function (res) { console.log(res) that.setData({ img: tempFilePaths[0].replace("http://tmp", "https://oss.jjyg8.com/img") }) }, fail: function ({ errMsg }) { console.log('upladImage fail, errMsg is: ', errMsg) wx.showToast({ title: "上傳失敗", duration: 1000 }) }, })
var message = { myself: 1, head_img_url: that.data.avatar_url, msg_type: 'image', msg: tempFilePath, myid: that.data.user_id,/*改 llp*/ uid: that.data.sender_ids, create_time: utils.formatTime(new Date()) } that.data.allContentList.push(message); that.setData({ 'inputObj.extraObj.chatInputShowExtra': false }); sendSocketMessage(message) that.setData({ allContentList: that.data.allContentList, dropDown: false, msg: '' // 清空輸入框文字 }) setTimeout(function () {/*改 llp*/ console.log('1111111111111111') that.setData({ scrollTopTX: 'row' + that.data.allContentList.length }) }, 100) that.scrollToBottom(); } }); });
chatInput.setExtraButtonClickListener(function (dismiss) {
console.log('Extra彈窗是否消失', dismiss); }) },
resetInputStatus() { chatInput.closeExtraView(); }, scrollToBottom: function () { this.setData({ toView: 'row_' + (this.data.allContentList.length - 1) }); console.log(this.data) }, // // 下拉重新整理 onPullDownRefresh: function () { console.log(488,'下拉') // // 顯示頂部重新整理圖示 wx.showNavigationBarLoading(); var that = this; if (!that.data.dropDown_id){ wx.request({ url: 'https://ztmp.jjyg8.com/api/InstantMessaging/query_chat', data: { receiver_id: that.data.sender_ids,/*改 llp*/ sender_id: that.data.user_id, type: 3 }, success: function (browsed) { var arr = []; var myself = ';' for (var i = 0; i < browsed.data.length; i++) { if (browsed.data[i].sender_id == that.data.user_id) { myself = 1 } else { myself = 0 } var itile = { myself: myself, head_img_url: that.data.avatar_url, msg: browsed.data[i].content, msg_type: 'text', myid: browsed.data[i].receiver_id, uid: browsed.data[i].sender_id, } arr.push(itile) } for (var i = 0; i < that.data.allContentList.length; i++) { arr.push(that.data.allContentList[i]) } that.setData({ allContentList: arr, dropDown_id:true,/*改 llp*/ dropDown: false, }) // setTimeout(function () {/*改 llp*/ // console.log('1111111111111111') // that.setData({ // scrollTopTX: 'row' + arr.length // }) // }, 100) // 隱藏導航欄載入框 wx.hideNavigationBarLoading(); // 停止下拉動作 wx.stopPullDownRefresh(); } }) }else{ this.setData({ dropDown: false, }) // 隱藏導航欄載入框 wx.hideNavigationBarLoading(); // 停止下拉動作 wx.stopPullDownRefresh(); wx.showToast({ title: '已查詢所有記錄', icon: 'success', duration: 2000 }) } }, upper(){//滾動到頂部 console.log('滾動到頂部') this.setData({ dropDown: true, }) }, lower(){//滾動到底部 console.log('1212312312313') this.setData({ scrollTopTX: 'row' + this.data.allContentList.length }) }, downTouchmove(){ this.setData({ dropDown: false, }) } }); //通過 WebSocket 連線傳送資料,需要先 wx.connectSocket,並在 wx.onSocketOpen 回撥之後才能傳送。 function sendSocketMessage(msg) { var that = this; SocketTask.send({ data: JSON.stringify(msg) }, function (res) { console.log('已傳送', res) }) }