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

JS實(shí)現(xiàn)彈出下載對(duì)話框及常見文件類型的下載

 更新時(shí)間:2017年07月13日 09:29:03   作者:我是小茗同學(xué)  
JS要實(shí)現(xiàn)下載功能,一般都是這么幾個(gè)過程:生成下載的URL,動(dòng)態(tài)創(chuàng)建一個(gè)A標(biāo)簽,并將其href指向生成的URL,然后觸發(fā)A標(biāo)簽的單擊事件,這樣就會(huì)彈出下載對(duì)話框,從而實(shí)現(xiàn)了一個(gè)下載的功能

1.寫在前面

JS要實(shí)現(xiàn)下載功能,一般都是這么幾個(gè)過程:生成下載的URL,動(dòng)態(tài)創(chuàng)建一個(gè)A標(biāo)簽,并將其href指向生成的URL,然后觸發(fā)A標(biāo)簽的單擊事件,這樣就會(huì)彈出下載對(duì)話框,從而實(shí)現(xiàn)了一個(gè)下載的功能。

這里所說的下載,有時(shí)候也可以理解為保存。出于安全考慮,JS肯定無法直接調(diào)用FileAPI寫文件到磁盤,但是卻可以通過下載來變相實(shí)現(xiàn)保存功能。

2.幾個(gè)備用知識(shí)點(diǎn)

2.1. JS觸發(fā)單擊事件

既然是用A標(biāo)簽?zāi)M,那么肯定要知道JS如何主動(dòng)觸發(fā)單擊事件。

最簡單的觸發(fā)單擊事件肯定是elem.click(),平時(shí)在不需要考慮兼容性的場(chǎng)合我都是這么干的,但是畢竟這個(gè)方法有兼容性(具體兼容性如何沒做過測(cè)試),所以還是要掌握一個(gè)通用的方法。

以下代碼是網(wǎng)上比較容易找到的一段代碼,我在前面加了一段MouseEvent的判斷:

/**
 * 觸發(fā)單擊事件
 * @param elem 需要觸發(fā)事件的DOM對(duì)象
 */
function fireClickEvent(elem)
{
 var event;
 if(window.MouseEvent) event = new MouseEvent('click');
 else
 {
  event = document.createEvent('MouseEvents');
  event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
 }
 elem.dispatchEvent(event);
}

2.2. HTML5的download屬性

這個(gè)屬性很重要,它可以指定下載文件名,并且可以告訴瀏覽器目標(biāo)鏈接是一個(gè)下載鏈接,不是一個(gè)普通鏈接,我們看下面代碼就能看出區(qū)別了:

<a href="data:text/txt;charset=utf-8,測(cè)試下載純文本" rel="external nofollow" rel="external nofollow" rel="external nofollow" download="測(cè)試.txt" >下載1</a>
<a href="data:text/txt;charset=utf-8,測(cè)試下載純文本" rel="external nofollow" rel="external nofollow" rel="external nofollow" >下載2</a>

可以發(fā)現(xiàn),下載1按鈕能夠?qū)崿F(xiàn)下載,點(diǎn)擊下載2鏈接時(shí)直接在瀏覽器打開文件內(nèi)容了。

補(bǔ)充說明:

file:///模式下貌似不生效;

鏈接指向一些第三方鏈接時(shí)也不會(huì)生效,具體有待研究;

2.3. JS彈出下載對(duì)話框

假如給我們的不是一個(gè)下載地址而是一個(gè)blob對(duì)象,我們可以通過URL.createObjectURL來給blob對(duì)象生成臨時(shí)URL,并且可以利用HTML5的download屬性來指定下載的文件名,好家伙,有了這2個(gè)東西我們就可以實(shí)現(xiàn)一個(gè)“萬能”的彈出下載對(duì)話框方法了。

綜上所述,我又在fireClickEvent的基礎(chǔ)上繼續(xù)簡單封裝了一個(gè)openDownloadDialog方法,使用如下:

openDownloadDialog(url, saveName)
openDownloadDialog(blob, saveName)

代碼如下:

/**
 * 通用的打開下載對(duì)話框方法,沒有測(cè)試過具體兼容性
 * @param url 下載地址,也可以是一個(gè)blob對(duì)象,必選
 * @param saveName 保存文件名,可選
 */
function openDownloadDialog(url, saveName)
{
 if(typeof url == 'object' && url instanceof Blob)
 {
  url = URL.createObjectURL(url); // 創(chuàng)建blob地址
 }
 var aLink = document.createElement('a');
 aLink.href = url;
 aLink.download = saveName || ''; // HTML5新增的屬性,指定保存文件名,可以不要后綴,注意,file:///模式下不會(huì)生效
 var event;
 if(window.MouseEvent) event = new MouseEvent('click');
 else
 {
  event = document.createEvent('MouseEvents');
  event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
 }
 aLink.dispatchEvent(event);
}

3.JS實(shí)現(xiàn)常見文件類型的下載

