重点1: 一但赋值内容,光标会失去,导致光标到第一位

解决方法 设置一个状态位isChange,编辑的时候不进行watch更新,因为emit会自动改变外层的值,触发watch

解决方法2 找回上一次的值进行替换

重点2:div可编辑  contenteditable="true"

重点3:div内只能是文本 不要html

-webkit-user-modify: read-write-plaintext-only;
user-modify: read-write-plaintext-only;

重点4: 上下高度居中(多行)

display: table-cell; vertical-align: middle;

重点5:移动光标

// 光标移动到起始偏移位置(具体看上下文代码)

document.getSelection().collapse(_this.firstChild, txtAnchorOffset)

重点5:输入中文的长度计算

重点6:复制黏贴事件的处理(最大长度)光标如何恢复原始位置,超出最大长度如何处理

最后 fail 的地方是

1,没找到中文拼音输入多字,按空格等按键确认的文字是什么,就是没找到怎么获取

2. 没找到中文输入前的文字是什么

3. 多行的文字进行处理,我记得是个数组node

4. 没能恢复到没有输入的前的状态

小计:

发现iview的textarea,在这块也存在光标位置计算不准确,它是把文字删了,恢复之前的状态,但是光标位置没有恢复。

参考

-webkit-user-modify

DIV可编辑后,与限制输入及光标偏移的纠葛
https://www.cnblogs.com/echon-cw/p/9809524.html

限制可编辑div只能输入纯文本
https://www.cnblogs.com/libo0125ok/p/8143642.html

