摘要:不過在細(xì)說之前我們先了解一下。這時(shí)候就是發(fā)揮作用的地方了??梢詫⒁粋€(gè)對象轉(zhuǎn)化為對象。這四個(gè)屬性可以定位一段被選中的文字。如上圖,我們知道元素排列是一段一段的,這里的就是指的每個(gè)段,就是選中的位置??隙ㄊ沁B續(xù)的,這樣我們就可以定位一段完整的。
Range是JavaScript的內(nèi)置對象,一般來講用到的地方不是很多,主要是一些交互性比較強(qiáng)的場景可能會(huì)用到,比如高亮標(biāo)注,用不到還好說,如果用到了查資料確實(shí)也是比較少的, 所以這里總結(jié)一下筆記,不會(huì)太深入。
需要注意的是這里很多方法都屬于實(shí)驗(yàn)性功能, 所以生產(chǎn)環(huán)境使用的使用需要謹(jǐn)慎,具體可以參考MDN。這里不贅述了。
range的應(yīng)用場景這類相對比較生僻的api應(yīng)用常見并不是很多, 這里我們先了解一下range的應(yīng)用場景.
就是常見的高亮標(biāo)注電子書之類的
人工標(biāo)注機(jī)器學(xué)習(xí)所需的基礎(chǔ)文檔(我所做的)
當(dāng)然應(yīng)該也有很多其他場景, 我也沒怎么接觸. 有興趣的可以自行了解
Range是什么顧名思義,Range其實(shí)可以認(rèn)為是一個(gè)選中的文字范圍, 但是Range又不依賴于鼠標(biāo)選中, 我們可以自行構(gòu)造或者克隆。不過在細(xì)說Range之前我們先了解一下Selection。
如圖當(dāng)我們選中一段文字時(shí), 我們就以通過window.getSelection來獲取Selection對象
Selection可以window.getSelection().toString()直接獲取選中的文字, 但是很多時(shí)候我們并不是要獲取選中的文字,而是要得到選中文字所在位置并將其存儲(chǔ)起來。這時(shí)候就是Range發(fā)揮作用的地方了。
window.getSelection().getRangeAt(0)可以將一個(gè)Selection對象轉(zhuǎn)化為Range對象。
我們需要關(guān)注的東西是startContainer,endContainer, startOffset,endOffset。這四個(gè)屬性可以定位一段被選中的文字。
如上圖,我們知道Dom元素排列是一段一段的, 這里的container就是指的每個(gè)段,offset就是選中的位置。Range肯定是連續(xù)的,這樣我們就可以定位一段完整的Range。
Range的存儲(chǔ)如果作為高亮, Range必然是要存到服務(wù)器上的, 但是作為js對象, Range不可以直接存到數(shù)據(jù)庫里,這時(shí)候就要對Range進(jìn)行一定的處理了。
上面提到過Range是可以手動(dòng)創(chuàng)建的:document.createRange:
var range = document.createRange(); range.setStart(startNode, startOffset); range.setEnd(endNode, endOffset);
這里startNode指startContainer, 自然就是指dom元素了,看到這里其實(shí)大家心里也該有點(diǎn)方案了,不好存儲(chǔ)的無非就是dom元素了,那我們將dom元素轉(zhuǎn)為選擇器存起來就好了, 到時(shí)再通過選擇器獲取dom元素。
當(dāng)然我們也有其他選擇: xpath, 主要是我接手項(xiàng)目的時(shí)候就是利用的xpath, 將dom轉(zhuǎn)為xpath的代碼如下:
// 獲取一個(gè)元素的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轉(zhuǎn)化為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 }總結(jié)
這篇文章筆記不會(huì)介紹太多api或者太過深入, 但是用法思路是一定的。共勉。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/107907.html
摘要:其工作原理我已經(jīng)在第一篇做了大部分的闡述我尚未提及的是在創(chuàng)建新對象的時(shí)候,會(huì)賦予新對象一個(gè)屬性指向構(gòu)造器的屬性。 第四篇拖了很久了,真是有點(diǎn)不好意思。實(shí)話實(shí)說,拖延很久的原因主要是沒想好怎么寫,因?yàn)檫@一篇的主題比較有挑戰(zhàn)性:原型和基于原型的繼承——啊~我終于說出口了,這下沒借口拖延了== 原型 我(個(gè)人)不喜歡的,就是講原型時(shí)上來就拿類做比較的,所以我不會(huì)這樣講。不過我的確講過構(gòu)造器函...
摘要:大多數(shù)情況下,對一個(gè)直接量和一個(gè)局部變量數(shù)據(jù)訪問的性能差異是微不足道的。 前端性能優(yōu)化之 JavaScript 前言 本文為 《高性能 JavaScript》 讀書筆記,是利用中午休息時(shí)間、下班時(shí)間以及周末整理出來的,此書雖有點(diǎn)老舊,但談?wù)摰男阅軆?yōu)化話題是每位同學(xué)必須理解和掌握的,業(yè)務(wù)響應(yīng)速度直接影響用戶體驗(yàn)。 一、加載和運(yùn)行 大多數(shù)瀏覽器使用單進(jìn)程處理 UI 更新和 JavaScri...
摘要:使用要點(diǎn)同源限制分配給線程運(yùn)行的腳本文件,必須與主線程的腳本文件同源。限制線程所在的全局對象,與主線程不一樣,無法讀取主線程所在網(wǎng)頁的對象,也無法使用這些對象。通信聯(lián)系線程和主線程不在同一個(gè)上下文環(huán)境,它們不能直接通信,必須通過消息完成。 介紹 Web Worker為Web內(nèi)容在后臺(tái)線程中運(yùn)行腳本提供了一種簡單的方法。線程可以執(zhí)行任務(wù)而不干擾用戶界面。此外,他們可以使用XMLHttpR...
摘要:線上另加入了排行榜功能,如需查看源碼的,請切換到分支整個(gè)項(xiàng)目結(jié)構(gòu)清晰,尤其單文件組件的表現(xiàn)力尤為突出,使得每個(gè)組件的邏輯都沒有過于復(fù)雜,而且在的統(tǒng)籌下,的單向數(shù)據(jù)流模式使得所有的變化都在可控制可預(yù)期的范圍內(nèi)。 2016注定不是個(gè)平凡年,無論是中秋節(jié)問世的angular2,還是全面走向穩(wěn)定的React,都免不了面對另一個(gè)競爭對手vue2。喜歡vue在設(shè)計(jì)思路上的先進(jìn)性(原諒我用了這么一個(gè)...
摘要:最近在自學(xué),無意看到群友一道比較有趣的問題,故嘗試給出答案。目前給出的版本是最簡單的情況,沒有考慮比較牌大小中出現(xiàn)數(shù)字或者字母重復(fù)的情況,以后有時(shí)間或許會(huì)給出更精細(xì)的版本。編寫程序,進(jìn)行撲克牌大小比較。 最近在自學(xué)Python,無意看到群友一道比較有趣的問題,故嘗試給出答案。目前給出的版本是...
閱讀 1350·2021-11-23 09:51
閱讀 2728·2021-09-03 10:47
閱讀 2313·2019-08-30 15:53
閱讀 2518·2019-08-30 15:44
閱讀 1439·2019-08-30 15:44
閱讀 1271·2019-08-30 10:57
閱讀 2008·2019-08-29 12:25
閱讀 1151·2019-08-26 11:57