最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

純JS實現(xiàn)監(jiān)控本地文件變化

 更新時間:2025年04月11日 11:05:44   作者:你不會困  
你是否曾夢想擁有一個能夠?qū)崟r監(jiān)控本地文件變化的網(wǎng)頁應(yīng)用,現(xiàn)在,這個夢想即將成為現(xiàn)實,本文將通過純JS實現(xiàn)這一功能,感興趣的小伙伴可以了解下

網(wǎng)頁端的超級能力:File System Observer API

在最新的Web技術(shù)革命中,我們迎來了一個令人興奮的新API——File System Observer API(文件系統(tǒng)觀察者API)。這不僅僅是一個簡單的文件操作工具,它賦予了網(wǎng)頁應(yīng)用前所未有的能力——實時監(jiān)控本地文件的一舉一動!

實時監(jiān)控,無需刷新

想象一下,你正在開發(fā)一個Web端相冊應(yīng)用,用戶可以隨時添加或刪除圖片。有了File System Observer API,你的應(yīng)用能夠即時響應(yīng)這些變化,無需用戶手動刷新頁面。這就像是給網(wǎng)頁裝上了千里眼和順風(fēng)耳,任何文件的新增、修改或刪除都逃不過它的監(jiān)控。

實現(xiàn)監(jiān)聽,簡單幾步

實現(xiàn)文件監(jiān)聽的步驟簡單到令人難以置信。首先,你需要實例化一個FileSystemObserver對象,并傳入一個回調(diào)函數(shù)。然后,通過showOpenFilePickershowDirectoryPicker選擇要監(jiān)聽的文件或文件夾,并使用observe方法開始監(jiān)聽。

監(jiān)聽文件和文件夾

無論是單個文件還是整個文件夾,F(xiàn)ile System Observer API都能輕松應(yīng)對。你可以選擇監(jiān)聽文件夾的一級內(nèi)容,或者通過設(shè)置recursive: true來監(jiān)聽所有子級內(nèi)容。

操作類型全覆蓋

文件的新建、刪除、修改、移動,甚至是重命名,F(xiàn)ile System Observer API都能準(zhǔn)確捕捉并通知你的應(yīng)用。每個操作都會生成一個詳細(xì)的FileSystemChangeRecord對象,讓你能夠精確地了解發(fā)生了什么。

試一下我們的 Demo,實時進(jìn)行修改,就會觸發(fā)

解除監(jiān)聽,一鍵搞定

當(dāng)你想要停止監(jiān)聽某個文件或文件夾時,只需調(diào)用disconnect方法,一切都會恢復(fù)原狀。

怎么申請token

首先我們訪問 谷歌FSO申請鏈接 并登錄賬號。

FSO 還是一套嶄新的 API,有多新呢?MDN 和 CanIUse 中還沒有建立關(guān)于它的詞條。但這并不意味著我們完全無法用于生產(chǎn)環(huán)境,我已經(jīng)用到線上功能中了。只要做一點配置工作,你和你的用戶就能成為全球第一批享受到 FSO 的人 。

Chrome 已經(jīng)對 FSO 開啟了試用,版本范圍是 129 到 134,你可以為你的 Web App 域名注冊一個試用 token,你可以跟著我一步一步操作

f12打開控制臺輸入FileSystemObserver,如果有返回既是使用成功

那怎么調(diào)用這套API來實現(xiàn)我們監(jiān)聽文件夾的功能?

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>谷歌FSO API</title>
  <style>
    .row-box {
      display: flex;
    }
    .row-box > div {
      width: 50%;
      height: 70vh;
      overflow: auto;
    }
    #log-box {
      background-color: #f0f0f0;
      padding: 10px;
      border: 1px solid #ccc;
      border-radius: 5px;
      display: none;
    }
    .alert-box {
      color: red;
      font-size: 12px;
      line-height: 1;
      margin-bottom: 12px;
      padding: 8px;
      border-radius: 12px;
    }
    .alert-title,.alert-content{
      font-size: 20px;
    }
    #dir-name{
      color: red;
    }
  </style>
