微信小程序聊天功能的示例代码


Posted in Javascript onJanuary 13, 2020

效果

微信小程序聊天功能的示例代码

初始化滚动条高度

var keyHeight = 0;

数据格式

const CHAT_DATA=[
 {
  type:0,//0客服1用户
  content:'欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎',
  headImg:'../../assets/common/images/headHortrait.jpeg',//头像
  creatTime:'2019-01-01',//创建时间
  contentType:'text'
 }, {
  type: 0,//0客服1用户
  content: '1111111',
  headImg: '../../assets/common/images/headHortrait.jpeg',//头像
  creatTime: '2019-01-01',//创建时间
  contentType: 'text'
 }, {
  type: 1,//0客服1用户
  content: '222222',
  headImg: '../../assets/common/images/headHortrait.jpeg',//头像
  creatTime: '2019-01-01',//创建时间
  contentType: 'text'
 }, {
  type: 0,//0客服1用户
  content: '333333',
  headImg: '../../assets/common/images/headHortrait.jpeg',//头像
  creatTime: '2019-01-01',//创建时间
  contentType: 'text'
 }, {
  type: 1,//0客服1用户
  content: '4444444',
  headImg: '../../assets/common/images/headHortrait.jpeg',//头像
  creatTime: '2019-01-01',//创建时间
  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',//创建时间
  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',//创建时间
  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',//创建时间
  contentType: 'img'
 }, {
  type: 1,//0客服1用户
  content: 'https://img.yzcdn.cn/vant/cat.jpeg',
  headImg: '../../assets/common/images/headHortrait.jpeg',//头像
  creatTime: '2019-01-01',//创建时间
  contentType: 'img'
 }
];

wxml对话框

<block wx:key wx:for='{{chatData}}' wx:for-index="index">

   <!-- 单个消息1 客服发出(左) -->
   <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>

   <!-- 单个消息2 用户发出(右) -->
   <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'>按住请说话</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();
/**
 * 初始化数据
 */
/**
 * 计算msg总高度
 */
