摘要:不過在細說之前我們先了解一下。這時候就是發揮作用的地方了??梢詫⒁粋€對象轉化為對象。這四個屬性可以定位一段被選中的文字。如上圖,我們知道元素排列是一段一段的,這里的就是指的每個段,就是選中的位置??隙ㄊ沁B續的,這樣我們就可以定位一段完整的。
Range是JavaScript的內置對象,一般來講用到的地方不是很多,主要是一些交互性比較強的場景可能會用到,比如高亮標注,用不到還好說,如果用到了查資料確實也是比較少的, 所以這里總結一下筆記,不會太深入。
需要注意的是這里很多方法都屬于實驗性功能, 所以生產環境使用的使用需要謹慎,具體可以參考MDN。這里不贅述了。
range的應用場景這類相對比較生僻的api應用常見并不是很多, 這里我們先了解一下range的應用場景.
就是常見的高亮標注電子書之類的
人工標注機器學習所需的基礎文檔(我所做的)
當然應該也有很多其他場景, 我也沒怎么接觸. 有興趣的可以自行了解
Range是什么顧名思義,Range其實可以認為是一個選中的文字范圍, 但是Range又不依賴于鼠標選中, 我們可以自行構造或者克隆。不過在細說Range之前我們先了解一下Selection。
如圖當我們選中一段文字時, 我們就以通過window.getSelection來獲取Selection對象
Selection可以window.getSelection().toString()直接獲取選中的文字, 但是很多時候我們并不是要獲取選中的文字,而是要得到選中文字所在位置并將其存儲起來。這時候就是Range發揮作用的地方了。
window.getSelection().getRangeAt(0)可以將一個Selection對象轉化為Range對象。
我們需要關注的東西是startContainer,endContainer, startOffset,endOffset。這四個屬性可以定位一段被選中的文字。
如上圖,我們知道Dom元素排列是一段一段的, 這里的container就是指的每個段,offset就是選中的位置。Range肯定是連續的,這樣我們就可以定位一段完整的Range。
Range的存儲如果作為高亮, Range必然是要存到服務器上的, 但是作為js對象, Range不可以直接存到數據庫里,這時候就要對Range進行一定的處理了。
上面提到過Range是可以手動創建的:document.createRange:
var range = document.createRange(); range.setStart(startNode, startOffset); range.setEnd(endNode, endOffset);
這里startNode指startContainer, 自然就是指dom元素了,看到這里其實大家心里也該有點方案了,不好存儲的無非就是dom元素了,那我們將dom元素轉為選擇器存起來就好了, 到時再通過選擇器獲取dom元素。
當然我們也有其他選擇: xpath, 主要是我接手項目的時候就是利用的xpath, 將dom轉為xpath的代碼如下:
// 獲取一個元素的xpath function getElementXPath (element) { if (!element) return null if (element.id) { return `//*[@id=${element.id}]` } else if (element.tagName === "BODY") { return "/html/body" } else { const sameTagSiblings = Array.from(element.parentNode.childNodes) .filter(e => e.nodeName === element.nodeName) const idx = sameTagSiblings.indexOf(element) return getElementXPath(element.parentNode) + "/" + element.tagName.toLowerCase() + (sameTagSiblings.length > 1 ? `[${idx + 1}]` : "") } }
將xpath轉化為Range:
function createRangeFromXPathRange (xpathRange) { var startContainer, endContainer, endOffset, evaluator = new XPathEvaluator() // must have legal start and end container nodes startContainer = evaluator.evaluate( xpathRange.startContainerPath, document.documentElement, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ) if (!startContainer.singleNodeValue) { return null } if (xpathRange.collapsed || !xpathRange.endContainerPath) { endContainer = startContainer endOffset = xpathRange.startOffset } else { endContainer = evaluator.evaluate( xpathRange.endContainerPath, document.documentElement, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ) if (!endContainer.singleNodeValue) { return null } endOffset = xpathRange.endOffset } // map to range object var range = document.createRange() range.setStart(startContainer.singleNodeValue, xpathRange.startOffset) range.setEnd(endContainer.singleNodeValue, endOffset) return range }總結
這篇文章筆記不會介紹太多api或者太過深入, 但是用法思路是一定的。共勉。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/107907.html
摘要:其工作原理我已經在第一篇做了大部分的闡述我尚未提及的是在創建新對象的時候,會賦予新對象一個屬性指向構造器的屬性。 第四篇拖了很久了,真是有點不好意思。實話實說,拖延很久的原因主要是沒想好怎么寫,因為這一篇的主題比較有挑戰性:原型和基于原型的繼承——啊~我終于說出口了,這下沒借口拖延了== 原型 我(個人)不喜歡的,就是講原型時上來就拿類做比較的,所以我不會這樣講。不過我的確講過構造器函...
摘要:大多數情況下,對一個直接量和一個局部變量數據訪問的性能差異是微不足道的。 前端性能優化之 JavaScript 前言 本文為 《高性能 JavaScript》 讀書筆記,是利用中午休息時間、下班時間以及周末整理出來的,此書雖有點老舊,但談論的性能優化話題是每位同學必須理解和掌握的,業務響應速度直接影響用戶體驗。 一、加載和運行 大多數瀏覽器使用單進程處理 UI 更新和 JavaScri...
摘要:使用要點同源限制分配給線程運行的腳本文件,必須與主線程的腳本文件同源。限制線程所在的全局對象,與主線程不一樣,無法讀取主線程所在網頁的對象,也無法使用這些對象。通信聯系線程和主線程不在同一個上下文環境,它們不能直接通信,必須通過消息完成。 介紹 Web Worker為Web內容在后臺線程中運行腳本提供了一種簡單的方法。線程可以執行任務而不干擾用戶界面。此外,他們可以使用XMLHttpR...
摘要:線上另加入了排行榜功能,如需查看源碼的,請切換到分支整個項目結構清晰,尤其單文件組件的表現力尤為突出,使得每個組件的邏輯都沒有過于復雜,而且在的統籌下,的單向數據流模式使得所有的變化都在可控制可預期的范圍內。 2016注定不是個平凡年,無論是中秋節問世的angular2,還是全面走向穩定的React,都免不了面對另一個競爭對手vue2。喜歡vue在設計思路上的先進性(原諒我用了這么一個...
摘要:最近在自學,無意看到群友一道比較有趣的問題,故嘗試給出答案。目前給出的版本是最簡單的情況,沒有考慮比較牌大小中出現數字或者字母重復的情況,以后有時間或許會給出更精細的版本。編寫程序,進行撲克牌大小比較。 最近在自學Python,無意看到群友一道比較有趣的問題,故嘗試給出答案。目前給出的版本是...
閱讀 1263·2021-11-23 09:51
閱讀 2638·2021-09-03 10:47
閱讀 2234·2019-08-30 15:53
閱讀 2414·2019-08-30 15:44
閱讀 1375·2019-08-30 15:44
閱讀 1194·2019-08-30 10:57
閱讀 1924·2019-08-29 12:25
閱讀 1087·2019-08-26 11:57