</head>
<body>
  <h1>File Observer API 監(jiān)聽文件夾變化</h1>
  <div class="alert-box">
    <div class="alert-title">?? 注意?。?!</div>
    <div class="alert-content">
      <p>本程序不會上傳任何文件到服務(wù)器,切勿使用重要文件進(jìn)行調(diào)試,以免造成數(shù)據(jù)丟失</p>
    </div>
  </div>
  <button id="dir-btn">請選擇一個文件夾進(jìn)行監(jiān)聽</button>
  <p>
    <span id="dir-name"></span>
  </p>
  <div class="row-box">
    <div id="dir-info"></div>
    <div id="log-box"></div>
  </div>
  <script type="importmap">
  {
    "imports": {
      "@rejax/fsot": "https://unpkg.com/@rejax/fsot/index.js"
    }
  }
  </script>
  <script type="module">
    import { setFSObserverToken } from './index.js'
    setFSObserverToken()
  </script>
  <script type="module">
    import { FSObserver } from '@rejax/fsot'

    const dirBtn = document.getElementById('dir-btn')
    const dirInfo = document.getElementById('dir-info')
    const logBox = document.getElementById('log-box')
    const dirName = document.getElementById('dir-name')

    let dirEntries = null
    const fob = new FSObserver(callback)

    const kindMap = {
      'directory': '文件夾',
      'file': '文件',
    }
    const operationMap = {
      'appeared': '新增',
      'disappeared': '刪除',
      'modified': '修改',
      'moved': '移動',
      'renamed': '重命名',
    }
    
    dirBtn.addEventListener('click', handleClick)
    
    async function handleClick() {
      const dirHandle = await window.showDirectoryPicker()
      dirEntries = dirHandle.values()

      const options = {
        recursive: true,
      }
      
      console.log('fob', fob);
      
      await fob.observe(dirHandle, options)
      const localDirName = fob.rootHandle.name
      dirName.innerText=`當(dāng)前監(jiān)聽的本地目錄: ${localDirName}`

      dirBtn.disabled = true
      logBox.style.display = 'block'

      for await (const entry of dirEntries) {
        const { kind, name } = entry
        showChild(kind, name)
      }
    }
    
    async function callback(log, records, observer) {
      console.log('log', log);
      const logEle = document.createElement('p')
      logEle.innerText = log.description
      logBox.appendChild(logEle)

      const { operation, handle, to, from } = log
      switch (operation) {
        case 'create':
          add(handle, to)
          break
        case 'remove':
          remove(handle, to)
          break
        case 'modify':
          modifyFile(handle, to)
          break
        case 'move':
          move(handle, to, from)
          break
        case 'rename':
          rename(handle, to, from)
          break
      }
    }
    function showChild(kind, name) {
      const entryId = `${kind}-${name}`
      const entry = document.createElement('p')
      entry.id = entryId
      entry.innerHTML = `${kindMap[kind]} ${name}`
      dirInfo.appendChild(entry)
    }
    
    async function add(handle, path) {
      const { kind } = handle
      if (!path.includes('/')) {
        // 子文件中增加實體時,不顯示
        showChild(kind, path)
      }
    }

    function remove(handle, path) {
      const { kind, name } = handle
      const childName = path || name
      const entryId = `${kind}-${childName}`
      const entry = document.getElementById(entryId)
      if (entry) {
        entry.remove()
      }
    }

    async function modifyFile(handle, path) {
      
    }

    async function rename(handle, path, oldPath) {
      const { kind, name } = handle
      const childName = path || name
      const entryId = `${kind}-${oldPath}`
      let entry = document.getElementById(entryId)
      if (entry) {
        entry.innerText = `${kindMap[kind]} ${path}`
        entry.id = `${kind}-${path}`
      }
    }

    async function move(handle, path, oldPath) {
      const { kind, name } = handle
      const childName = path || name
      const entryId = `${kind}-${oldPath}`
      let entry = document.getElementById(entryId)
      const pathArr = path.split('/')
      const oldPathArr = oldPath.split('/')
      
      // 文件層級下沉
      if (pathArr.length > oldPathArr.length) {
        entry?.remove()
      }

      // 文件層級上升
      if (pathArr.length < oldPathArr.length && pathArr.length === 1) {
        showChild(kind, name)
      }
    }
  </script>
</body>
</html>

這里是setFSObserverToken,把前面申請到的token進(jìn)行替換即可,這里要配置好域名,域名不一樣會報錯,無法使用

export function setFSObserverToken () {
  let token = 'AvBwEvROC6H+jSr2r1nwgj0G0T8tOs2MnXT9GSFcHVXV2un4GQ/+9Sa2TfWbJGhUbZe5lyF+APSpjovP+NtNEQwAAABWeyJvcmlnaW4iOiJodHRwOi8vMTI3LjAuMC4xOjUzMTA1IiwiZmVhdHVyZSI6IkZpbGVTeXN0ZW1PYnNlcnZlciIsImV4cGlyeSI6MTc0NzE4MDc5OX'
  const origin = window.location.origin
  if (origin.includes('https://rejax.fun')) {
    token = 'AvBwEvROC6H+jSr2r1nwgj0G0T8tOs2MnXT9GSFcHVXV2un4GQ/+9Sa2TfWbJGhUbZe5lyF+APSpjovP+NtNEQwAAABWeyJvcmlnaW4iOiJodHRwOi8vMTI3LjAuMC4xOjUzMTA1IiwiZmVhdHVyZSI6IkZpbGVTeXN0ZW1PYnNlcnZlciIsImV4cGlyeSI6MTc0NzE4MDc5OX'
  }
  const meta = document.createElement('meta')
  meta.httpEquiv = 'origin-trial'
  meta.content = token
  document.head.appendChild(meta)
}

