亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

我可以使用什么來使用多個文本節點可靠地獲取 Javascript 中單擊的字符偏移量?

我可以使用什么來使用多個文本節點可靠地獲取 Javascript 中單擊的字符偏移量?

GCT1015 2023-11-02 21:27:07
當用戶單擊某些文本時,我使用Window.getSelection獲取用戶單擊位置的字符偏移量。當只有一個文本節點時,這非常有效,并且關于如何做到這一點有很多很好的答案。但是,當我有兩個或多個文本節點彼此相鄰呈現時,我遇到了問題。這是一個復制問題的小提琴,但我將在這里介紹它:用例:我正在構建一個文本編輯器,并使用對用戶按鍵做出反應的 Javascript 控制 DOM,而不是使用 contentEditable 容器。我想跟蹤(并顯示)用戶的“光標”在文本中的位置(即,如果他們開始輸入,將輸入文本的位置),并讓他們單擊文本中的任意位置以手動設置光標到他們點擊的地方。HTML:<p class="sentence">  <span class="word" index="0">There </span><span class="word" index="1">is </span><span class="word" index="2">a </span><span class="word" index="3">big, </span><span class="word" index="4">wonderful </span><span class="word" index="5">world.</span></p>JavaScript:$('.word').click(function() {  let word_index = $(this).attr('index');    let selection  = window.getSelection();  let char_index = selection.focusOffset;  console.log('Clicked to set a new cursor @');  console.log('Word index = ' + word_index.toString() +              ' / char index = ' + char_index.toString() );});簡而言之,此代碼打印 aword index和 acharacter index表示光標在文本中的位置,就好像它是可編輯輸入一樣。如果你點擊“There”中“T”的左半部分,它會打印Clicked to set a new cursor @Word index = 0/ char index = 0單擊“T”的右側(這樣光標將放置在其之后但“h”之前)將打印相同的單詞索引,但字符索引為 1,因為光標現在放置在一個字符上,等等。這也很有效......除了單擊任何單詞(第一個除外)的第一個字符的左半部分。單擊“is”中“i”的左半部分(在單詞索引 1、字符索引 0 處設置插入符號)會打印單詞索引 1(正確)和字符索引 6(前一個單詞的長度)。當存在多個彼此相鄰的文本節點時Window.getSelection(或更具體地說, )不是計算這種字符偏移量的正確方法嗎?selection.focusOffset我需要使用其他庫或方法嗎?解決該問題的一個“解決方案”是在每個單詞周圍應用邊距,以在它們之間放置不可點擊的間隙。在這種情況下,單擊“i”的左半部分會給出正確的單詞/字符索引(1,0 而不是 1,6),但會產生空格的副作用,如果用戶不小心單擊那里,則不會發生任何情況(此應用程序中存在嚴重的副作用,因此它并不是真正可行的“修復”)??雌饋碇辽?3px 的邊距總是返回正確的值,而 2px 或更小的邊距總是返回錯誤的值。我正在 Chrome 中進行測試,因為我最終將構建一個 Electron 應用程序,所以我想我只需要它在 Blink 中工作,但如果解決方案對于 Web 版本也與瀏覽器無關,那就太好了。
查看完整描述

2 回答

?
瀟瀟雨雨

TA貢獻1833條經驗 獲得超4個贊

我能夠通過實施以下兩個額外的護欄來實現此目的:

https://img1.sycdn.imooc.com/6543a3d200014c7b04290373.jpg

要使其跨瀏覽器,還有更多工作要做,但這里有一個更新的小提琴,它使用這些調整來獲取 Chrome 中所需的值。



查看完整回答
反對 回復 2023-11-02
?
子衿沉夜

TA貢獻1828條經驗 獲得超3個贊

默認行為取決于瀏覽器,因此您需要進行一些檢查才能給出一致的結果。

這是一個簡單的示例,它將event.target元素與parentElement返回的文本節點的進行比較selection.focusNode,如果不匹配,它會檢查焦點節點的兄弟節點是否匹配并相應地調整偏移量。

您需要使其更加穩健。您還需要處理方向性(從左到右選擇會產生反向焦點,并且選擇從右到左的錨節點)。您也可以看看Selection.containsNode()

function handleSelection(e) {

? const selection = window.getSelection();

??

? const fNode = selection.focusNode;

??

? const fElement = fNode.parentElement;

? const tElement = e.target;

??

? let word_index = tElement.dataset.index;

? let char_index = selection.focusOffset;

??

? if (!fElement.isEqualNode(tElement)?

? ? && fElement.nextElementSibling.isEqualNode(tElement)) {

? ? char_index=0;

? }

??

? console.log(

? ? 'fNode: ', fNode.parentElement.innerText,

? ? ' tNode: ', tElement.innerText,

? ? ' char: ', char_index,

? ? ' word: ', word_index

? );


}


const words = document.querySelectorAll('.word');

words.forEach((w, i) => (

? w.dataset.index = i+1,?

? w.addEventListener('click', handleSelection)));

.word {

? border: 1px solid gray;

? font-size: 2rem;

}

<p class="sentence">

? <span class="word">Hello </span><span class="word">wonderful</span><span class="word"> world.</span>

</p>


查看完整回答
反對 回復 2023-11-02
  • 2 回答
  • 0 關注
  • 165 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號