項(xiàng)目場(chǎng)景:
提示:1、實(shí)現(xiàn)小程序預(yù)覽
doc、docx、xls、xlsx、ppt、pptx、pdf類型文件
?????????? 2、進(jìn)入頁(yè)面展示文件內(nèi)容、開始按鈕,點(diǎn)擊,按鈕變?yōu)椤荆?*s)】倒計(jì)時(shí)
?????????? 3、倒計(jì)時(shí)結(jié)束后,此按鈕消失,彈出顯示【完成】,彈框保留2s后小時(shí),用戶繼續(xù)閱讀
例如:項(xiàng)目場(chǎng)景:示例:學(xué)習(xí)計(jì)時(shí)
問題描述
提示:小程序自帶的api可以實(shí)現(xiàn)文件預(yù)覽,但不可以在文件預(yù)覽頁(yè)面添加按鈕,不可以操作文件預(yù)覽頁(yè)面:
例如:小程序文檔地址:wx.openDocument(Object object) | 微信開放文檔
小程序代碼:
wx.downloadFile({
// 示例 url,并非真實(shí)存在
url: 'http://example.com/somefile.pdf',
success: function (res) {
const filePath = res.tempFilePath
wx.openDocument({
filePath: filePath,
success: function (res) {
console.log('打開文檔成功')
}
})
}
})
分析:
提示:考慮建立新頁(yè)面,用web-view組件放預(yù)覽文件,cover-image組件做按鈕,但存在兼容性問題,部分手機(jī)cover-image組件被web-view遮擋。
解決方案:
提示:前端將預(yù)覽的html文件(包括倒計(jì)時(shí)操作),放在服務(wù)器,后端用kkfileview部署獲取預(yù)覽地址給前端【kkFileView為文件文檔在線預(yù)覽解決方案,該項(xiàng)目使用流行的spring boot搭建,易上手和部署,基本支持主流辦公文檔的在線預(yù)覽,如doc,docx,xls,xlsx,ppt,pptx,pdf,txt,zip,rar,圖片,視頻,音頻等等,官網(wǎng)地址:https://kkfileview.keking.cn/zh-cn/docs/config.html】
小程序端:
fileUrl為服務(wù)器文件地址 :'https://******.com/fileRead.html?id='+this.data.id+'&userId='+res.data.id文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-539027.html
<web-view style="width: 100px !important;height: 200px !important;" src="{{fileUrl}}" bindload="successLoad">
</web-view>
服務(wù)器fileRead.html文件:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-539027.html
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="shortcut icon" href="#" />
<meta charset="UTF-8" />
<meta http-equiv="cache-control" content="no-cache,no-store,must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="expires" content="0" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<style>
body {
margin: 0;
padding: 0;
}
.btn_read {
position: absolute;
display: none;
right: 0;
left: 50%;
bottom: 30px;
transform: translateX(-50%);
width: 150px;
height: auto;
z-index: 9999;
}
.text-box {
position: absolute;
display: none;
right: 0;
left: 50%;
bottom: 30px;
transform: translateX(-50%);
z-index: 9999;
width: 130px;
height: 40px;
line-height: 40px;
border-radius: 8px;
border: 1px #B11818 solid;
color: #B11818;
font-size: 15px;
font-weight: bold;
text-align: center;
}
.box {
position: absolute;
display: none;
}
.finish-box {
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 143px;
height: auto;
z-index: 9999;
}
</style>
</head>
<script>
//可以將查找標(biāo)簽節(jié)點(diǎn)的操作進(jìn)行簡(jiǎn)化 var btn = getElementById('btn')
function $(id) {
return document.getElementById(id);
}
//設(shè)置iframe自適應(yīng)
function changeFrameHeight() {
var ifm1 = $("myiframe");
ifm1.height = document.documentElement.clientHeight + 'px';
ifm1.width = document.documentElement.clientWidth + 'px';
}
//key(需要檢索的鍵) url(傳入的需要分割的url地址,例:?id=2&age=18)
function getSearchString(key, Url) {
var str = Url;
str = str.substring(1, str.length); // 獲取URL中?之后的字符(去掉第一位的問號(hào))
// 以&分隔字符串,獲得類似name=xiaoli這樣的元素?cái)?shù)組
var arr = str.split("&");
var obj = new Object();
// 將每一個(gè)數(shù)組元素以=分隔并賦給obj對(duì)象
for (var i = 0; i < arr.length; i++) {
var tmp_arr = arr[i].split("=");
obj[decodeURIComponent(tmp_arr[0])] = decodeURIComponent(tmp_arr[1]);
}
return obj[key];
}
</script>
<body id="id_body" style="height: 100vh;width: 100%; overflow-y: hidden">
<iframe id="myiframe" name="myiframe"></iframe>
<img src="開始學(xué)習(xí)圖片" id="btn_start" class="btn_read" />
<div id="text_count" class=" text-box">學(xué)習(xí)中</div>
<img id="icon_finish_bg" class="box finish-box" src="完成學(xué)習(xí)圖片"></img>
<script>
console.log('time',new Date())
var timer = null; //timer變量記錄定時(shí)器setInterval的返回值
var search = window.location.search;//地址參數(shù),傳入的需要分割的url地址,例:?id=2&age=18
var fileId = getSearchString("id", search); //文件id
var userId = getSearchString("userId", search);
var baseUrl = '接口請(qǐng)求地址'
var loading = false
var learnDuration = 0 //學(xué)習(xí)時(shí)間,接口返回
//監(jiān)聽窗口分辨率改變
window.onresize = function () {
changeFrameHeight();
}
window.onload = function () {
changeFrameHeight();
//開始閱讀監(jiān)聽
$("btn_start").addEventListener("click", function () {
$("btn_start").setAttribute("style", "display:none");
$("text_count").setAttribute("style", "display:block");
countTime(learnDuration)
});
$("myiframe").onload = function (e) {
console.log('myiframe加載成功');
loading = true
var ifDoc = $("myiframe").contentDocument || {};
var ifTitle = ifDoc.title || '';
console.log('ifTitle', ifTitle);
if (ifTitle.indexOf("404") >= 0 || ifTitle.indexOf("錯(cuò)誤") >= 0) {
console.log('加載失敗');
}
}
getDetail()
};
//請(qǐng)求接口獲取詳情
function getDetail() {
$("btn_start").setAttribute("style", "display:block");
var url = baseUrl + '/courseware/textbooks/detail/' + fileId
var xhr = new XMLHttpRequest();
// 可以設(shè)置請(qǐng)求頭,一般不設(shè)置
//超時(shí)設(shè)置 2s 設(shè)置
xhr.timeout = 50000;
//超時(shí)回調(diào)
xhr.ontimeout = function () {
// alert("網(wǎng)絡(luò)異常, 請(qǐng)稍后重試!!");
}
//網(wǎng)絡(luò)異?;卣{(diào)
xhr.onerror = function () {
// alert("你的網(wǎng)絡(luò)似乎出了一些問題!");
}
//設(shè)置響應(yīng)體數(shù)據(jù)的類型
xhr.responseType = 'json';
xhr.open("get", url);
xhr.send(null);
//注冊(cè)相關(guān)事件回調(diào)處理函數(shù)
xhr.onload = function (e) {
if (xhr.status == 200 || xhr.status == 304) {
if (xhr.status == 200 && xhr.response && xhr.response.code == 200) {
loadPage(xhr.response.data)
} else {
console.log("Request was unsuccessful: " + xhr.status); // 請(qǐng)求失敗,返回 響應(yīng)的 HTTP 狀態(tài)
}
}
};
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {// (整個(gè)數(shù)據(jù)傳輸過程結(jié)束)
}
};
}
//加載頁(yè)面
function loadPage(res) {
if (!res) {
return false;
}
if (!res.textbooks) {
return false;
}
document.title = res.textbooks ? res.textbooks.name : ''//修改html標(biāo)題
learnDuration = res.learnDuration//獲取倒計(jì)時(shí)時(shí)間
var base64_url = base64_encode(res.textbooks.url)
var url = encodeURIComponent(base64_url)
console.log("base64_url", base64_url);
console.log("url", url);
var fileUrl = '預(yù)覽文件服務(wù)端地址/onlinePreview?url=' + url + '&officePreviewType=' + res.suffix; //要預(yù)覽文件的訪問地址,后端使用kkfileview后的地址
$("myiframe").src = fileUrl
$("text_count").innerHTML = '學(xué)習(xí)中(' + res.learnDuration + "s)";
console.log('fileUrl', fileUrl);
}
//結(jié)束學(xué)習(xí)
function finishComplete(params) {
var api = baseUrl + '/courseware/learn/complete?id=' + fileId + '&userId=' + userId
var xhr2 = new XMLHttpRequest();
// 可以設(shè)置請(qǐng)求頭,一般不設(shè)置
//超時(shí)設(shè)置 2s 設(shè)置
xhr2.timeout = 50000;
//超時(shí)回調(diào)
xhr2.ontimeout = function () {
alert("網(wǎng)絡(luò)異常, 請(qǐng)稍后重試!!");
}
//網(wǎng)絡(luò)異常回調(diào)
xhr2.onerror = function () {
alert("你的網(wǎng)絡(luò)似乎出了一些問題!");
}
//設(shè)置響應(yīng)體數(shù)據(jù)的類型
xhr2.responseType = 'json';
xhr2.open("get", api);
xhr2.send(null);
//注冊(cè)相關(guān)事件回調(diào)處理函數(shù)
xhr2.onload = function (e) {
if (xhr2.status == 200 || xhr2.status == 304) {
if (xhr2.status == 200 && xhr2.response && xhr2.response.code == 200) {
} else {
console.log("Request /courseware/learn/complete was unsuccessful: " + xhr2.status); // 請(qǐng)求失敗,返回 響應(yīng)的 HTTP 狀態(tài)
}
}
};
}
function countTime(count) {
//點(diǎn)擊開始建 開始計(jì)數(shù)
timer = setInterval(function () {
count--;
if (count==0) {
finishComplete()
}
if (count < 0) {
clearInterval(timer);
$("id_body").removeChild($("text_count"));
$("icon_finish_bg").setAttribute("style", "display:block");
setTimeout(function () {
$("icon_finish_bg").setAttribute("style", "display:none");
}, 2000)
} else {
// submitSutdy()
$("text_count").innerHTML = '學(xué)習(xí)中(' + count + "s)";
}
// 需要改變頁(yè)面上時(shí)分秒的值
}, 1000);
}
function base64_encode(str) {
//下面是64個(gè)基本的編碼
var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var out, i, len;
var c1, c2, c3;
len = str.length;
i = 0;
out = "";
while (i < len) {
c1 = str.charCodeAt(i++) & 0xff;
if (i == len) {
out += base64EncodeChars.charAt(c1 >> 2);
out += base64EncodeChars.charAt((c1 & 0x3) << 4);
out += "==";
break;
}
c2 = str.charCodeAt(i++);
if (i == len) {
out += base64EncodeChars.charAt(c1 >> 2);
out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
out += base64EncodeChars.charAt((c2 & 0xF) << 2);
out += "=";
break;
}
c3 = str.charCodeAt(i++);
out += base64EncodeChars.charAt(c1 >> 2);
out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
out += base64EncodeChars.charAt(c3 & 0x3F);
}
return out;
}
</script>
</body>
</html>
到了這里,關(guān)于實(shí)現(xiàn)微信小程序預(yù)覽文件,預(yù)覽頁(yè)面添加倒計(jì)時(shí)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!