摘要:借助預加載圖片詳情文檔地址項目中為了確保頁面顯示時,圖片已經全部加載完畢,因此需要提前加載圖片,加載圖片的過程使用進度條顯示。第二個參數表示是否搜索其子目錄。并在同元素或父級添加了時,元素顯示。
1. 借助require.context預加載圖片
詳情文檔地址
項目中為了確保頁面顯示時,圖片已經全部加載完畢,因此需要提前加載圖片,加載圖片的過程使用進度條顯示。
在webpack構建的項目中,可以使用require.context來獲取到靜態資源的地址。語法如下:
require.context(directory, useSubdirectories = false, regExp = /^.//)
第一個參數表示要搜索的文件夾目錄,該目錄支持相對路徑與在配置文件中定義的路徑別名。
第二個參數表示是否搜索其子目錄。
第三個參數是一個用來匹配文件的正則表達式。
require.context("modules/App", true, /.(png|jpg|jpeg|gif)$/); // 創建一個包含App目錄下所有圖片的上下文模塊
可以使用該上下文模塊自帶的keys方法得到路徑組成的數組。
const images = require.context("modules/App/", true, /.(png|jpeg|jpg|gif)$/); console.log(images.keys());
效果大概如下圖所示。
得到圖片路徑之后,就可以借助Promise.all來完成圖片預加載,確保圖片加載完成之后再渲染頁面。
Promise.all(images.keys().map(path => { const image = new Image(); image.src = path; image.onload = image.onerror = () => { resolve(); } }))
但是在開發中遇到一個問題,本地頁面引用的圖片是編譯過后的圖片地址,并不是相對路徑,因此如果直接這樣的話會因此地址不一致而報錯。
解決辦法是在設置image對象src屬性時,修改如下:
image.src = images(path); // images 是由require.context 創建的上下文模塊
打印出images(path)之后的圖片路徑如下:
上面的修復方式可以使用如下的知識點來理解。
const ctx = require.context("modules/App", true, /*.js/); const table = ctx("./table.js"); // 上面的代碼等價于 const table = require("modules/App/table.js"); // 使用require引入模塊
參考文檔
當還需要從服務端提前加載其他資源時,可以使用數組的concat方法一起放入Promise.all中。
Promise.all(images.keys().map( // ... ).concat(http.get("/api/v1/summary")))2. 細節優化
整個頁面的顯示,一共有15頁構成,由于每一頁的邏輯與效果都有不少差異,因此將每一頁定義為了一個組件,最初在引入這些模塊時很糟糕的這樣做:
import Page00 from "./Page00"; import Page01 from "./Page01"; import Page02 from "./Page02"; import Page03 from "./Page03"; import Page04 from "./Page04"; import Page05 from "./Page05"; import Page06 from "./Page06"; import Page07 from "./Page07"; import Page08 from "./Page08"; import Page09 from "./Page09"; import Page10 from "./Page10"; import Page11 from "./Page11"; import Page12 from "./Page12"; import Page13 from "./Page13"; import Page14 from "./Page14"; // render里也很復雜 // ... render() { return () } ...
當組件更多時,這樣的引入方式自然是不合理的,可以使用循環的方式來引入代碼,優化如下:
const allPages = []; for(let i = 0; i < 15; i++) { const id = `0${i}`.slice(-2); allPages.push(require(`./Page${id}`).default) }
這樣就將所有的Page組件放在了allPages數組中。
render里也可以使用map來渲染。
render() { return (3. 使用高階組件處理公共邏輯{allPages.map(({ id, Component: Page }) =>) })}
每一個Page組件中,都有共同的元素或邏輯,包括logo,分享當前屏幕截圖按鈕,統計邏輯,判斷對應頁面是否顯示等。可以將這些共用邏輯使用高階組件來處理以簡化代碼。
因此定義了withBox組件來處理它們。
import React from "react"; import logo from "./images/logo.png"; import { sendEvent } from "utils/track"; import share from "./share"; export default function(Wrapped, checkProp) { return class NewPage extends React.Component { shareScreen = () => { const id = this.refs.box.getAttribute("data-page-id"); this.refs.box.classList.add("will-screenshot"); setTimeout(() => share.shareScreenshot(), 100); setTimeout(() => this.refs.box.classList.remove("will-screenshot"), 1500); sendEvent("share-click", "page" + id); sendEvent("click", "share-btn"); }; render() { const { id, className, ...props } = this.props; const cls = className ? `page${id} ${className}` : `page${id}`; if (!checkProp || (props.info[checkProp] !== null && props.info[checkProp] !== "undefined")) { return (4. 通過添加/刪除元素的方式統一控制動畫); } return null; } }; }
首先定義一個class如下,將會參與動畫的元素(或其父級)都添加該class以隱藏。
.aninode { visibility: hidden; }
并在同元素(或父級)添加了animated時,元素顯示。
.animated { &.aninode, .aninode { visibility: visible; } }
并在運動元素的class中添加了animated時,運動生效,因此定義運動css時,應該這樣做:
.animated { &.flyTopIn, .flyTopIn { animation-name: flyTopIn; animation-duration: 1s; } /* more */ }
因此,運動元素在運動開始之前,應該保持這樣
需要運動時,在該元素的class中添加animated即可。
// or
使用sass的循環語法定義delay樣式
@for $i from 0 through $delay_count { .animated .delay#{$i * 100} { animation-delay: $i * 100; animation-fill-mode: backwards; } }
具體實現可參考
5. 小數精度問題導致的bugjs的計算中,經常會遇到小數精度的問題,最初沒有注意,導致數據顯示出了很多問題。例如如下計算結果
1.099 * 100 109.89999999999999
解決方法如下:
(1.099 * 100).toFixed(2)6. Promise與setTimeout的寫法問題
利用setTimeout判斷某個對象是否注入成功。
// 錯誤寫法 export const checkSDK = () => { var timer = null; const start = Date.now(); return new Promise((resolve, reject) => { if (typeof window.TigerBridge === "object") { resolve(); return; } if (Date.now() - start <= 5 * 1000) { clearTimeout(timer); timer = setTimeout(checkSDK, 100); return; } reject(); }) } // 正確寫法 export const checkBridge = () => { var timer = null; const start = Date.now(); function check(resolve, reject) { if (typeof window.TigerBridge === "object") { resolve(); return true; } if (Date.now() - start <= 5 * 1000) { clearTimeout(timer); timer = setTimeout(check.bind(null, resolve, reject), 100); return; } reject(); return false; } return new Promise((resolve, reject) => check(resolve, reject)) }
本地模擬注入過程
if (process.env.NODE_ENV != "production") { setTimeout(() => { window.TigerBridge = { getAccessToken: () => { return pkg.token; }, isAccountPermissionLimited: () => false }; }, 1600); }7. 圖片串行加載優化
一次性加載所有圖片會導致瀏覽器http線程阻塞嚴重。因此需要稍作優化,讓圖片一張一張加載。
// 優化前 images.keys().map(path => new Promise(resolve => { const image = new Image(); image.src = images(path); image.onload = image.onerror = resolve; })) // 優化后 images.keys().reduce((cachePromise, path) => cachePromise.then(() => { return new Promise(resolve => { const image = new Image(); const complete = () => { clearTimeout(timer); resolve(); } const timer = setTimeout(complete, 1000); // 單張圖片最多加載1s image.src = images(path); image.onload = image.onerror = complete; }) }), Promise.resolve());
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/90455.html
摘要:事件原因之前使用開發的一個網站。事件的處理方法在公司是有專門的安全組來做安全這塊兒工作的。第一時間對這個接口進行了下線處理,然后評估了安全的解決方案,再次上線該接口。這些機器也肯定是經過做特殊的隔離處理的沒有敏感的公司信息資源。 事件原因: 之前使用Nodejs開發的一個網站。在網站上有一個頁面有個功能,允許用戶上傳圖片或者粘貼一張圖片鏈接。服務端讀取用戶上傳的圖片信息或者是請求用戶填...
摘要:項目開發完成,接下來是上線,關于項目的部署,我司前端是部署在服務器上,關于的相關文檔,請自行查閱本文只記錄部署時碰到的一些問題。其他總結文章常規打包優化方案組件通信處理方案后臺管理項目總結 項目開發完成,接下來是上線,關于vue項目的部署,我司前端是部署在nginx服務器上,關于nginx的相關文檔,請自行查閱;本文只記錄部署時碰到的一些問題。 打包 vue項目打包后,是生成一系列的靜...
摘要:參與者項目經理產品經理開發經理測試經理及其它相關人員。項目上線后問題反饋針對項目客戶反饋問題進行分析總結,類似缺陷分析,重點總結遺漏的原因及后需的規避措施。六匯總整理各部門總結并發布基于測試總結過程中的數據分析,我們提出了對部門的建議。 最近參與了幾次面試,面試者的簡歷中都會提及:需求或者...
閱讀 2048·2019-08-30 15:52
閱讀 2440·2019-08-29 18:37
閱讀 790·2019-08-29 12:33
閱讀 2839·2019-08-29 11:04
閱讀 1523·2019-08-27 10:57
閱讀 2092·2019-08-26 13:38
閱讀 2759·2019-08-26 12:25
閱讀 2445·2019-08-26 12:23