3.1. JS生成CSV文件并下載

csv是一種逗號(hào)分隔的表格文件格式,可以很好的被Excel支持,由于其文件格式簡單,所以經(jīng)常用在簡單的表格上面。最重要的是它是一種純文本格式,可以很輕松地用JS來生成而不借助第三方庫。

3.1.1. CSV格式示例

如下:

姓名,期中成績,期末成績
張三,58,95
李四,98,74
王二,47,38
劉能,15,100
黃五,87,68

excel打開效果如下:

3.1.2. 初次嘗試

首先想到的是使用data:text/txt;來實(shí)現(xiàn),先看一下下載純文本:

<a download="測(cè)試.txt" href="data:text/txt;charset=utf-8,測(cè)試下載純文本" rel="external nofollow" rel="external nofollow" rel="external nofollow" >下載</a>

以上代碼沒毛病,然后再換成csv。換csv的最大問題就是如何處理換行,很簡單,用encodeURIComponent編碼一下就可以了:

<button onclick="test()">下載CSV</button>
<script>
function test()
{
 var csv = '姓名,期中成績,期末成績\n張三,58,95\n李四,98,74';
 var a = document.createElement('a');
 a.href = 'data:text/txt;charset=utf-8,'+encodeURIComponent(csv);
 a.download = '測(cè)試.csv';
 a.click(); // 這里偷個(gè)懶,直接用click模擬
}
</script>

3.1.3. 解決CSV亂碼問題

雖然我們用的是UTF-8編碼,下載后你會(huì)發(fā)現(xiàn),用文本編輯器打開沒問題,但是用Excel打開亂碼:

別急,原因就是少了一個(gè)\ufeffBOM頭,改成這樣就沒問題了:

<button onclick="test()">下載CSV</button>
<script>
function test()
{
 var csv = '姓名,期中成績,期末成績\n張三,58,95\n李四,98,74';
 var a = document.createElement('a');
 a.href = 'data:text/txt;charset=utf-8,\ufeff'+encodeURIComponent(csv);
 a.download = '測(cè)試.csv';
 a.click(); // 這里偷個(gè)懶,直接用click模擬
}
</script>

3.1.4. 繼續(xù)解決下載文件名的問題

大部分瀏覽器可能都沒啥問題,但是一些比較老的Chrome可能下載的時(shí)候指定的download就是不生效,此時(shí)可以用blob來解決:

var csv = '姓名,期中成績,期末成績\n張三,58,95\n李四,98,74';
var blob = new Blob(['\ufeff' + data], {type: 'text/csv,charset=UTF-8'});
openDownloadDialog(blob, '測(cè)試.csv');

建議一般情況下都用這種方法,穩(wěn)妥一點(diǎn)。

3.1.5. 最后總結(jié)

不考慮兼容性的保存CSV方法:

/**
 * 保存CSV文件
 * @params csv csv文件內(nèi)容
 * @params saveName 保存的文件名
 */
function saveCSV(csv, saveName)
{
 var a = document.createElement('a');
 a.href = 'data:text/csv;charset=utf-8,\ufeff' + encodeURIComponent(csv);
 a.download = saveName;
 a.click();
}

考慮兼容性的保存CSV方法:

/**
 * 保存CSV文件
 * @params csv csv文件內(nèi)容
 * @params saveName 保存的文件名
 */
function saveCSV(csv, saveName)
{
 var blob = new Blob(['\ufeff' + csv], {type: 'text/csv,charset=UTF-8'});
 openDownloadDialog(blob, saveName);
}

3.2. JS實(shí)現(xiàn)純文本的下載保存

掌握了csv,再去下載純文本基本上就沒啥問題了,就是換一下文件類型而已:

var csv = '你好,我是小茗同學(xué)!\n測(cè)試換行!';
var blob = new Blob([data], {type: 'text/txt,charset=UTF-8'});
openDownloadDialog(blob, '測(cè)試.csv');

3.3. JS實(shí)現(xiàn)圖片的下載保存

網(wǎng)頁上一般要保存圖片都是從canvas里面拿到的圖片數(shù)據(jù),通過toDataURL轉(zhuǎn)換為base64數(shù)據(jù):

/**
 * 將某個(gè)canvas保存為圖片
 * @param canvasObj canvas對(duì)象
 * @param saveName 保存的名稱
 * @param type 保存的圖片格式,如 image/png
 * @param quality 圖片質(zhì)量,可選0-1
 */
function saveImage(canvasObj, saveName, type, quality)
{
 if(!canvasObj) return;
 type = type || 'image/png';
 quality = quality || 0.92;
 var url = canvasObj.toDataURL(type, quality).replace(/image\/.*?;/, 'image/octet-stream;');
 openDownloadDialog(url, saveName);
}

擴(kuò)展

關(guān)于文件保存,不嫌麻煩的話,GitHub上面有個(gè)比較出名的庫:https://github.com/eligrey/FileSaver.js/

demo:https://eligrey.com/demos/FileSaver.js/