總結(jié)

File System Observer API的引入,不僅僅是對Web開發(fā)者的一次解放,更是對整個Web生態(tài)的巨大推動。它讓W(xué)eb應(yīng)用更加強大,用戶體驗更加流暢?,F(xiàn)在,是時候開始探索這個全新的API,為你的Web應(yīng)用增添超級能力了!

到此這篇關(guān)于純JS實現(xiàn)監(jiān)控本地文件變化的文章就介紹到這了,更多相關(guān)JS監(jiān)控本地文件變化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • js截取字符串的兩種方法及區(qū)別詳解

    js截取字符串的兩種方法及區(qū)別詳解

    本文是對js截取字符串的兩種方法及區(qū)別進(jìn)行了詳細(xì)的介紹,需要的朋友可以過來參考下,希望對大家有所幫助
    2013-11-11
  • JavaScript自動設(shè)置IFrame高度的小例子

    JavaScript自動設(shè)置IFrame高度的小例子

    JavaScript自動設(shè)置IFrame高度的小例子,需要的朋友可以參考一下
    2013-06-06
  • JS按鈕閃爍功能的實現(xiàn)代碼

    JS按鈕閃爍功能的實現(xiàn)代碼

    js按鈕閃爍功能的實現(xiàn)代碼分為html和js兩部分代碼,具體實現(xiàn)代碼大家參考下本文
    2017-07-07
  • JSON.stringify 基礎(chǔ)與進(jìn)階用法完全攻略

    JSON.stringify 基礎(chǔ)與進(jìn)階用法完全攻略

    掌握J(rèn)SON.stringify核心功能,包括數(shù)據(jù)類型支持、嵌套處理、循環(huán)引用檢測、格式化輸出及安全性保障,適用于API傳輸、配置生成等場景,助開發(fā)者高效處理數(shù)據(jù),本文給大家介紹JSON.stringify基礎(chǔ)與進(jìn)階用法完全攻略,感興趣的朋友跟隨小編一起看看吧
    2025-09-09
  • js實現(xiàn)table添加行tr、刪除行tr、清空行tr的簡單實例

    js實現(xiàn)table添加行tr、刪除行tr、清空行tr的簡單實例

    下面小編就為大家?guī)硪黄猨s實現(xiàn)table添加行tr、刪除行tr、清空行tr的簡單實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-10-10
  • JS連連看源碼完美注釋版(推薦)

    JS連連看源碼完美注釋版(推薦)

    連連看最難的部分應(yīng)該是路徑搜索,即鼠標(biāo)點的兩點之間看有無可通的路徑。 看過有人寫的遞歸寫法,心里癢癢,就捉摸了一下,發(fā)現(xiàn)不用遞歸的情況下難度也不大
    2013-12-12
  • 鼠標(biāo)左鍵單擊沖突的問題解決方法(防止冒泡)

    鼠標(biāo)左鍵單擊沖突的問題解決方法(防止冒泡)

    一個頁面實現(xiàn)了兩種右鍵菜單,當(dāng)鼠標(biāo)左鍵單擊空白處時,右鍵菜單并不隱藏,下面為大家解決鼠標(biāo)左鍵單擊沖突的問題
    2014-05-05
  • JS實現(xiàn)移動端整屏滑動的實例代碼

    JS實現(xiàn)移動端整屏滑動的實例代碼

    本文通過實例代碼給大家分享了基于js 實現(xiàn)移動端整屏滑動效果,基本思路是檢測手指滑動方向,獲取手指抬起時的位置,減去手指按下時的位置,得正即為向下滑動了,具體實現(xiàn)代碼大家參考下本文
    2017-11-11
  • ios中視頻的最后一楨問題解決

    ios中視頻的最后一楨問題解決

    這篇文章主要給大家介紹了關(guān)于ios中視頻的最后一楨問題的解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • Canvas?drawImage方法實現(xiàn)圖片壓縮詳解

    Canvas?drawImage方法實現(xiàn)圖片壓縮詳解

    這篇文章主要為大家介紹了Canvas?drawImage方法實現(xiàn)圖片壓縮詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11

最新評論

运城市| 济南市| 广西| 黎川县| 武邑县| 新化县| 平塘县| 昌宁县| 盱眙县| 吴堡县| 蒲城县| 诏安县| 彭泽县| 兴和县| 理塘县| 五台县| 清丰县| 霍山县| 邮箱| 涞水县| 东兴市| 高雄市| 平原县| 黎城县| 青浦区| 湖南省| 石林| 涟水县| 桦南县| 蓬安县| 平昌县| 若尔盖县| 莱州市| 集安市| 张家口市| 长海县| 清水河县| 黄平县| 马关县| 德清县| 五台县|