div使用contenteditable兼容问题

2018-12-27  本文已影响103人  halapro_liu

1、div可以使用contenteditable模拟input框
在vue中,可以使用v-model实现组件的双向绑定,组件中使用v-html显示值
2、可以给div添加tabindex,使div支持focus和blur事件
3、可以使用css3实现placeholder

 /* 当div为空时,显示data-placeholder的值*/
.input-text-placeholder:empty:before {
  content: attr(data-placeholder);
  color: #cacaca;
}

4、ios无法输入问题
可以使用-webkit-user-select: text;解决

.ios-user-select {
  -webkit-user-select: text;
}

5、在使用了input事件后,光标位置显示不正常问题

<div
  ref="input"
  :name="attr"
  contenteditable="true"
  tabindex="1"
  class="input-text ios-user-select input-text-placeholder"
  v-html="currentValue"
  :data-placeholder="placeholder"
  @blur="checkInput"
  @input="edit">
</div>
// 监听中文输入
mounted () {
  // 监听中文输入
  const el = this.$refs.input
  el.addEventListener('compositionstart', this.onCompositionstart, false)
  el.addEventListener('compositionend', this.onCompositionend, false)
},
methods: {
  onCompositionstart (e) {
    this.isLock = true
  },
  onCompositionend (e) {
    this.isLock = false
  },
  edit (e) {
    // 解决中文输入的时候,直接输出英文字母的问题(中文输入期间,不允许输入字符)
    setTimeout(() => {
      if (this.isLock) return
      let value = e.target.innerHTML
      // 去除换行符
      value = value.replace(/(\<\/?\w*\>)/g, '').replace(/(\r\n)|(\n)/g, '')
      this.$emit('input', {
        attr: this.attr,
        value: value
      })
    }, 0)
    // 如果是pc的话,timeout设置为5就好,ios经测试,使用40才有效果
    const timeout = 40
    setTimeout(() => {
      this.getCursor(e.target)
    }, timeout)
  },
  // 解决光标定位问题
  getCursor (el) {
    if (window.getSelection) {
      el.focus()
      const sel = getSelection()
      sel.selectAllChildren(el)
      sel.collapseToEnd()
    } else if (document.selection) {
      var range = document.selection.createRange()// 创建选择对象
      range.moveToElementText(el)// range定位到el
      range.collapse(false)// 光标移至最后
      range.select()
    }
  }
},
beforeDestroy () {
  // 清除监听中文输入
  const el = this.$refs.input
  el.removeEventListener('compositionstart', this.onCompositionstart, false)
  el.removeEventListener('compositionend', this.onCompositionend, false)
}
上一篇下一篇

猜你喜欢

热点阅读