以上所述是小編給大家介紹的JS實(shí)現(xiàn)彈出下載對(duì)話框及常見文件類型的下載,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • 禁用頁面部分JavaScript不是全部而是部分

    禁用頁面部分JavaScript不是全部而是部分

    全部限制那是很簡單的事,直接把<script>腳本塊過濾掉就行了,但是部分限制又是如何做到的呢,下面我們一起來看看
    2014-09-09
  • 整理關(guān)于Bootstrap警示框的慕課筆記

    整理關(guān)于Bootstrap警示框的慕課筆記

    這篇文章主要為大家整理了關(guān)于Bootstrap導(dǎo)航的慕課筆記,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • Javascript圖像處理—閾值函數(shù)實(shí)例應(yīng)用

    Javascript圖像處理—閾值函數(shù)實(shí)例應(yīng)用

    閾值是最簡單的圖像分割方法,接下來將介紹五種閾值類型感興趣的朋友可以參考下
    2013-01-01
  • 一文了解ES5和ES6的區(qū)別

    一文了解ES5和ES6的區(qū)別

    ES6是JavaScript語言的主要增強(qiáng),允許我們編寫程序,ES6適用于復(fù)雜的應(yīng)用程序,盡管ES5和ES6在本質(zhì)上有一些相似之處,但它們之間也有許多不同之處,下面這篇文章主要給大家介紹了關(guān)于ES5和ES6區(qū)別的相關(guān)資料,需要的朋友可以參考下
    2023-05-05
  • javascript實(shí)現(xiàn)的字符串與十六進(jìn)制表示字符串相互轉(zhuǎn)換方法

    javascript實(shí)現(xiàn)的字符串與十六進(jìn)制表示字符串相互轉(zhuǎn)換方法

    這篇文章主要介紹了javascript實(shí)現(xiàn)的字符串與十六進(jìn)制表示字符串相互轉(zhuǎn)換方法,涉及javascript字符串轉(zhuǎn)換的相關(guān)技巧,在防止SQL注入和XSS中具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • JS可斷點(diǎn)續(xù)傳文件上傳實(shí)現(xiàn)代碼解析

    JS可斷點(diǎn)續(xù)傳文件上傳實(shí)現(xiàn)代碼解析

    這篇文章主要介紹了JS可斷點(diǎn)續(xù)傳文件上傳實(shí)現(xiàn)代碼解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • JavaScript函數(shù)定義方法實(shí)例詳解

    JavaScript函數(shù)定義方法實(shí)例詳解

    這篇文章主要介紹了JavaScript函數(shù)定義方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了javascript函數(shù)的聲明、定義、調(diào)用等原理與常見操作技巧,需要的朋友可以參考下
    2019-03-03
  • uni-app實(shí)現(xiàn)頁面通信EventChannel的操作方法

    uni-app實(shí)現(xiàn)頁面通信EventChannel的操作方法

    使用了EventBus的方法實(shí)現(xiàn)不同頁面組件之間的一個(gè)通信,在uni-app中,我們也可以使用uni-app API,uni.navigateTo來實(shí)現(xiàn)頁面間的通信,這篇文章主要介紹了uni-app實(shí)現(xiàn)頁面通信EventChannel的操作方法,需要的朋友可以參考下
    2024-05-05
  • js 文件引入實(shí)現(xiàn)代碼

    js 文件引入實(shí)現(xiàn)代碼

    項(xiàng)目前端的文件和后臺(tái)開發(fā)分離,只要后臺(tái)開發(fā)更新svn前端的js,css文件都會(huì)更新,以前引用的是一個(gè)js文件如AA.js,由于想在項(xiàng)目中引用jquery庫,如果在每個(gè)文件的頭部都引讓他們從新寫入這個(gè)jq文件不太可能
    2010-04-04
  • ES6學(xué)習(xí)教程之塊級(jí)作用域詳解

    ES6學(xué)習(xí)教程之塊級(jí)作用域詳解

    很多語言中都有塊級(jí)作用域,但JS沒有,它使用var聲明變量,以function來劃分作用域,大括號(hào)“{}” 卻限定不了var的作用域,下面這篇文章主要給大家介紹了關(guān)于ES6學(xué)習(xí)教程之塊級(jí)作用域的相關(guān)資料,需要的朋友可以參考下。
    2017-10-10

最新評(píng)論

出国| 晋中市| 渝北区| 永州市| 通城县| 舟曲县| 绥江县| 中江县| 金阳县| 九江市| 桦甸市| 古丈县| 澄江县| 达拉特旗| 子洲县| 北海市| 五台县| 水城县| 孙吴县| 伊通| 宁远县| 章丘市| 长海县| 沽源县| 陇川县| 台山市| 三亚市| 永济市| 沿河| 伽师县| 通海县| 崇义县| 东明县| 濮阳市| 关岭| 柘荣县| 石台县| 南宫市| 茶陵县| 乌兰浩特市| 濮阳市|