f***@163.com
f***@163.com
  • 发布:2025-07-01 15:14
  • 更新:2025-07-01 15:41
  • 阅读:41

在uniapp 移动端,在文本中,选择字符串,并可以调整选择的范围

分类:uni-app

在uniapp 移动端中,一长串字符串显示,手指选中其中一部分字符串,选中部分高亮显示,并可以调整选择的范围,针对选择的范围发起事件

2025-07-01 15:14 负责人:无 分享
已邀请:
DCloud_UNI_JBB
  • f***@163.com (作者)

    你好,我看您回答的是鼠标拖动,我的场景是在移动端,text、rich-text的selectable属性,手指接触不生效

    2025-07-01 15:32

  • DCloud_UNI_JBB

    回复 f***@163.com: 麻烦发个可复现demo

    2025-07-01 15:33

  • f***@163.com (作者)

    回复 DCloud_UNI_JBB:

    <template>

    <view class="container">

    <view>

    <text :selectable="true">{{content}}</text>

    </view>


    <view v-if="showToolbar" class="toolbar" :style="toolbarStyle">  
    <button @click="highlightSelection">高亮</button>
    <button @click="showNoteDialog">添加批注</button>
    </view>

    <uni-popup ref="noteDialog" type="dialog">
    <view class="note-dialog">
    <view class="selected-text">{{ selectedText }}</view>
    <textarea v-model="noteContent" placeholder="输入批注内容"></textarea>
    <button @click="addNote">保存批注</button>
    </view>
    </uni-popup>

    </view>

    </template>


    <script setup>

    import { ref } from 'vue'


    const content = "这里是一大段只读的富文本内容...222222</div>"

    const editorCtx = ref(null)

    const selectedText = ref('')

    const selectionRange = ref(null)

    const showToolbar = ref(false)

    const toolbarStyle = ref({})

    const noteContent = ref('')

    const noteDialog = ref(null)

    const notes = ref([])


    const onEditorReady = () => {

    uni.createSelectorQuery().select('#editor').context((res) => {

    editorCtx.value = res.context

    }).exec()

    }


    const onSelectionChange = (e) => {

    if (e.detail.text) {

    selectedText.value = e.detail.text

    selectionRange.value = e.detail.range

    showToolbar.value = true

    toolbarStyle.value = {

    top: ${e.detail.top + e.detail.height + 10}px,

    left: ${e.detail.left}px

    }

    } else {

    showToolbar.value = false

    }

    }


    const highlightSelection = async () => {

    if (!selectionRange.value) return

    await editorCtx.value.format('backgroundColor', '#FFFF00')

    notes.value.push({

    text: selectedText.value,

    range: selectionRange.value,

    color: '#FFFF00'

    })

    }


    const showNoteDialog = () => {

    noteDialog.value.open()

    }


    const addNote = async () => {

    if (!noteContent.value.trim()) return

    await highlightSelection()

    notes.value[notes.value.length - 1].content = noteContent.value

    noteContent.value = ''

    noteDialog.value.close()

    }

    </script>


    <style>

    .container {

    padding: 20px;

    }

    .editor {

    height: 400px;

    background-color: #fff;

    border: 1px solid #eee;

    padding: 10px;

    -webkit-user-select: text;

    -moz-user-select: text;

    -ms-user-select: text;

    user-select: text;

    }

    .toolbar {

    position: fixed;

    display: flex;

    gap: 10px;

    background-color: #fff;

    padding: 8px;

    border-radius: 5px;

    box-shadow: 0 2px 10px rgba(0,0,0,0.2);

    z-index: 100;

    }

    .note-dialog {

    padding: 20px;

    width: 80vw;

    }

    .selected-text {

    margin-bottom: 15px;

    padding: 10px;

    background-color: #f5f5f5;

    border-radius: 4px;

    }

    textarea {

    width: 100%;

    height: 120px;

    margin-bottom: 15px;

    border: 1px solid #ddd;

    padding: 10px;

    border-radius: 4px;

    }

    button {

    padding: 8px 16px;

    }

    </style>

    2025-07-01 15:42

  • DCloud_UNI_JBB

    回复 f***@163.com: 这个代码我运行直接报错,你发个完整的工程吧,记得脱敏和精简。

    2025-07-01 16:00

要回复问题请先登录注册