VUE DIV模拟input框的基本处理
关键代码
<div class="dialog-main"
:contenteditable= "editable"
v-text="noticeContent"
v-if="noDate"
innerHTML.length = "20"
ref="Maincontent"
@input="handleInput"
@compositionstart="handleStart"
@compositionend="handleEnd"
>
/**
* 限制输入长度
* 如10个中文,英文就可以20
*/
validateTextLength (value) {
// 中文、中文标点、全角字符按1长度,英文、英文符号、数字按0.5长度计算
let cnReg = /([\u4e00-\u9fa5]|[\u3000-\u303F]|[\uFF00-\uFF60])/g
let mat = value.match(cnReg)
let length
if (mat) {
length = (mat.length + (value.length - mat.length) * 0.5)
return length
} else {
return value.length * 0.5
}
},
/**
* @input事件
*/
handleInput (event) {
let text = event.target.innerText
this.valueHandle(event, text)
},
/**
* 处理逻辑
* strVale文本数据
*/
valueHandle (event, strVale) {
let _this = this
let text = strVale
this.sendContent = text
if (this.composing) {
return
}
let len = this.validateTextLength(text)
if (len > 500) {
this.$refs.Maincontent.innerHTML = text.substr(0, 500)
this.$refs.Maincontent.focus()
}
setTimeout(() => {
_this.keepLastIndex(event.target)
}, 5)
// 拓展 如果想要只需要前100位数据
// this.content = this.content.substring(0, 100)
},
/**
* 中文输入开始
*/
handleStart () {
this.composing = true
},
/**
* 中文输入结束
*/
handleEnd ($event) {
this.composing = false
let text = $event.target.innerHTML
// console.log($event.target.innerHTML)
this.valueHandle($event, text)
},
// 编辑
editHandle () {
this.editable = true
this.noDate = true
// let notice = this.NoticeContent
// this.NoticeContent(false)
},