<!--
* @description text
!-->
<template>
<div ref="textareaCenter" id="textareaCenter"
@focus="isChange = false"
@blur="isChange = true"
class="textareaCenter" contenteditable="true" v-text="innerValue">
</div>
</template> <script>
// import privateZenMixins from '@/view/biz/input/components/privateZenMixins.js'
export default {
name: 'textareaCenter',
// mixins: [privateZenMixins],
components: {},
props: {
maxlength: {
type: Number,
default:
},
value: {
type: String,
default: ''
}
},
data () {
return {
isChange: true,
innerValue: this.value
}
},
watch: {
value (val) {
if (this.isChange) {
this.innerValue = val
}
},
innerValue (val) {
console.info('innerValue', val)
}
// value (val) {
// console.info('this.$refs.textareaCenterRef.target.innerText', this.$refs.textareaCenterRef.innerText)
// // console.info('watch value', val)
// // this.$nextTick(() => {
// // this.valueInner = this.getMaxText(val)
// // })
//
// // this.$emit('input', this.valueInner)
// // console.info('watch this.valueInner', this.valueInner)
// if (!this.lock) {
// console.info('watch lock val', val)
// this.valueInner = this.getMaxText(val)
// this.$refs.textareaCenterRef.innerText = this.getMaxText(val)
// }
// }
},
computed: {},
methods: {
// oEmit (event, oldtxt, firstChild, txtAnchorOffset)
oEmit (event) {
if (this.$refs.textareaCenter.innerText.replace(/\n/g, 'n').length >= this.maxlength) {
event.preventDefault()
}
console.info('oEmit', this.$refs.textareaCenter.innerText.replace(/\n/g, 'n').length)
this.$emit('input', this.$refs.textareaCenter.innerText)
},
init () {
let _this
let oldDate
let noteMax = this.maxlength
let oThis = this
// let that = oThis.$refs.textareaCenter.innerText
let content = document.getElementById('textareaCenter')
// 注册中文的输入事件,
let isCN = false
content.addEventListener('compositionstart', function (event) {
oThis.oEmit(event)
console.info('compositionstart')
isCN = true
console.info('kkk3', this.textContent.replace(/\n/g, 'n').length)
// 撤销预输入内容,必须否则会替代末尾字符 if (this.textContent.replace(/\n/g, 'n').length >= noteMax) {
event.preventDefault()
}
})
content.addEventListener('compositionend', function (event) {
oThis.oEmit(event)
console.info('compositionend')
isCN = false
console.info('oldDate', oldDate, 'event.clipboardData.getData(\'Text\').length')
oThis.$refs.textareaCenter.innerText = oThis.$refs.textareaCenter.innerText.slice(, noteMax)
document.getSelection().collapse(_this.firstChild, txtAnchorOffset)
})
// 注册文本输入事件,获取光标的起止偏移数据,如果是非中文以及超出长度的输入,则撤销本次操作
let txtAnchorOffset, txtFocusOffset
content.addEventListener('textInput', function (event) {
oThis.oEmit(event)
console.info('textInput', oThis.innerValue, '11jj', content.textContent)
let _sel = document.getSelection()
txtAnchorOffset = _sel.anchorOffset
txtFocusOffset = _sel.focusOffset console.info('kkk2', this.textContent.replace(/\n/g, 'n').length)
// 必须加上isCN的判断,否则获取不到正确的光标数据
if (!isCN && this.textContent.replace(/\n/g, 'n').length >= noteMax) {
event.preventDefault()
}
})
// 注册粘贴事件,获取粘贴数据的长度
let pastedLength
content.addEventListener('paste', function (event) {
oThis.oEmit(event)
console.info('paste')
if (!event.clipboardData) return
pastedLength = event.clipboardData.getData('Text').length
let txtLength = oThis.$refs.textareaCenter.innerText.replace(/\n/g, 'n').length
if ((pastedLength + txtLength) >= noteMax) {
event.preventDefault()
}
}) // 注册输入事件,对输入的数据进行
content.addEventListener('input', function (event) {
oThis.oEmit(event)
console.info('input')
setTimeout(function () {
oThis.oEmit(event)
console.info('input setTimeout')
// oldDate
if (!isCN) {
_this = content
console.info('kkk1', _this.textContent.replace('\n', '3333333n').length)
if (_this.textContent.replace(/\n/g, 'n').length > noteMax) {
let data = _this.textContent
if (pastedLength > ) {
oldDate = data.slice(, txtAnchorOffset) + data.slice(txtFocusOffset + pastedLength, data.length)
// 粘贴字符串长度置为0,以免影响到下一次判断。
pastedLength =
} else {
oldDate = data.slice(, txtAnchorOffset) + data.slice(txtFocusOffset, data.length)
}
// 再次截取最大长度字符串,防止溢出
_this.textContent = oldDate.slice(, noteMax)
// mThis.$emit('input', _this.textContent)
// oThis.oEmit(event, oldDate.slice(0, noteMax), _this.firstChild, txtAnchorOffset)
oThis.oEmit(event)
console.info('_this.textContent', _this.textContent)
// console.info('mThis', mThis)
// 光标移动到起始偏移位置
document.getSelection().collapse(_this.firstChild, txtAnchorOffset)
}
}
}, )
})
}
// getMaxText (txt) {
// let ret
// if (this.maxlength === 0) {
// ret = txt
// } else {
// if (txt.length > this.maxlength) {
// ret = txt.substr(0, this.maxlength)
// } else {
// ret = txt
// }
// }
// console.info('ret', ret)
// return ret
// },
// textareaCenterInput (item) {
// // this[attr] = api.getStrByteLen(this[attr], length)
// // console.info('textareaCenterInput', item)
// // innerText innerHTML
// // item.target.innerText = this.getMaxText(item.target.innerText)
// this.$emit('input', item.target.innerText)
// } },
created () {},
mounted () {
this.init()
console.info('value', this.value)
}
}
</script>
<style lang="less">
/*.textareaCenterWrap {*/
/*display: table;*/
/*width: 100%;*/
/*}*/
.textareaCenter {
background-color: #CCCCCC;
-webkit-user-modify: read-write-plaintext-only;
user-modify: read-write-plaintext-only;
width: %;
height: %;
margin: ;
/*!*display: inline-block;*!*/
display: table-cell;
text-align: left;
padding: 10px;
/*!*padding-left: 10px;*!*/
vertical-align: middle;
white-space: pre-wrap;
font-size: .14rem;
font-family: "微软雅黑 regular";
&:focus {
outline: #d5e8fc auto 0px !important;
}
} </style>

