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


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 相关文章推荐
仿校内登陆框,精美,给那些很厉害但是没有设计天才的程序员
Nov 24 Javascript
jquery 表格的增行删行实现思路
Mar 21 Javascript
使用jQuery.wechat构建微信WEB应用
Oct 09 Javascript
了不起的node.js读书笔记之node的学习总结
Dec 22 Javascript
基于jQuery Bar Indicator 插件实现进度条展示效果
Sep 30 Javascript
JS实现的最简Table选项卡效果
Oct 14 Javascript
JavaScript:Date类型全面解析
May 19 Javascript
详解Vue生命周期的示例
Mar 10 Javascript
AngularJS ng-repeat指令及Ajax的应用实例分析
Jul 06 Javascript
最基础的vue.js双向绑定操作
Aug 23 Javascript
解决angular2在双向数据绑定时[(ngModel)]无法使用的问题
Sep 13 Javascript
layui清空,重置表单数据的实例
Sep 12 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内存表来代替php session的类
2009/02/01 PHP
PHP生成短网址的3种方法代码实例
2014/07/08 PHP
PHP自带方法验证邮箱是否存在
2016/02/01 PHP
浅析PHP类的反射来实现依赖注入过程
2018/02/06 PHP
php处理多图上传压缩代码功能
2018/06/13 PHP
详解PHP神奇又有用的Trait
2019/03/25 PHP
PHP5.6.8连接SQL Server 2008 R2数据库常用技巧分析总结
2019/05/06 PHP
仿jQuery的siblings效果的js代码
2011/08/09 Javascript
HTML复选框和单选框 checkbox和radio事件介绍
2012/12/12 Javascript
Jquery+CSS3实现一款简洁大气带滑动效果的弹出层
2013/05/15 Javascript
js动态调用css属性的小规律及实例说明
2013/12/28 Javascript
JS获取各种浏览器窗口大小的方法
2014/01/14 Javascript
js修改原型的属性使用介绍
2014/01/26 Javascript
原生js实现复制对象、扩展对象 类似jquery中的extend()方法
2014/08/30 Javascript
jQuery插件实现控制网页元素动态居中显示
2015/03/24 Javascript
轻松掌握jQuery中wrap()与unwrap()函数的用法
2016/05/24 Javascript
javascript创建含数字字母的随机字符串方法总结
2016/08/01 Javascript
Angular2表单自定义验证器的实现
2016/10/19 Javascript
BootStrap Tooltip插件源码解析
2016/12/27 Javascript
详解react-router 4.0 下服务器如何配合BrowserRouter
2017/12/29 Javascript
vue中的inject学习教程
2019/04/24 Javascript
vue实现按需加载组件及异步组件功能
2019/05/27 Javascript
微信公众号平台接口开发 获取微信服务器IP地址方法解析
2019/08/14 Javascript
vue轮播组件实现$children和$parent 附带好用的gif录制工具
2019/09/26 Javascript
[00:56]PWL开团时刻DAY8——追追追追追!
2020/11/09 DOTA
python 正则表达式 概述及常用字符
2009/05/04 Python
Python基于Pymssql模块实现连接SQL Server数据库的方法详解
2017/07/20 Python
Python数据结构与算法之使用队列解决小猫钓鱼问题
2017/12/14 Python
详解Python if-elif-else知识点
2018/06/11 Python
解决tensorflow测试模型时NotFoundError错误的问题
2018/07/27 Python
Python中矩阵创建和矩阵运算方法
2018/08/04 Python
python创建文件备份的脚本
2018/09/11 Python
python中Django文件上传方法详解
2020/08/05 Python
初中生个人学习的自我评价
2013/12/04 职场文书
2016中秋节问候语
2015/11/11 职场文书
golang中实现给gif、png、jpeg图片添加文字水印
2021/04/26 Golang