全部代码
<template>
<div class="del-confirm" v-if="groupNameStatus">
<div class="group-dialog">
<div class="dialog-content">
<p class="win-top">
<span class="win-txt">群公告</span>
<span class="edit" @click="editHandle" v-if="+userId === +groupCreaterId"><icon-svg name="icon-kaka-compile" icon-style="edit-ico"></icon-svg></span>
<span class="close-icon" @click="closeGroupNameDialog">
<icon-svg name="icon-kaka-close" icon-style="off-ico"></icon-svg>
</span>
</p>
<div class="dialog-main"
:contenteditable= "editable"
v-text="noticeContent"
v-if="noDate"
innerHTML.length = "20"
ref="Maincontent"
@input="handleInput"
@compositionstart="handleStart"
@compositionend="handleEnd"
>
</div>
<!-- <div>{{groupAnnouncement}}</div> -->
<div v-if="!noDate" class="dialog-main">暂无群公告</div>
<div class="name-create-btn" v-if="editable">
<div class="cancel" @click="cancelEdit">取消</div>
<div class="sure" @click="sure">确定</div>
</div>
<div class="edit-tips" v-if="!editable"><p class="tips-main">只有群主才能修改公告</p></div>
</div>
</div>
</div>
</template>
<script>
import api from '@/api/group'
export default {
name: 'notice',
showChatBox: {
type: Boolean,
default: false
},
data () {
return {
groupNameStatus: true,
friendsInfo: this.$store.getters.friendsInfo,
contactList: {},
checkedContact: [],
searchVal: '',
groupName: '',
userId: this.$store.getters.userId,
noticeContent: '',
editable: false,
noDate: false,
sendContent: '',
composing: false
}
},
computed: {
// 群id
groupId () {
return this.$store.state.mainInit.showGroupNoticeId.groupId
},
// 群id
groupCreaterId () {
return this.$store.getters.groupSetInfo.createrId
},
groupAnnouncement () {
return this.$store.getters.groupSetInfo.groupAnnouncement
},
NoticeContent: {
get () {
let groupAnnouncement = this.$store.getters.groupSetInfo.groupAnnouncement
if (groupAnnouncement) {
this.noDate = true
this.noticeContent = groupAnnouncement
}
return groupAnnouncement
},
set (v) {
// 使用vuex中的mutations中定义好的方法来改变
let groupNotice = this.$store.state.mainInit.showGroupNoticeId
let copyMyinfo = Object.assign({}, groupNotice)
copyMyinfo.groupInfo.groupAnnouncement = v
console.log(copyMyinfo)
this.$store.dispatch('showGroupNoticeId', copyMyinfo)
}
}
},
methods: {
/**
* 限制输入长度
* 如10个中文,英文就可以20
*/
validateTextLength (value) {
// 中文、中文标点、全角字符按1长度,英文、英文符号、数字按0.5长度计算
let cnReg = /([\u4e00-\u9fa5]|[\u3000-\u303F]|[\uFF00-\uFF60])/g
let mat = value.match(cnReg)
let length
if (mat) {
length = (mat.length + (value.length - mat.length) * 0.5)
return length
} else {
return value.length * 0.5
}
},
/**
* @input事件
*/
handleInput (event) {
let text = event.target.innerText
this.valueHandle(event, text)
},
/**
* 处理逻辑
* strVale文本数据
*/
valueHandle (event, strVale) {
let _this = this
let text = strVale
this.sendContent = text
if (this.composing) {
return
}
let len = this.validateTextLength(text)
if (len > 500) {
this.$refs.Maincontent.innerHTML = text.substr(0, 500)
this.$refs.Maincontent.focus()
}
setTimeout(() => {
_this.keepLastIndex(event.target)
}, 5)
// 拓展 如果想要只需要前100位数据
// this.content = this.content.substring(0, 100)
},
/**
* 中文输入开始
*/
handleStart () {
this.composing = true
},
/**
* 中文输入结束
*/
handleEnd ($event) {
this.composing = false
let text = $event.target.innerHTML
// console.log($event.target.innerHTML)
this.valueHandle($event, text)
},
// 编辑
editHandle () {
this.editable = true
this.noDate = true
// let notice = this.NoticeContent
// this.NoticeContent(false)
},
closeCreateGroupWindow () {
this.$electron.ipcRenderer.send('closeCreateGroup')
},
// 取消
cancelEdit () {
this.editable = false
if (this.noticeContent) {
this.noDate = true
} else {
this.noDate = false
}
},
// 关闭
closeGroupNameDialog () {
this.$store.dispatch('showGroupNotice', false)
this.editable = false
},
// 确定保存
sure () {
// console.log(this.noticeContent) 公告接口测试修改
let groupId = this.$store.state.mainInit.showGroupNoticeId.groupId
let params = {
userId: this.$store.getters.userId,
groupId: groupId,
groupAnnouncement: this.sendContent,
devType: 3
}
api.sendAnnouncement(params).then(res => {
console.log(res)
if (res.code === '1') {
this.$store.dispatch('showGroupNotice', false)
// 保存到当前的VUEX
let groupSetInfo = this.$store.getters.groupSetInfo
let copyMyinfo = Object.assign({}, groupSetInfo)
copyMyinfo.groupAnnouncement = this.sendContent
this.$store.dispatch('groupSetInfo', copyMyinfo)
}
this.editable = false
// this.$store.commit('SHOW_HANDLESUCCESS', true)
}).catch(err => {
console.log(err)
})
},
keepLastIndex (obj) {
if (window.getSelection) { // ie11 10 9 ff safari
obj.focus() // 解决ff不获取焦点无法定位问题
let range = window.getSelection() // 创建range
range.selectAllChildren(obj) // range 选择obj下所有子内容
range.collapseToEnd() // 光标移至最后
} else if (document.selection) { // ie10 9 8 7 6 5
let range = document.selection.createRange() // 创建选择对象
// var range = document.body.createTextRange();
range.moveToElementText(obj) // range定位到obj
range.collapse(false) // 光标移至最后
range.select()
}
},
getNoticeData () {
let groupAnnouncement = this.$store.getters.groupSetInfo.groupAnnouncement
if (groupAnnouncement) {
this.noDate = true
this.noticeContent = groupAnnouncement
}
}
},
created () {
// this.dealContactList()
this.getNoticeData()
}
}
</script>
<style scoped lang="scss">
.del-confirm {
position: absolute;
width: 100%;
height: 100%;
margin: auto;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color:rgba(0, 0, 0, 0);
z-index: 999;
.win-top {
height: 40px;
background-color: #F5F6F7;
padding-left: 20px;
border-radius: 4px;
// @extend .drag;
.win-txt {
float: left;
font-size: 14px;
color: #252B38;
line-height: 40px;
// @extend .no-drag;
}
.edit{
width: 15px;
height: 14px;
line-height: 40px;
margin-left: 10px;
cursor: pointer;
}
.close-icon {
float: right;
width: 30px;
height: 30px;
margin-top: 5px;
margin-right: 5px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
.iconsvg {
color: #A4A4A7;
font-size: 9px;
}
&:hover {
& > .off-ico {
color: #f45454;
}
}
@extend .no-drag;
}
}
.group-dialog {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
background: $rgba;
z-index: 1;
.dialog-content {
width: 338px;
height: 440px;
position: absolute;
background-color: #fff;
left: 50%;
top: 50%;
margin-left: -169px;
margin-top: -220px;
box-shadow: 0 2px 10px 2px rgba(0, 0, 0, .19);
border-radius: 4px;
.dialog-main {
height: 350px;
padding: 20px;
overflow: auto;
// -webkit-user-modify: read-write-plaintext-only;
outline: none;
[contenteditable]:empty:not(:focus):before{
content: attr(placeholder)
}
&:focus {
outline: none;
}
}
}
.group-name {
width: 213px;
height: 22px;
border: 1px solid #E2E6E9;
font-size: 12px;
color: #232936;
padding: 0 7px;
display: block;
margin: 22px auto 35px;
&:focus {
outline: none;
}
}
.name-create-btn {
text-align: center;
// height: 30px;
font-size: 0;
.cancel {
display: inline-block;
width: 68px;
height: 30px;
line-height: 30px;
text-align: center;
border-radius: 4px;
font-size: 12px;
cursor: pointer;
background-color: #ffffff;
border: 1px solid #999;
color: #333;
margin-right: 15px;
}
.sure{
display: inline-block;
margin-left: 15px;
width: 68px;
height: 30px;
line-height: 30px;
text-align: center;
border-radius: 4px;
font-size: 12px;
cursor: pointer;
background-color: $btn-confim;
color: #fff;
border: 1px solid $btn-confim;
}
}
.edit-tips {
text-align: center;
height: 30px;
line-height: 30px;
.tips-main{
font-size:10px;
color:rgba(162,164,168,1);
position: relative;
&::after,&::before {
content: '';
width: 20px;
height: 1px;
background:rgba(216,216,216,1);
border-radius: 1px;
position: absolute;
}
&::after {
left: 90px;
top: 15px;
}
&::before {
right: 90px;
top: 15px;
}
}
}
}
}
</style>
VUE DIV模拟input框的基本处理的更多相关文章
- div模拟文本框textarea
需求:利用highlight.js对文本框中的内容进行高亮显示 1.highlight.js使用 js中:<script src="js/highlight/highlight.pac ...
- vue中让input框自动聚焦
created(){ this.changfouce(); }, methods: { //在vue生命周期的created()钩子函数进行的DOM操作要放在Vue.nextTick()的回调函数中, ...
- input框只允许输入正整数、正数(包含小数)的解决方法 vue.js实现
我来打自己脸了!!!!...刚刚发现在中文输入法下是无效的,有人能解决这个问题么 如果要求input只能输入数字怎么做? 设置type="number" ? 那我如果想限制长度,此 ...
- vue开发中利用正则限制input框的输入(手机号、非0开头的正整数等)
我们在前端开发中经常会碰到类似手机号输入获取验证码的情况,通常情况下手机号的输入需要只能输入11位的整数数字.并且需要过滤掉一些明显不符合手机号格式的输入,那么我们就需要用户在输入的时候就控制可以输入 ...
- jquery div 下拉框焦点事件
这章与上一张<jquery input 下拉框(模拟select控件)焦点事件>类似 这章讲述div的焦点事件如何使用 div的焦点事件与input的焦点事件区别在于 需要多添加一个属性: ...
- 小实例---关于input宽度自适应以及多个input框合并拆分
前两个月,公司内部需要开发关于大数据方面的辅助工具语料分词系统,在这个项目中遇到以下几个主要问题,在此分享~ 一.input宽度根据内定文本宽度自适应 背景:项目需求中,前台展示,需要从后台获取的.t ...
- 使用DIV弹出框的代码示例,备忘。
1.思路 使用DIV模拟弹出框,一共用三个div: divWindow: 原来的界面内容区域 divLogin:要弹出的内容区域 divBackground:给弹出内容区域做个遮罩的区域. 点击 “请 ...
- vue.js实现单选框、复选框和下拉框
Vue.js可以很方便的实现数据双向绑定,所以在处理表单,人机交互方面具有很大的优势.下边以单选框.复选框和下拉框为例介绍他们在HTML和Vue.js中的具体实现方式. 一.单选框 在传统的HTM ...
- VUE 单选下拉框Select中动态加载 默认选中第一个
<lable>分类情况</lable> <select v-model="content.tid"> <option v-for=&quo ...
随机推荐
- java:IO流(File,字节流/输入输出流(InputStream(FileInputStream),OutputStream(FileOutStream)),字符流(Reader,Writer))
File: * java.io.File类:代表一个文件或目录. * 常用的构造方法: * File(String pathname)通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例 ...
- Python基础知识思维导图|自学Python指南
微信公众号[软件测试大本营]回复"python",获取50本python精华电子书. 测试/开发知识干货,互联网职场,程序员成长崛起,终身学习. 现在最火的编程语言是什么?答案就是 ...
- cocos2dx基础篇(4) 标签CCLabel
[本节内容] cocos2dx三种文字字体的显示:CCLabelTTF(一般字体).CCLabelAtlas(自定义字体).CCLabelBMFont(自定义字体) CCLabelTTF CCLabe ...
- [DS+Algo] 011 哈希
目录 1. hash 函数 2. 哈希表 3. 密码存储 1. hash 函数 关键词 任意长度输入 固定长度输出 特征 理论上输入跟输出并不是一对一 实际使用假定不会出现碰撞或者冲突 常用算法 (M ...
- 【转帖】国产x86处理器KX-6000发布
国产最先进x86处理器KX-6000发布:8核3.0GHz 力压酷睿i5处理器 https://www.cnbeta.com/articles/tech/858981.htm 全网所有的网页都写错了 ...
- 【基本优化实践】【1.4】tempdb优化
[1]tempdb介绍 tempdb全局存储内部对象,用户对象,临时表,临时对象,以及SQL Server操作创建的存储过程.每个数据库实例只有一个tempdb,所以可能存在性能以及磁盘空间瓶颈. 各 ...
- XOR on segment(线段树区间异或更新)
原题传送门 本题大意:给定n个数字和m个操作,操作共有两种,第一种是求解区间l到r上元素的和,第二种是将区间l到r的元素都异或一个x,作为某个位置的新值. 很容易想到线段树维护区间和,但是我们发现,在 ...
- c++实现直接插入排序
基本概念 直接插入排序是一种最简单的排序方法,排序过程为:先将第一个元素看作是只有一个元素的有序子表,然后从第二个元素开始,将待排序元素依次插入到前面有序的子表中,直到全部排序完毕.在整个过程中,前面 ...
- PostgreSQL-事务与commit优化
基本概念 事务 Transaction 是 数据库管理系统DBMS 执行过程中的一个逻辑单元,是一个 sql命令组成的序列. 其特点在于,当事务被提交DBMS后,DBMS需要确保所有的操作被完成:如果 ...
- python中逐行打印
方法一:readline函数 f = open("./code.txt") # 返回一个文件对象 line = f.readline() # 调用文件的 readline()方法 ...