textareaCenter 未完结 其实就是iview的textarea的从写一遍 需求是光标上下居中的更多相关文章

  1. DIV当textarea使用,在聚焦的时候将光标移动到内容的末尾

    #### DIV当textarea使用,在聚焦的时候将光标移动到内容的末尾 #### <style type="text/css"> .test_box { width ...

  2. 未完结第八节 JBPM流程节点

    1.12个节点介绍 2.Node节点

  3. NOIP刷题建议(未完结)

    1NOIP提高组真题 2NOI部分题目 为什么要写这个? 主要是一个人在硕大的机房里打(wan)代(you)码(xi),没多少时间了,所以打算来总结一下. 这个也是为我接下来冲刺做一个准备. 这个会不 ...

  4. 【Java线程安全】 — 常用数据结构及原理(未完结)

    本文主要记录自己对于多线程安全的学习,先来记几个线程安全模型. 首先最重要的当然是volatile和AQS了: 我们知道,整个java.cuncurrent包的核心就是volatile,CAS加自旋悲 ...

  5. (未完结)“文远知行杯”GDET第十四届竞赛(网络赛共10题,仅整理出6题)

    刚开学没多久就打了一个网络赛,通过这次网络赛我是发现我是真的菜... 放假前校赛的排名让我有些自满,寒假丝毫没有接触ACM,一直沉迷于Steam,这个真的值得好好反省. 虽然现在大一课有点多,在学校也 ...

  6. MySQL查询(未完结)

    MySql查询 单表查询: 查询所有字段 SELECT * FROM 表名; '*' 代表所有字段 查询指定字段 SELECT 字段名1, 字段名2 FROM 表名; 按照指定条件查询记录 1. 查询 ...

  7. java 集合类复习(未完结)

    JAVA常用数据结构及原理分析(面试总结) https://blog.csdn.net/qq_29631809/article/details/72599708 java 中几种常用数据结构   ht ...

  8. #linux 命令使用 cp -未完结版

    下载了sublime 解压之后,想把文件夹放到opt目录,这里用命令cp将其复制过来 johnny@johnny-pc:~$ sudo cp -r ~/下载/Sublime_2.0.2 /opt/ [ ...

  9. [未完结]数字微分分析法的直线绘制(DDA)

    注意! 本文被第1次更新,可能存在后续更新 直线画法 直线的斜截式方程 在二维空间下,一条直线的方程可以被描述为若干种形式,其中比较常见的一种是斜截式方程: \[y=kx+b\] 其中\(k\)称为直 ...

随机推荐

  1. Redis 总结精讲 看一篇成高手系统

    转自:https://blog.csdn.net/hjm4702192/article/details/80518856 本文围绕以下几点进行阐述 1.为什么使用redis2.使用redis有什么缺点 ...

  2. makefile中的变量赋值

    在makefile中赋值方式有:'='.':='.'?='和'+='. A = a $(B) B = b all: echo $(A) #运行结果:echo a b a b 这种赋值方式是没有先后顺序 ...

  3. 反编译.net下的exe程序

    1. 什么叫.net平台 .NET框架是一个多语言组件开发和执行环境,它提供了一个跨语言的统一编程环境..NET框架的目的是便于开发人员更容易地建立Web应用程序和Web服务,使得Internet上的 ...

  4. 关于Synchornized,Lock,AtomicBoolean和volatile的区别介绍

    1.  volatile 变量可以被看作是一种 "程度较轻的 synchronized". 2.  Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的 ...

  5. 吴裕雄--天生自然 R语言开发学习:聚类分析(续一)

    #-------------------------------------------------------# # R in Action (2nd ed): Chapter 16 # # Clu ...

  6. 杂谈php之什么是cgi,fastcgi,fpm,cli,mod

    杂谈PHP极少关注的问题 本话题来自于我使用PHP进行网页爬虫的一次经历.对于一个web开发者来说,PHP解释器本身却知之甚小,实在是惭愧呐! 首先这个话题要从几个提问开始. PHP是什么? 外文名: ...

  7. idea激活教程(永久)支持2019 3.1 亲测

    此教程已支持最新2019.3版本 本教程适用Windows.Mac.Ubuntu等所有平台. 激活前准备工作 配置文件修改已经不在bin目录下直接修改,而是通过Idea修改 如果输入code一直弹出来 ...

  8. XML的相关基础知识分享(二)

    前面我们讲了一下XML相关的基础知识(一),下面我们在加深一下,看一下XML高级方面. 一.命名空间 1.命名冲突 XML命名空间提供避免元素冲突的方法. 命名冲突:在XML中,元素名称是由开发者定义 ...

  9. 并查集(不相交集)的Union操作

    在并查集(不相交集)中附加操作\(Deunion\),它实现的功能是取消最后一次\(Union\)的操作. 实现思想 初始化一个空栈,将每一次的\(Union\)操作的两个集合的根和其值\(Push\ ...

  10. vue——一个页面实现音乐播放器

    请忽略下面这段文字年关将至,时间好歹又多出了些许.却不敢过度消遣.岁月未曾饶过我,我亦不想饶过岁月.且将它塞得膨胀,让这一年看似加更充实.不曾料想我一个爱些风花雪月.研墨行歌之人,却做起了碼农这一行当 ...