• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • 跟我一起使用electron搭建一個文件瀏覽器應用吧(三)

    第二篇博客中我們可以看到我們構建的桌面應用會顯示我們的文件及文件夾。
    In the second blog, we can see that the desktop application we built will display our files and folders.
    但是有一點就是它不能進行點擊查看里面的內容,接下來我們繼續改造我們的項目吧~
    But one thing is that it can't Click to see the contents. Next, let's continue to transform our project.
    第一步重構代碼,將代碼進行邏輯分組
    The first step is to refactor the code and group it logically.

    fileSystem.js
    'use strict';
    
    const async = require('async');
    const fs = require('fs');
    const osenv = require('osenv');
    const path = require('path');
    
    let shell;
    
    if (process.versions.electron) {
      shell = require('electron').shell;
    } else {
      shell = window.require('nw.gui').Shell;
    }
    
    function getUsersHomeFolder() {
      return osenv.home();
    }
    
    function getFilesInFolder(folderPath, cb) {
      fs.readdir(folderPath, cb);
    }
    
    function inspectAndDescribeFile(filePath, cb) {
      let result = { file: path.basename(filePath), path: filePath, type: '' };
      fs.stat(filePath, (err, stat) => {
        if (err) {
          cb(err);
        }       else {
          if (stat.isFile()) {
            result.type = 'file';
          }
          if (stat.isDirectory()) {
            result.type = 'directory';
          }
          cb(err, result);
        }
      });
    }
    
    function inspectAndDescribeFiles(folderPath, files, cb) {
      async.map(files, (file, asyncCb) => {
        let resolvedFilePath = path.resolve(folderPath, file);
        inspectAndDescribeFile(resolvedFilePath, asyncCb);
      }, cb);
    }
    
    function openFile(filePath) {
      shell.openItem(filePath);
    }
    
    module.exports = {
      getUsersHomeFolder,
      getFilesInFolder,
      inspectAndDescribeFiles,
        openFile
    };
    userInterface.js
    'use strict';
    
    let document;
    const fileSystem = require('./fileSystem');
    const search = require('./search');
    const path = require('path');
    
    function displayFolderPath(folderPath) {
      document.getElementById('current-folder')
        .innerHTML = convertFolderPathIntoLinks(folderPath);
      bindCurrentFolderPath();
    }
    
    function clearView() {
      const mainArea = document.getElementById('main-area');
      let firstChild = mainArea.firstChild;
      while (firstChild) {
        mainArea.removeChild(firstChild);
        firstChild = mainArea.firstChild;
      }
    }
    
    function loadDirectory(folderPath) {
      return function (window) {
        if (!document) document = window.document;
            search.resetIndex();
        displayFolderPath(folderPath);
        fileSystem.getFilesInFolder(folderPath, (err, files) => {
          clearView();
          if (err) {
            return alert('Sorry, we could not load your folder');
          }
          fileSystem.inspectAndDescribeFiles(folderPath, files, displayFiles);
        });
      };
    }
    
    function displayFile(file) {
      const mainArea = document.getElementById('main-area');
      const template = document.querySelector('#item-template');
      let clone = document.importNode(template.content, true);
      search.addToIndex(file);
      clone.querySelector('img').src = `images/${file.type}.svg`;
      clone.querySelector('img').setAttribute('data-filePath', file.path);
      if (file.type === 'directory') {
        clone.querySelector('img')
          .addEventListener('dblclick', () => {
            loadDirectory(file.path)();
          }, false);
            } else {
            clone.querySelector('img')
            .addEventListener('dblclick', () => {
            fileSystem.openFile(file.path);
            },
            false);
        }
      clone.querySelector('.filename').innerText = file.file;
      mainArea.appendChild(clone);
    }
    
    
    function displayFiles(err, files) {
      if (err) {
        return alert('Sorry, we could not display your files');
      }
      files.forEach(displayFile);
    }
    
    function bindDocument (window) {
      if (!document) {
        document = window.document;
      }
    }
    
    function bindSearchField(cb) {
      document.getElementById('search').addEventListener('keyup', cb, false);
    }
    
    function filterResults(results) {
      const validFilePaths = results.map((result) => { return result.ref; });
      const items = document.getElementsByClassName('item');
      for (var i = 0; i < items.length; i++) {
        let item = items[i];
        let filePath = item.getElementsByTagName('img')[0]
          .getAttribute('data-filepath');
        if (validFilePaths.indexOf(filePath) !== -1) {
          item.style = null;
        } else {
          item.style = 'display:none;';
        }
      }
    }
    
    function resetFilter() {
      const items = document.getElementsByClassName('item');
      for (var i = 0; i < items.length; i++) {
        items[i].style = null;
      }
    }
    
    function convertFolderPathIntoLinks (folderPath) {
      const folders = folderPath.split(path.sep);
      const contents    = [];
      let pathAtFolder = '';
      folders.forEach((folder) => {
         pathAtFolder += folder + path.sep;
         contents.push(`<span class="path" data-path="${pathAtFolder.slice(0,-1)}">${folder}</span>`);
      });
      return contents.join(path.sep).toString();
    }
    
    function bindCurrentFolderPath() {
      const load = (event) => {
        const folderPath = event.target.getAttribute('data-path');
        loadDirectory(folderPath)();
      };
    
      const paths = document.getElementsByClassName('path');
      for (var i = 0; i < paths.length; i++) {
        paths[i].addEventListener('click', load, false);
      }
    }
    
    module.exports = { bindDocument, displayFiles, loadDirectory, bindSearchField, filterResults, resetFilter };
    app.js
    'use strict';
    
    const fileSystem = require('./fileSystem');
    const userInterface = require('./userInterface');
    const search = require('./search');
    
    function main() {
      userInterface.bindDocument(window);
      let folderPath = fileSystem.getUsersHomeFolder();
      userInterface.loadDirectory(folderPath)(window);
      userInterface.bindSearchField((event) => {
        const query = event.target.value;
        if (query === '') {
          userInterface.resetFilter();
        } else {
          search.find(query, userInterface.filterResults);
        }
      });
    }
    
    window.onload = main;
    app.css
    body {
         padding: 0;
         margin: 0;
         font-family: 'Helvetica','Arial','sans';
    }
    
    #toolbar {
         top: 0px;
         position: fixed;
         background: red;
         width: 100%;
         z-index: 2;
    }
    
    #current-folder {
         float: left;
         color: white;
         background: rgba(0,0,0,0.2);
         padding: 0.5em 1em;
         min-width: 10em;
         border-radius: 0.2em;
         margin: 1em;
    }
    
    #main-area {
         clear: both;
         margin: 2em;
         margin-top: 3em;
         z-index: 1;
    }
    
    .item {
         position: relative;
         float: left;
         padding: 1em;
         margin: 1em;
         width: 6em;
         height: 6em;
         text-align: center;
    }
    
    .item .filename {
         padding-top: 1em;
         font-size: 10pt;
    }
    
    #search {
         float: right;
         padding: 0.5em;
         min-width: 10em;
         border-radius: 3em;
         margin: 2em 1em;
         border: none;
         outline: none;
    }
    
    span.path:hover, img:hover {
         opacity: 0.7;
         cursor: pointer;
    }
    index.html
    <html>
      <head>
        <title>Lorikeet</title>
        <link rel="stylesheet" href="app.css" />
        <script src="app.js"></script>
      </head>
      <body>
        <template id="item-template">
          <div class="item">
            <img class="icon" />
            <div class="filename"></div>
          </div>
        </template>
        <div id="toolbar">
          <div id="current-folder"></div>
                <input type="search" id="search" results="5" placeholder="Search" />
        </div>
        <div id="main-area"></div>
      </body>
    </html>
    search.js
    'use strict';
    
    const lunr = require('lunr');
    let index;
    
    function resetIndex() {
      index = lunr(function () {
        this.field('file');
        this.field('type');
        this.ref('path');
      });
    }
    
    function addToIndex(file) {
      index.add(file);
    }
    
    function find(query, cb) {
      if (!index) {
        resetIndex();
      }
    
      const results = index.search(query);
      cb(results);
    }
    
    module.exports = { addToIndex, find, resetIndex };

    安裝lunr.js他支持對文件夾和文件的搜索
    Install lunr. js, which supports searching for folders and files
    cnpm install lunr --save
    這個lunr的版本號最好為0.7.2,不用最新的。
    The lunr version number is best 0.7.2, not the latest.
    運行項目我們可以看到效果為
    We can see the effect of running the project is as follows
    1037363-20190122185739228-1289190658.png

    本文的例子學習自 <<跨平臺桌面應用開發基于Electron與NW.js>>這本書

    版權聲明:本文為weixin_30379973原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/weixin_30379973/article/details/96555414

    智能推薦

    python網絡圖片下載---跟我一起爬王者農藥皮膚吧

    python網絡圖片下載—跟我一起爬王者農藥皮膚吧 開工前介紹兩句 1.環境:本文代碼是在python 3.6的環境下編譯的,用的是Mac電腦,Windows也可,用python3就可以了 2.工具:本文代碼是在pycharm工具上編寫的,也可以使用其他python編譯器;還需要用到瀏覽器,隨便一個都行,本文用的Mac自帶的Safari瀏覽器。 3.目的:本文適合初學python的人,...

    跟我一起讀《Hadoop權威指南》 第三篇 -- HDFS (Hadoop分布式文件系統)

    HDFS概念 HDFS(Hadoop Distributed FileSystem)是Hadoop旗艦級別文件系統,用來存儲超大文件(從幾百MB到幾百TB級別數據)、流式數據訪問、高延時的以及一次寫入多次讀取的文件系統。 數據塊 HDFS有數據塊(block)的概念,一個塊默認大小是128MB,HDFS中的文件會被分為多個塊,每個塊都是一個獨立的存儲單元,需要注意的是:當一個文件的塊小于數據塊大小...

    跟我一起學python3(一)

    一、學習內容如下: 1、python環境的安裝(windows) 2、輸出語句 print() 3、輸入語句 input() 4、if else語句 語法格式: 5、循環(while)  語法格式: 二、學習過程 1、python環境的安裝 下載地址:https://www.python.org/downloads/windows/ 點擊安裝,注意,勾選下面的選項,不...

    跟我一起寫makefile(一)

    一、關于make和makefile的基本概念和使用: Make: 是一個能自動判斷一個大型程序中哪些源代碼需要重新編譯 的工具 并且根據判斷的結果自動調用編譯器去編譯源代碼 最終按照一定的順序,將編譯結果整合成可執行程序 當項目中的某個文件做過修改,沒有的make的情況下可能要重新編譯整個項目,而make可以自動的判斷哪些需要重新編譯,哪些需要先進行編譯,節省大量時間。 makefile: 可以認...

    跟我一起學習webpack(一)

    跟我一起打包我們的第一個應用 第一步安裝webpack 接下來我們新建文件 項目整個目錄結構如下 接下來我們打包這個項目 使用命令很長很難記 我們會發現多出來dist文件夾 現在我們直接打開瀏覽器運行項目效果為 上面我們提到,打包的命令很難記很難記,現在我們可以使用npm script這個簡化命令的方式去運行 我們修改package.json文件為 scripts是npm提供的腳本命令功能,在這里...

    猜你喜歡

    神奇的Batch Normalization 如果一個模型僅訓練BN層會是什么樣的

    您可能會感到驚訝,但這是有效的。 ? 最近,我閱讀了arXiv平臺上的Jonathan Frankle,David J. Schwab和Ari S. Morcos撰寫的論文“Training BatchNorm and Only BatchNorm: On the Expressive Power of Random Features in CNNs”。 這個主意立刻引起了...

    用Python實現校園通知更新提醒

    前言 這個項目實已經在一個月前已經完成了,一直都想寫一篇博客來總結這個過程中遇到的一些問題。但最近一個月來都比較忙,所以一直拖到了現在。 首先說說起因吧,我沒事的時候,總喜歡依次點開學校主頁、教務處、圖書館以及學院的網站,看看有沒有什么新通知,雖然大多與我無關。恰逢最近正在學Python,經常聽到別人說用Python寫爬蟲很簡單,但自己尚未接觸過爬蟲。于是抱著試一試的心態看了幾篇關于Python爬...

    spring_ioc相關_第一章

    1 spring是一站式框架,在javaee的三層結構中,每一層都提供不提并的解決技術 web層:springMVC service層:spring的ioc dao層:spring的jdbcTemplate 2 javaee為避免兩個類之間出現耦合,則把對象的創建交給spring進行管理,spring的ioc操作:(1)ioc的配置文件方式;(2)ioc注解方式 3 ioc的底層原理使用技術(1)...

    【Python+OpenCV】視頻流局部區域像素值處理-一種特征提取方法

    參考我之前寫的處理圖片的文章:Python+OpenCV實現【圖片】局部區域像素值處理(改進版) 開發環境:Python3.6.0 + OpenCV3.2.0 任務目標:攝像頭采集圖像(例如:480*640),并對視頻流每一幀(灰度圖)特定矩形區域(480*30)像素值進行行求和,得到一個480*1的數組,用這480個數據繪制條形圖,即在逐幀采集視頻流并處理后“實時”顯示采...

    JavaWeb——【前端】——注冊頁面

    頁面效果 實現代碼 注意事項 主要使用的bootstrap樣式 如果想引用,不要直接復制,沒用的。 先介紹下所引用的文件: boostrap的js、bootstrap的css、jquery的js、以及自己編寫的register.css。 因為博主用的thymeleaf語法,所以有th符號。 若要使用時,根據個人情況導入相應的依賴。...

    精品国产乱码久久久久久蜜桃不卡