微信小程序聊天功能的示例代碼
更新時(shí)間:2020年01月13日 14:19:31 作者:lulu
這篇文章主要介紹了微信小程序聊天功能的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
效果

初始化滾動(dòng)條高度
var keyHeight = 0;
數(shù)據(jù)格式
const CHAT_DATA=[
{
type:0,//0客服1用戶
content:'歡迎歡迎歡迎歡迎歡迎歡迎歡迎歡迎歡迎歡迎歡迎歡迎歡迎歡迎歡迎歡迎歡迎歡迎歡迎歡迎歡迎歡迎歡迎歡迎歡迎歡迎歡迎歡迎',
headImg:'../../assets/common/images/headHortrait.jpeg',//頭像
creatTime:'2019-01-01',//創(chuàng)建時(shí)間
contentType:'text'
}, {
type: 0,//0客服1用戶
content: '1111111',
headImg: '../../assets/common/images/headHortrait.jpeg',//頭像
creatTime: '2019-01-01',//創(chuàng)建時(shí)間
contentType: 'text'
}, {
type: 1,//0客服1用戶
content: '222222',
headImg: '../../assets/common/images/headHortrait.jpeg',//頭像
creatTime: '2019-01-01',//創(chuàng)建時(shí)間
contentType: 'text'
}, {
type: 0,//0客服1用戶
content: '333333',
headImg: '../../assets/common/images/headHortrait.jpeg',//頭像
creatTime: '2019-01-01',//創(chuàng)建時(shí)間
contentType: 'text'
}, {
type: 1,//0客服1用戶
content: '4444444',
headImg: '../../assets/common/images/headHortrait.jpeg',//頭像
creatTime: '2019-01-01',//創(chuàng)建時(shí)間
contentType: 'text',
}, {
type: 0,//0客服1用戶
content: 'http://tmp/wxc79c66d8b0ed19a8.o6zAJs6QE8L8FKq645ts4e3LoKzI.pGakaVHKmbQ3160aa57e2bf33cb576fbabf691cd890b.durationTime=3706.aac',
headImg: '../../assets/common/images/headHortrait.jpeg',//頭像
creatTime: '2019-01-01',//創(chuàng)建時(shí)間
contentType: 'voice',
duration: '3706',
},{
type: 1,//0客服1用戶
content: 'http://tmp/wxc79c66d8b0ed19a8.o6zAJs6QE8L8FKq645ts4e3LoKzI.pGakaVHKmbQ3160aa57e2bf33cb576fbabf691cd890b.durationTime=3706.aac',
headImg: '../../assets/common/images/headHortrait.jpeg',//頭像
creatTime: '2019-01-01',//創(chuàng)建時(shí)間
contentType: 'voice',
duration:'3706'
},
{
type: 1,//0客服1用戶
content: 'https://img.yzcdn.cn/vant/cat.jpeg',
headImg: '../../assets/common/images/headHortrait.jpeg',//頭像
creatTime: '2019-01-01',//創(chuàng)建時(shí)間
contentType: 'img'
}, {
type: 1,//0客服1用戶
content: 'https://img.yzcdn.cn/vant/cat.jpeg',
headImg: '../../assets/common/images/headHortrait.jpeg',//頭像
creatTime: '2019-01-01',//創(chuàng)建時(shí)間
contentType: 'img'
}
];
wxml對(duì)話框
<block wx:key wx:for='{{chatData}}' wx:for-index="index">
<!-- 單個(gè)消息1 客服發(fā)出(左) -->
<view wx:if='{{item.type==0}}' id='msg-{{index}}' class="contentLeft" style=''>
<view class="head">
<image class="headImg" src='{{item.headImg}}' mode='widthFix'></image>
</view>
<view class='leftMsg' wx:if="{{item.contentType==='text'}}">{{item.content}}</view>
<view class='leftMsg' wx:if="{{item.contentType==='voice'}}" data-duration="{{item.content}}">{{item.duration}}s</view>
<view class='leftMsg img' wx:if="{{item.contentType==='img'}}"><image src="{{item.content}}" data-src="{{item.content}}" mode='widthFix' bindtap="onPreview"/></view>
</view>
<!-- 單個(gè)消息2 用戶發(fā)出(右) -->
<view wx:else id='msg-{{index}}' class="contentRight">
<view class='rightMsg' wx:if="{{item.contentType==='voice'}}" data-duration="{{item.duration}}" bindtap="playRecord" style="width:{{30+item.duration*5}}px;justify-content: flex-end;display:flex;color:#000;">{{item.duration}}"<van-icon name="../../../assets/common/icon/voice-r.png" style="padding:0 0 0 5px;" /></view>
<view class='rightMsg' wx:if="{{item.contentType==='text'}}">{{item.content}}</view>
<view class='rightMsg img' wx:if="{{item.contentType==='img'}}"><image src="{{item.content}}" data-src="{{item.content}}" mode='widthFix' bindtap="onPreview"/></view>
<view>
<image class="headImg" src='{{item.headImg}}' mode='widthFix'></image>
</view>
</view>
</block>
wxml底部輸入框
<view class='inputRoom' style='bottom: {{inputBottom}};height: {{bottomHeight}}'>
<van-row class="bottomRow">
<van-col span="2"wx:if="{{show}}"> <van-icon bindtap="startRecord" class="iconfont icon" class-prefix='icon' size="40rpx" name="yuyin" ></van-icon></van-col>
<van-col span="2" wx:if="{{!show}}"> <van-icon bindtap="startRecord" class="iconfont icon" class-prefix='icon' size="40rpx" name="fabiaowenzhang" ></van-icon></van-col>
<van-col span="18" wx:if="{{show}}"> <input bindconfirm='sendClick'bind:input="inputValue" adjust-position='{{false}}' value='{{inputVal}}' confirm-type='send' bindfocus='focus' bindblur='blur'></input></van-col>
<van-col span="18" wx:if="{{!show}}"> <view class="holdTape" bind:touchstart="startTalk" bind:touchend='stopRecord'>按住請(qǐng)說話</view></van-col>
<van-col span="2"><van-icon class="iconfont icon" class-prefix='icon' size="40rpx" name='biaoqing' bindtap="getEmoji"></van-icon></van-col>
<van-col span="2"><van-uploader use-slot accept='image' bind:after-read="uploadeImg"> <van-icon class="iconfont icon" class-prefix='icon' size="40rpx" name='icon02' ></van-icon></van-uploader></van-col>
</van-row>
<view wx:if="{{showEmoji}}" class="emoji">
<emoji bind:clickEmoji="clickEmoji" data-key="inputVal" value="{{inputVal}}" />
</view>
</view>
</view>
<view class="recordDailog" wx:if="{{showDailog}}" >
<view class="show">
<image src="../../assets/common/images/record.png"></image>
<text>{{toastTitle}}</text>
</view>
css
#page{
height: 90%;
overflow-y: auto;
}
.content{
background: white;
}
.inputRoom {
width: 100vw;
/* height: 16vw; */
border-top: 1px solid #cdcdcd;
position: fixed;
bottom: 0;
display: flex;
align-items: center;
z-index: 20;
background: white;
flex-direction: column;
}
.bottomRow{
width: 100%;
height: 16vw;
display: flex;
align-items: center;
flex-direction: row
}
.bottomRow .van-row{
width: 100%;
}
.emoji{
height: 30vw;
}
input {
width: 90%;
height: 9.33vw;
background-color: #EEF4FA;
border-radius: 6rpx;
font-size: 28rpx;
color: #444;
padding: 0 3%;
margin-left: 2%;
}
.leftMsg {
font-size: 26rpx;
color: #333333;
line-height: 6vw;
padding: 2vw 2.5vw;
background-color: #EEF4FA;
border-radius: 10rpx;
z-index: 10;
}
.rightMsg {
font-size: 26rpx;
color: white;
line-height: 6vw;
padding: 2vw 2.5vw;
background-color: #496DFF;
border-radius: 10rpx;
z-index: 10;
}
.chatFrame{
background: white;
height: 100%
}
.icon{
line-height: 8vw;
}
.head{
display: flex;
align-items: center
}
.headImg{
border-radius: 50%; width: 60rpx;height: 60rpx;
}
.holdTape{
width: 90%;
height: 9.33vw;
background-color: #EEF4FA;
border-radius: 6rpx;
padding: 0 3%;
margin-left: 2%;
display: flex;
align-items: center;
justify-content: center;
}
.recordDailog{
-webkit-transition-duration: 300ms;
transition-duration: 300ms;
z-index: 1000;
position: fixed;
top: 50%;
left: 50%;
width: -webkit-fit-content;
width: fit-content;
-webkit-transform: translate(-50%,-50%);
transform: translate(-50%,-50%);
max-width: var(--toast-max-width,70%);
}
.show{
width: var(--toast-default-width,90px);
min-height: var(--toast-default-min-height,90px);
padding: var(--toast-default-padding,16px);
display: flex;
-webkit-flex-direction: column;
flex-direction: column;
-webkit-align-items: center;
align-items: center;
-webkit-justify-content: center;
justify-content: center;
box-sizing: initial;
color: var(--toast-text-color,#fff);
font-size: var(--toast-font-size,14px);
line-height: var(--toast-line-height,20px);
white-space: pre-wrap;
word-wrap: break-word;
background-color: var(--toast-background-color,rgba(50,50,51,.88));
border-radius: var(--toast-border-radius,4px);
}
.show image{
width: 24px;
height: 24px
}
image{
/* max-width: 88vw;
max-height: 400rpx; */
width: 100%
}
.img{
background: none;
width: 90%
}
.contentRight{
display: flex; justify-content: flex-end; padding: 2vw 2vw 2vw 11vw;width: 86%;
}
.contentLeft{
display: flex; padding: 2vw 11vw 2vw 2vw;width: 86%;
}
js
// pages/contact/contact.js
const {
pageFunc
} = require('../../utils/util.js');
const app = getApp();
var windowWidth = wx.getSystemInfoSync().windowWidth;
var windowHeight = wx.getSystemInfoSync().windowHeight;
var keyHeight = 0;
const { CHAT_DATA}=require("../../data/customerService.js");
import Toast from '../../components/vant/toast/toast';
const recorderManager = wx.getRecorderManager();
const innerAudioContext = wx.createInnerAudioContext();
const db = wx.cloud.database();
/**
* 初始化數(shù)據(jù)
*/
/**
* 計(jì)算msg總高度
*/
function calScrollHeight(that, keyHeight) {
var query = wx.createSelectorQuery();
query.select('.scrollMsg').boundingClientRect(function(rect) {
}).exec();
}
Page({
/**
* 頁面的初始數(shù)據(jù)
*/
data: {
scrollHeight: '100vh',
inputVal:"",
inputBottom: 0,
chatData:[],
show:true,
showDailog:false,
bottomHeight:"18vw",
sendData:{},
pagination: {
pageSize: 5,
currentPage: 1,
total: 0,
},
showEmoji:false,
toastTitle:"錄音中...."
},
/**
* 生命周期函數(shù)--監(jiān)聽頁面加載
*/
onLoad: function (options) {
// this.setData({
// cusHeadIcon: app.globalData.userInfo.avatarUrl,
// });
const {
pagination
} = this.data
this.getData({ param: CHAT_DATA, pagination });
wx.pageScrollTo({
scrollTop: 1000
})
},
getData(params) {
const { chatData } = this.data;
const {
param,
pagination: {
pageSize = 10,
currentPage = 1
},
} = params;
this.setData({
pagination: { pageSize, currentPage }
});
const {
data,
pagination
} = pageFunc(param, currentPage, pageSize);
data.forEach((item) => {
if (item.duration) {
item.duration = Math.ceil(item.duration / 1000)
}
});
this.setData({
'chatData': data.concat(chatData)
});
},
startRecord(){//開始錄音
const {show}=this.data
if (show){
this.setData({
show: false,
})
}else{
this.setData({
show: true,
})
}
},
startTalk(e){//開始說話
this.setData({
showDailog:true,
})
const options = {
duration: 60000,
sampleRate: 44100,
numberOfChannels: 1,
encodeBitRate: 192000,
format: 'aac',
frameSize: 50
}
recorderManager.start(options)
recorderManager.onStart((res) => {
})
},
stopRecord(){//停止說話
const that=this
this.setData({
showDailog:false,
})
recorderManager.stop();
recorderManager.onStop((res) => {
const { sendData, chatData } = that.data;
let { tempFilePath, duration, fileSize} = res
sendData.tempFilePathData=res
duration = Math.ceil(duration / 1000)
const data = { content: tempFilePath, duration , fileSize, contentType: 'voice', type: 1};
chatData.push(data);
wx.createSelectorQuery().select('.content').boundingClientRect(function (rect) {
// 使頁面滾動(dòng)到底部
wx.pageScrollTo({
scrollTop: rect.bottom + 5000
})
}).exec();
that.setData({
'tempFilePath': tempFilePath,
sendData,
chatData,
scrollHeight: (windowHeight - 0) + 'px',
toView: 'msg-' + (chatData.length - 1),
inputBottom: '0px'
})
})
},
playRecord(e){//播放語音
const { currentTarget: { dataset: { duration } }}=e;
const { tempFilePath} = this.data
innerAudioContext.autoplay = true;
innerAudioContext.src = tempFilePath ,
innerAudioContext.onPlay(() => {
this.setData({
toastTitle: "播放中....",
showDailog: true,
})
})
innerAudioContext.onEnded((res) => {
this.setData({
toastTitle: "錄音中....",
showDailog: false,
})
})
innerAudioContext.onError((res) => {
});
innerAudioContext.play()
},
uploadeImg(e){
const { file: { path,size:fileSize} } = e.detail;
const { chatData } = this.data;
const data = { content: path, fileSize, contentType: 'img', type: 1 };
chatData.push(data);
wx.createSelectorQuery().select('.content').boundingClientRect(function (rect) {
// 使頁面滾動(dòng)到底部
wx.pageScrollTo({
scrollTop: rect.bottom + 5000
})
}).exec()
this.setData({
chatData,
scrollHeight: (windowHeight - 0) + 'px',
toView: 'msg-' + (chatData.length - 1),
inputBottom:'0px'
})
},
getEmoji(){//獲取表情包
wx.createSelectorQuery().select('.content').boundingClientRect(function (rect) {
// 使頁面滾動(dòng)到底部
wx.pageScrollTo({
scrollTop: rect.bottom + 5000
})
}).exec()
this.setData({
showEmoji:true,
bottomHeight:"48vw"
})
},
clickEmoji: function (e) {//選擇表情包
const {
detail: {
value
},
currentTarget: {
dataset: {
key
}
}
} = e;
this.setData({
[key]: value
})
},
onPreview(e){
const {
currentTarget: {
dataset: {
src
}
}
} = e;
const urls = [src]
wx.previewImage({
current: src,
urls
})
},
/**
* 生命周期函數(shù)--監(jiān)聽頁面顯示
*/
onShow: function () {
},
/**
* 頁面相關(guān)事件處理函數(shù)--監(jiān)聽用戶下拉動(dòng)作
*/
onPullDownRefresh: function () {
let { pagination: { currentPage } } = this.data
this.getData({
param: CHAT_DATA,
pagination: {
pageSize: 5,
currentPage: currentPage + 1,
}
});
},
/**
* 頁面上拉觸底事件的處理函數(shù)
*/
onReachBottom: function () {
},
/**
* 獲取聚焦
*/
inputValue(e){
const {detail:{value}}=e
this.setData({
inputVal:value
})
},
focus: function (e) {
const { chatData}=this.data
keyHeight = e.detail.height;
wx.pageScrollTo({
scrollTop: windowHeight - keyHeight
})
this.setData({
toView: 'msg-' + (chatData.length - 1),
inputBottom: keyHeight + 'px',
scrollHeight: (windowHeight - keyHeight) + 'px',
showEmoji:false,
bottomHeight: "18vw"
})
//計(jì)算msg高度
// calScrollHeight(this, keyHeight);
},
//失去聚焦(軟鍵盤消失)
blur: function (e) {
const { chatData } = this.data
this.setData({
scrollHeight: '100vh',
inputBottom: 0
})
this.setData({
toView: 'msg-' + (chatData.length - 1)
})
},
/**
* 發(fā)送點(diǎn)擊監(jiān)聽
*/
sendClick: function (e) {
const { chatData, scrollHeight}=this.data;
wx.createSelectorQuery().select('.content').boundingClientRect(function (rect) {
// 使頁面滾動(dòng)到底部
wx.pageScrollTo({
scrollTop: rect.bottom + 5000
})
}).exec()
chatData.push({
type: 1,
contentType: 'text',
content: e.detail.value,
headImg: '../../assets/common/images/headHortrait.jpeg',
})
this.setData({
chatData,
inputVal:''
});
},
/**
* 退回上一頁
*/
toBackClick: function () {
wx.navigateBack({})
}
})// pages/contact/contact.js
const {
pageFunc
} = require('../../utils/util.js');
const app = getApp();
var windowWidth = wx.getSystemInfoSync().windowWidth;
var windowHeight = wx.getSystemInfoSync().windowHeight;
var keyHeight = 0;
const { CHAT_DATA}=require("../../data/customerService.js");
import Toast from '../../components/vant/toast/toast';
const recorderManager = wx.getRecorderManager();
const innerAudioContext = wx.createInnerAudioContext();
const db = wx.cloud.database();
/**
* 初始化數(shù)據(jù)
*/
/**
* 計(jì)算msg總高度
*/
function calScrollHeight(that, keyHeight) {
var query = wx.createSelectorQuery();
query.select('.scrollMsg').boundingClientRect(function(rect) {
}).exec();
}
Page({
/**
* 頁面的初始數(shù)據(jù)
*/
data: {
scrollHeight: '100vh',
inputVal:"",
inputBottom: 0,
chatData:[],
show:true,
showDailog:false,
bottomHeight:"18vw",
sendData:{},
pagination: {
pageSize: 5,
currentPage: 1,
total: 0,
},
showEmoji:false,
toastTitle:"錄音中...."
},
/**
* 生命周期函數(shù)--監(jiān)聽頁面加載
*/
onLoad: function (options) {
// this.setData({
// cusHeadIcon: app.globalData.userInfo.avatarUrl,
// });
const {
pagination
} = this.data
this.getData({ param: CHAT_DATA, pagination });
wx.pageScrollTo({
scrollTop: 1000
})
},
getData(params) {
const { chatData } = this.data;
const {
param,
pagination: {
pageSize = 10,
currentPage = 1
},
} = params;
this.setData({
pagination: { pageSize, currentPage }
});
const {
data,
pagination
} = pageFunc(param, currentPage, pageSize);
data.forEach((item) => {
if (item.duration) {
item.duration = Math.ceil(item.duration / 1000)
}
});
this.setData({
'chatData': data.concat(chatData)
});
},
startRecord(){//開始錄音
const {show}=this.data
if (show){
this.setData({
show: false,
})
}else{
this.setData({
show: true,
})
}
},
startTalk(e){//開始說話
this.setData({
showDailog:true,
})
const options = {
duration: 60000,
sampleRate: 44100,
numberOfChannels: 1,
encodeBitRate: 192000,
format: 'aac',
frameSize: 50
}
recorderManager.start(options)
recorderManager.onStart((res) => {
})
},
stopRecord(){//停止說話
const that=this
this.setData({
showDailog:false,
})
recorderManager.stop();
recorderManager.onStop((res) => {
const { sendData, chatData } = that.data;
let { tempFilePath, duration, fileSize} = res
sendData.tempFilePathData=res
duration = Math.ceil(duration / 1000)
const data = { content: tempFilePath, duration , fileSize, contentType: 'voice', type: 1};
chatData.push(data);
wx.createSelectorQuery().select('.content').boundingClientRect(function (rect) {
// 使頁面滾動(dòng)到底部
wx.pageScrollTo({
scrollTop: rect.bottom + 5000
})
}).exec();
that.setData({
'tempFilePath': tempFilePath,
sendData,
chatData,
scrollHeight: (windowHeight - 0) + 'px',
toView: 'msg-' + (chatData.length - 1),
inputBottom: '0px'
})
})
},
playRecord(e){//播放語音
const { currentTarget: { dataset: { duration } }}=e;
const { tempFilePath} = this.data
innerAudioContext.autoplay = true;
innerAudioContext.src = tempFilePath ,
innerAudioContext.onPlay(() => {
this.setData({
toastTitle: "播放中....",
showDailog: true,
})
})
innerAudioContext.onEnded((res) => {
this.setData({
toastTitle: "錄音中....",
showDailog: false,
})
})
innerAudioContext.onError((res) => {
});
innerAudioContext.play()
},
uploadeImg(e){
const { file: { path,size:fileSize} } = e.detail;
const { chatData } = this.data;
const data = { content: path, fileSize, contentType: 'img', type: 1 };
chatData.push(data);
wx.createSelectorQuery().select('.content').boundingClientRect(function (rect) {
// 使頁面滾動(dòng)到底部
wx.pageScrollTo({
scrollTop: rect.bottom + 5000
})
}).exec()
this.setData({
chatData,
scrollHeight: (windowHeight - 0) + 'px',
toView: 'msg-' + (chatData.length - 1),
inputBottom:'0px'
})
},
getEmoji(){//獲取表情包
wx.createSelectorQuery().select('.content').boundingClientRect(function (rect) {
// 使頁面滾動(dòng)到底部
wx.pageScrollTo({
scrollTop: rect.bottom + 5000
})
}).exec()
this.setData({
showEmoji:true,
bottomHeight:"48vw"
})
},
clickEmoji: function (e) {//選擇表情包
const {
detail: {
value
},
currentTarget: {
dataset: {
key
}
}
} = e;
this.setData({
[key]: value
})
},
onPreview(e){
const {
currentTarget: {
dataset: {
src
}
}
} = e;
const urls = [src]
wx.previewImage({
current: src,
urls
})
},
/**
* 生命周期函數(shù)--監(jiān)聽頁面顯示
*/
onShow: function () {
},
/**
* 頁面相關(guān)事件處理函數(shù)--監(jiān)聽用戶下拉動(dòng)作
*/
onPullDownRefresh: function () {
let { pagination: { currentPage } } = this.data
this.getData({
param: CHAT_DATA,
pagination: {
pageSize: 5,
currentPage: currentPage + 1,
}
});
},
/**
* 頁面上拉觸底事件的處理函數(shù)
*/
onReachBottom: function () {
},
/**
* 獲取聚焦
*/
inputValue(e){
const {detail:{value}}=e
this.setData({
inputVal:value
})
},
focus: function (e) {
const { chatData}=this.data
keyHeight = e.detail.height;
wx.pageScrollTo({
scrollTop: windowHeight - keyHeight
})
this.setData({
toView: 'msg-' + (chatData.length - 1),
inputBottom: keyHeight + 'px',
scrollHeight: (windowHeight - keyHeight) + 'px',
showEmoji:false,
bottomHeight: "18vw"
})
//計(jì)算msg高度
// calScrollHeight(this, keyHeight);
},
//失去聚焦(軟鍵盤消失)
blur: function (e) {
const { chatData } = this.data
this.setData({
scrollHeight: '100vh',
inputBottom: 0
})
this.setData({
toView: 'msg-' + (chatData.length - 1)
})
},
/**
* 發(fā)送點(diǎn)擊監(jiān)聽
*/
sendClick: function (e) {
const { chatData, scrollHeight}=this.data;
wx.createSelectorQuery().select('.content').boundingClientRect(function (rect) {
// 使頁面滾動(dòng)到底部
wx.pageScrollTo({
scrollTop: rect.bottom + 5000
})
}).exec()
chatData.push({
type: 1,
contentType: 'text',
content: e.detail.value,
headImg: '../../assets/common/images/headHortrait.jpeg',
})
this.setData({
chatData,
inputVal:''
});
},
/**
* 退回上一頁
*/
toBackClick: function () {
wx.navigateBack({})
}
})
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
您可能感興趣的文章:
- 如何利用微信小程序和php實(shí)現(xiàn)即時(shí)通訊聊天功能
- python實(shí)現(xiàn)簡單的聊天小程序
- 微信小程序?qū)崿F(xiàn)聊天室功能
- 微信小程序?qū)崿F(xiàn)聊天室
- 小程序?qū)崿F(xiàn)簡單語音聊天的示例代碼
- 微信小程序websocket實(shí)現(xiàn)即時(shí)聊天功能
- 微信小程序視頻彈幕發(fā)送功能的實(shí)現(xiàn)
- 微信小程序?qū)崿F(xiàn)發(fā)送模板消息功能示例【通過openid推送消息給用戶】
- 微信小程序發(fā)送短信驗(yàn)證碼完整實(shí)例
- 微信小程序?qū)崿F(xiàn)聊天界面發(fā)送功能(示例代碼)
相關(guān)文章
js尾調(diào)用優(yōu)化的實(shí)現(xiàn)
這篇文章主要介紹了js尾調(diào)用優(yōu)化的實(shí)現(xiàn),尾調(diào)用(Tail Call)是函數(shù)式編程的一個(gè)重要概念,本文介紹它的含義和用法。感興趣的可以了解一下2019-05-05
JS 實(shí)現(xiàn)點(diǎn)擊a標(biāo)簽的時(shí)候讓其背景更換
點(diǎn)擊a標(biāo)簽的時(shí)候給其換背景的方法有很多,在本文將為大家介紹下js是如何實(shí)現(xiàn)的,感興趣的朋友不要錯(cuò)過2013-10-10
js如何構(gòu)造elementUI樹狀菜單的數(shù)據(jù)結(jié)構(gòu)詳解
由于業(yè)務(wù)需要,要求實(shí)現(xiàn)樹形菜單,且菜單數(shù)據(jù)由后臺(tái)返回,下面這篇文章主要給大家介紹了關(guān)于js如何構(gòu)造elementUI樹狀菜單的數(shù)據(jù)結(jié)構(gòu)的相關(guān)資料,需要的朋友可以參考下2021-05-05
基于JavaScript實(shí)現(xiàn)文件秒傳功能
在互聯(lián)網(wǎng)高速發(fā)展的今天,文件上傳已經(jīng)成為網(wǎng)頁應(yīng)用中的一個(gè)基本功能,隨著用戶上傳文件尺寸的不斷增大、對(duì)質(zhì)量清晰度的要求也越來越高,所以本文給大家介紹了如何使用JavaScript實(shí)現(xiàn)文件秒傳功能,需要的朋友可以參考下2024-01-01
JavaScript實(shí)現(xiàn)批量重命名文件
這篇文章主要為大家詳細(xì)介紹了如何利用JavaScript實(shí)現(xiàn)批量重命名文件,文中的示例代碼講解詳細(xì),有需要的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-12-12