function calScrollHeight(that, keyHeight) {
 var query = wx.createSelectorQuery();
 query.select('.scrollMsg').boundingClientRect(function(rect) {
 }).exec();
}
Page({

 /**
  * 页面的初始数据
  */
 data: {
  scrollHeight: '100vh',
  inputVal:"",
  inputBottom: 0,
  chatData:[],
  show:true,
  showDailog:false,
  bottomHeight:"18vw",
  sendData:{},
  pagination: {
   pageSize: 5,
   currentPage: 1,
   total: 0,
  },
  showEmoji:false,
  toastTitle:"录音中...."
 },

 /**
  * 生命周期函数--监听页面加载
  */
 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) {
    // 使页面滚动到底部
    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) {
   // 使页面滚动到底部
   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) {
   // 使页面滚动到底部
   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
  })
 },
 /**
  * 生命周期函数--监听页面显示
  */
 onShow: function () {

 },

 /**
  * 页面相关事件处理函数--监听用户下拉动作
  */
 onPullDownRefresh: function () {
  let { pagination: { currentPage } } = this.data
  this.getData({
   param: CHAT_DATA,
   pagination: {
    pageSize: 5,
    currentPage: currentPage + 1,
   }
  });
 },

 /**
  * 页面上拉触底事件的处理函数
  */
 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"
  })
  //计算msg高度
  // calScrollHeight(this, keyHeight);

 },

 //失去聚焦(软键盘消失)
 blur: function (e) {
  const { chatData } = this.data
  this.setData({
   scrollHeight: '100vh',
   inputBottom: 0
  })
  this.setData({
   toView: 'msg-' + (chatData.length - 1)
  })

 },

 /**
  * 发送点击监听
  */
 sendClick: function (e) {
  const { chatData, scrollHeight}=this.data;
  wx.createSelectorQuery().select('.content').boundingClientRect(function (rect) {
   // 使页面滚动到底部
   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();
/**
 * 初始化数据
 */
/**
 * 计算msg总高度
 */
function calScrollHeight(that, keyHeight) {
 var query = wx.createSelectorQuery();
 query.select('.scrollMsg').boundingClientRect(function(rect) {
 }).exec();
}
Page({

 /**
  * 页面的初始数据
  */
 data: {
  scrollHeight: '100vh',
  inputVal:"",
  inputBottom: 0,
  chatData:[],
  show:true,
  showDailog:false,
  bottomHeight:"18vw",
  sendData:{},
  pagination: {
   pageSize: 5,
   currentPage: 1,
   total: 0,
  },
  showEmoji:false,
  toastTitle:"录音中...."
 },

 /**
  * 生命周期函数--监听页面加载
  */
 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) {
    // 使页面滚动到底部
    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) {
   // 使页面滚动到底部
   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) {
   // 使页面滚动到底部
   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
  })
 },
 /**
  * 生命周期函数--监听页面显示
  */
 onShow: function () {

 },

 /**
  * 页面相关事件处理函数--监听用户下拉动作
  */
 onPullDownRefresh: function () {
  let { pagination: { currentPage } } = this.data
  this.getData({
   param: CHAT_DATA,
   pagination: {
    pageSize: 5,
    currentPage: currentPage + 1,
   }
  });
 },

 /**
  * 页面上拉触底事件的处理函数
  */
 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"
  })
  //计算msg高度
  // calScrollHeight(this, keyHeight);

 },

 //失去聚焦(软键盘消失)
 blur: function (e) {
  const { chatData } = this.data
  this.setData({
   scrollHeight: '100vh',
   inputBottom: 0
  })
  this.setData({
   toView: 'msg-' + (chatData.length - 1)
  })

 },

 /**
  * 发送点击监听
  */
 sendClick: function (e) {
  const { chatData, scrollHeight}=this.data;
  wx.createSelectorQuery().select('.content').boundingClientRect(function (rect) {
   // 使页面滚动到底部
   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({})
 }

})

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript 函数速查表
Feb 07 Javascript
javascript 弹出层组件(升级版)
May 12 Javascript
jquery 插件开发 extjs中的extend用法小结
Jan 04 Javascript
JQuery页面的表格数据的增加与分页的实现
Dec 10 Javascript
textarea焦点的用法实现获取焦点清空失去焦点提示效果
May 19 Javascript
JavaScript使用指针操作实现约瑟夫问题实例
Apr 07 Javascript
AngualrJS中每次$http请求时的一个遮罩层Directive
Jan 26 Javascript
JS在一定时间内跳转页面及各种刷新页面的实现方法
May 26 Javascript
原生js实现日期计算器功能
Feb 17 Javascript
JS获取指定月份的天数两种实现方法
Jun 22 Javascript
如何为你的JavaScript代码日志着色详解
Apr 08 Javascript
Vue组件为什么data必须是一个函数
Jun 11 Javascript
js实现适配移动端的拖动效果
Jan 13 #Javascript
Vue 嵌套路由使用总结(推荐)
Jan 13 #Javascript
优化Vue中date format的性能详解
Jan 13 #Javascript
JS document文档的简单操作完整示例
Jan 13 #Javascript
JavaScript数组排序小程序实现解析
Jan 13 #Javascript
JS document form表单元素操作完整示例
Jan 13 #Javascript
JS校验与最终登陆界面功能完整示例
Jan 13 #Javascript
You might like
五款常用mysql slow log分析工具的比较分析
2011/05/22 PHP
PHP删除指定目录中的所有目录及文件的方法
2015/02/26 PHP
PHP模板引擎smarty详细介绍
2015/05/26 PHP
Yii配置与使用memcached缓存的方法
2016/07/13 PHP
PHP基于PDO扩展操作mysql数据库示例
2018/12/24 PHP
PHP标准库 (SPL)――Countable用法示例
2020/06/05 PHP
JavaScript 10件让人费解的事情
2010/02/15 Javascript
IE6 hack for js 集锦
2014/09/23 Javascript
打造个性化的功能强大的Jquery虚拟键盘(VirtualKeyboard)
2014/10/11 Javascript
使用script的src实现跨域和类似ajax效果
2014/11/10 Javascript
JS给超链接加确认对话框的方法
2015/02/24 Javascript
zepto与jquery的区别及zepto的不同使用8条小结
2016/07/28 Javascript
纯css下拉菜单 无需js
2016/08/15 Javascript
JS正则表达式学习之贪婪和非贪婪模式实例总结
2016/12/26 Javascript
js canvas实现QQ拨打电话特效
2017/05/10 Javascript
Javascript中Promise的四种常用方法总结
2017/07/14 Javascript
通过js控制时间,一秒一秒自己动的实例
2017/10/25 Javascript
浅谈Postman解决token传参的问题
2018/03/31 Javascript
微信小程序授权登陆及每次检查是否授权实例代码
2019/09/18 Javascript
JavaScript实现指定数量的并发限制的示例代码
2020/03/10 Javascript
解决echarts 一条柱状图显示两个值,类似进度条的问题
2020/07/20 Javascript
小程序实现点击tab切换左右滑动
2020/11/16 Javascript
跟老齐学Python之总结参数的传递
2014/10/10 Python
Python基于OpenCV实现人脸检测并保存
2019/07/23 Python
Python3.7 pyodbc完美配置访问access数据库
2019/10/03 Python
Python发送邮件封装实现过程详解
2020/05/09 Python
教你使用Sublime text3搭建Python开发环境及常用插件安装另分享Sublime text3最新激活注册码
2020/11/12 Python
详解HTML5中CSS外观属性
2020/09/10 HTML / CSS
一个精品风格的世界:Atterley
2019/05/01 全球购物
函授教育个人学习的自我评价
2013/12/31 职场文书
大学生职业生涯规划范文
2014/01/22 职场文书
应聘护士求职信
2014/07/21 职场文书
2014坚持党风廉政建设思想汇报
2014/09/18 职场文书
招商引资工作汇报
2014/10/28 职场文书
终止劳动合同通知书
2015/04/16 职场文书
手把手教你导入Go语言第三方库
2021/08/04 Golang