前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >useTextSelection vue 文本选择hook

useTextSelection vue 文本选择hook

作者头像
copy_left
发布2020-05-09 16:33:19
7070
发布2020-05-09 16:33:19
举报
文章被收录于专栏:方球方球

文本选择

Uesage

代码语言:javascript
复制
<template>
  <div id="app">
    
    {{ state }}
    <div ref='ele'> 测试文本 </div>
    

  </div>
</template>

<script>
import { useTextSelection } from 'vx-hook'


export default {
  name: 'App',
  setup(){
    const [ state, ele ] = useTextSelection()

    return {
      state,
      ele
    }

  }
  
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

Params

  • initDom 文本选择事件绑定元素 ref

Result

  • state
    • text 被选中文本 string
    • width 选中宽度 number | NaN
    • height 选中高度 number | NaN
    • top 选择框 顶部坐标 number | NaN
    • bottom 选择框 底部坐标 number | NaN
    • left 选择框 左侧坐标 number | NaN
    • right 选择框 右侧坐标 number | NaN
  • element 绑定元素

实现

代码语言:javascript
复制
import { ref, computed, watch, onMounted, onUnmounted } from 'vue'


const initRect = {
    top: NaN,
    left: NaN,
    bottom: NaN,
    right: NaN,
    height: NaN,
    width: NaN,
}

const initState = {
    text: '',
    ...initRect
}

function getInitState(){
    return { ...initState }
}


// 获取选择文本及坐标
function getRectFromSelection(){

    const selection = window.getSelection()
    const text = selection.toString()
    
    if(selection.rangeCount < 1){ return initRect }
    
    const range = selection.getRangeAt(0);
    
    const {
        height,
        width,
        top,
        left,
        right,
        bottom
    } = range.getBoundingClientRect()
    
    return {
        text,
        height,
        width,
        top,
        left,
        right,
        bottom
    }
    
}

const createOnMouseupHandler =  state => () => {    
    if (!window.getSelection) return;
    const data = getRectFromSelection()
    if(data.text){ 
        state.value = data
    }
    
}   


const createOnmousedownHandler = state => () => {

    if (!window.getSelection) return;

    if(state.value.text){
        state.value =  getInitState()
    }
    
    window.getSelection().removeAllRanges()
    
}


/**
 * 文本选择
 * @param { element } intiDom 绑定元素 
 * @returns { array } 
 *  - state
 *      - text 被选中文本
 *      - width 选中宽度
 *      - height 选中高度
 *      - top 选择框 顶部坐标
 *      - bottom 选择框 底部坐标
 *      - left 选择框 左侧坐标
 *      - right 选择框 右侧坐标
 *  - element 绑定元素
 */
export default function useTextSelection(intiDom){
    const element = ref(null)
    const target = computed(() => intiDom&&intiDom.value ? intiDom : element.value )
    const state = ref(getInitState())    

    const onMouseupHandler = createOnMouseupHandler(state)
    const onMousedownHandler = createOnmousedownHandler(state)
    

    watch(() => target.value, (ele, oldEle) =>{

        if(oldEle){
            oldEle.removeEventListener('mouseup', onMouseupHandler)
            oldEle.removeEventListener('mousedown', onMousedownHandler)
        }

        if(ele){
            ele.addEventListener('mouseup', onMouseupHandler)
            ele.addEventListener('mousedown', onMousedownHandler)
        }
    })

    onMounted(() => {
        document.addEventListener('mousedown', onMousedownHandler)
    })

    onUnmounted(() =>{
        document.removeEventListener('mousedown', onMousedownHandler)
    })
    
    return [ state, element ]
    
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Uesage
  • Params
  • Result
  • 实现
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档