一行JavaScript代碼實(shí)現(xiàn)預(yù)覽圖片、視頻、文件
用最簡(jiǎn)單的使用方式,實(shí)現(xiàn)大多數(shù)類型資源的預(yù)覽。
IPreview.previewUuid('xxxx-xxxx-xxxx-xxxx');簡(jiǎn)介
一行代碼實(shí)現(xiàn)預(yù)覽 是我在公司內(nèi)搭建的前端組件庫(kù)中的一個(gè)功能。目的是解決預(yù)覽方式不統(tǒng)一、預(yù)覽不同類型資源困難、預(yù)覽實(shí)現(xiàn)代碼混亂的問(wèn)題。這個(gè)功能從提出到落地應(yīng)用,極大提高了我的開(kāi)發(fā)效率(更多摸魚時(shí)間)!
tips: 需要注意的是,這個(gè)功能依賴于云對(duì)象OSS存儲(chǔ),這也是大多數(shù)企業(yè)存儲(chǔ)文件的方式,個(gè)人項(xiàng)目需要根據(jù)實(shí)現(xiàn)原理另行封裝改造。
預(yù)覽演示
此處為我部署在公司內(nèi)網(wǎng)的文檔站點(diǎn),演示各類資源的預(yù)覽效果。

實(shí)現(xiàn)原理
這里用簡(jiǎn)單代碼展示原理,方便理解。實(shí)際開(kāi)發(fā)中會(huì)進(jìn)行大量?jī)?yōu)化,以及調(diào)整預(yù)覽UI、預(yù)覽功能等等。
3.1 根據(jù)uuid獲取url
文件存儲(chǔ)服務(wù)依賴uuid來(lái)區(qū)分文件,避免同名文件覆蓋問(wèn)題。一般在公司前端基建中已經(jīng)封裝好了工具函數(shù),可以通過(guò)uuid獲取文件地址。類似下面這種格式:
export async function getUrlByUuid (uuid: string): Promise<string> {
// ...
}3.2 通過(guò)url計(jì)算預(yù)覽信息
從云存儲(chǔ)廠商返回的url中,我們能計(jì)算出很多信息。我總結(jié)了下有這些:fileName、fileExt、fileType,將它們統(tǒng)一放在名為預(yù)覽信息的對(duì)象里。
interface PreviewInfo {
url: string; // oss文件地址
fileName: string; // 文件名稱
fileExt: string; // 文件后綴 (例如:"doc")
fileType: 'img' | 'file' | 'video'; // 文件類型
}
export async function getPreviewInfoFromUrl (url: string): PreviewInfo {
// 根據(jù)url計(jì)算預(yù)覽信息
// ...
}3.3 預(yù)覽圖片
為了用于預(yù)覽時(shí)縮放、移動(dòng)圖片的功能,我選擇基于antd的Image組件進(jìn)行封裝,并通過(guò)函數(shù)調(diào)用的方式預(yù)覽。
圖片預(yù)覽模板組件:
function PreviewImage ({src, onClose}) {
return (
<Image
preview={{
src,
visible: true,
onVisibleChange: value => {
if (!value) {
onClose?.()
}
}
}}
/>
)
}預(yù)覽圖片:
// React 16
type Unmount = () => void;
// 打開(kāi)預(yù)覽彈窗
function openPreview (Template: React.FC, previewInfo: PreviewInfo): Unmount {
let div = document.createElement('div');
let el = React.createElement(Template, {
src: previewInfo.url,
onClose: unmount
})
document.body.appendChild(div);
// 將React元素渲染到div,讓預(yù)覽組件生效
ReactDOM.render(el, div);
// 卸載
function unmount () {
if (!div) return;
ReactDOM.unmountComponentAtNode(div);
div.remove();
div = null;
el = null;
}
return unmount;
}
// 預(yù)覽圖片
function previewImgUrl (previewInfo: PreviewInfo) {
openPreview(PreviewImage, previewInfo)
}3.4 預(yù)覽文件
預(yù)覽文件這一步需要注意的是:需要獲取可預(yù)覽的url地址,否則文件有些會(huì)直接下載,例如doc。以doc文件可預(yù)覽地址舉例,需要公司事先擁有預(yù)覽文件的在線網(wǎng)址。如果沒(méi)有的話,需要去搭建一個(gè)類似的站點(diǎn)提供服務(wù),方便后期一處維護(hù)所有項(xiàng)目生效。類似于這樣的方式:
https://my.previewfile.com?url=【encodeURIComponent(oss地址)】
預(yù)覽Iframe模板組件:
import { Modal } from 'antd'
function PreviewIframe ({src, onClose}) {
const [visible, setVisible] = useState(true);
return (
<Modal
visible={visible}
title="預(yù)覽文件"
afterClose={onClose}
onCancel={() => setVisible(false)}
footer={null}
>
<iframe src={src} style={{width: '80vw',height: '80vh'}}/>
</Modal>
)
}預(yù)覽文件
// React 16
function previewFileUrl (previewInfo: PreviewInfo): Unmount {
return openPreview(PreviewIframe, previewInfo)
}3.5 預(yù)覽視頻
預(yù)覽視頻,我這里選擇的是 aliplayer-react,將其封裝成視頻彈窗模板。
預(yù)覽視頻模板組件:
import { Modal } from 'antd';
import Player from 'aliplayer-react';
// Video默認(rèn)配置項(xiàng)
const INITIAL = {
source: '',
width: '100%',
height: '100%',
autoplay: true,
isLive: false,
rePlay: false,
playsinline: true,
preload: true,
controlBarVisibility: 'hover',
useH5Prism: true,
components: [
{
name: 'RateComponent',
type: Player.components.RateComponent,
},
],
};
function PreviewVideo ({src, onClose}) {
const [visible, setVisible] = useState(true);
// 配置添加視頻地址
const videoConfig = useMemo(() => {
return {
...INITIAL,
source: src
}
}, [])
return (
<Modal
visible={visible}
title="預(yù)覽文件"
afterClose={onClose}
onCancel={() => setVisible(false)}
footer={null}
>
<Player config={videoConfig} />
</Modal>
)
}預(yù)覽文件
// React 16
function previewVideoUrl (previewInfo: PreviewInfo) {
openPreview(PreviewVideo, previewInfo)
}previewUuid 代碼實(shí)現(xiàn)
class Preview {
// 其他功能
// ...
// 預(yù)覽文件oss地址
public async previewUuid (uuid: string) {
const url = await getUrlByUuid(uuid);
return this.previewUrl(url)
}
// 預(yù)覽文件uuid
public async previewUrl (ossUrl: string) {
const previewInfo = await getPreviewInfoFromUrl(ossUrl);
// 預(yù)覽不同文件
switch (previewInfo.fileType) {
case 'img': // 預(yù)覽圖片
previewImgUrl(previewInfo)
break;
case 'file': // 預(yù)覽文件
previewFileUrl(previewInfo)
break;
case 'video': // 預(yù)覽視頻
previewVideoUrl(previewInfo)
break;
default:
message.warn(`.${previewInfo.fileExt}格式文件暫不支持預(yù)覽!`)
break;
}
}
}總結(jié)
到此這篇關(guān)于JavaScript代碼實(shí)現(xiàn)預(yù)覽圖片、視頻、文件的文章就介紹到這了,更多相關(guān)js預(yù)覽圖片、視頻、文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺談JavaScript宏任務(wù)和微任務(wù)執(zhí)行順序
本文主要介紹了JavaScript宏任務(wù)和微任務(wù)執(zhí)行順序,結(jié)合實(shí)例代碼進(jìn)行了詳細(xì)的講解,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-06-06
JavaScript封裝LINQ查詢方法實(shí)戰(zhàn)
本文主要介紹了通過(guò)js-linq庫(kù)在JavaScript中實(shí)現(xiàn)類似.NET LINQ的查詢功能,封裝Where、Select、OrderBy等方法,提升數(shù)組和可迭代對(duì)象的數(shù)據(jù)處理效率與代碼可讀性2025-09-09
JavaScript 中 JSON.parse 函數(shù) 和 JSON.stringify 函數(shù)
這篇文章主要介紹了JavaScript -- JSON.parse 函數(shù) 和 JSON.stringify 函數(shù),本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-12-12
關(guān)于javascript中this關(guān)鍵字(翻譯+自我理解)
在傳統(tǒng)面向?qū)ο笳Z(yǔ)言中,this關(guān)鍵字是個(gè)很乖的小孩,從不亂跑,該是誰(shuí)的就是誰(shuí)的??墒窃贘avaScript中,我們發(fā)現(xiàn)它不那么乖,有時(shí)甚至把我們搞的暈頭轉(zhuǎn)向的。所以有必要對(duì)它稍微做個(gè)總結(jié)。2010-10-10
JavaScript設(shè)計(jì)模式之觀察者模式實(shí)例詳解
這篇文章主要介紹了JavaScript設(shè)計(jì)模式之觀察者模式,結(jié)合實(shí)例形式詳細(xì)分析了javascript觀察者模式的概念、原理、用法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2019-01-01
關(guān)于獲取DIV內(nèi)部?jī)?nèi)容報(bào)錯(cuò)的原因分析及解決辦法
這篇文章主要介紹了關(guān)于獲取DIV內(nèi)部?jī)?nèi)容報(bào)錯(cuò)的原因分析及解決辦法的相關(guān)資料,需要的朋友可以參考下2016-01-01

