亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

JavaScript之Range--或許會(huì)有點(diǎn)用

stonezhu / 1150人閱讀

摘要:不過在細(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

相關(guān)文章

  • 理解 JavaScript(四)

    摘要:其工作原理我已經(jīng)在第一篇做了大部分的闡述我尚未提及的是在創(chuàng)建新對象的時(shí)候,會(huì)賦予新對象一個(gè)屬性指向構(gòu)造器的屬性。 第四篇拖了很久了,真是有點(diǎn)不好意思。實(shí)話實(shí)說,拖延很久的原因主要是沒想好怎么寫,因?yàn)檫@一篇的主題比較有挑戰(zhàn)性:原型和基于原型的繼承——啊~我終于說出口了,這下沒借口拖延了== 原型 我(個(gè)人)不喜歡的,就是講原型時(shí)上來就拿類做比較的,所以我不會(huì)這樣講。不過我的確講過構(gòu)造器函...

    cuieney 評論0 收藏0
  • 前端性能優(yōu)化 JavaScript

    摘要:大多數(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...

    Coding01 評論0 收藏0
  • JavaScriptWeb Worker

    摘要:使用要點(diǎn)同源限制分配給線程運(yùn)行的腳本文件,必須與主線程的腳本文件同源。限制線程所在的全局對象,與主線程不一樣,無法讀取主線程所在網(wǎng)頁的對象,也無法使用這些對象。通信聯(lián)系線程和主線程不在同一個(gè)上下文環(huán)境,它們不能直接通信,必須通過消息完成。 介紹 Web Worker為Web內(nèi)容在后臺(tái)線程中運(yùn)行腳本提供了一種簡單的方法。線程可以執(zhí)行任務(wù)而不干擾用戶界面。此外,他們可以使用XMLHttpR...

    BigNerdCoding 評論0 收藏0
  • 單文件組件下的vue,可以擦出怎樣的火花

    摘要:線上另加入了排行榜功能,如需查看源碼的,請切換到分支整個(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è)...

    Keven 評論0 收藏0
  • 趣味Python題目10月8日

    摘要:最近在自學(xué),無意看到群友一道比較有趣的問題,故嘗試給出答案。目前給出的版本是最簡單的情況,沒有考慮比較牌大小中出現(xiàn)數(shù)字或者字母重復(fù)的情況,以后有時(shí)間或許會(huì)給出更精細(xì)的版本。編寫程序,進(jìn)行撲克牌大小比較。 最近在自學(xué)Python,無意看到群友一道比較有趣的問題,故嘗試給出答案。目前給出的版本是...

    Mertens 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<