Files
FamilyBook/assets/js/preview.js
T

102 lines
3.6 KiB
JavaScript
Raw Normal View History

/**
* 全局附件预览(v24 用户第 3 条)
*
* 点缩略图 → **在本页**弹一层把内容放出来,不再新开标签页。
* · 图片 → <img>
* · 视频 → <video controls autoplay>(media.php 支持 Range,进度条能拖)
* · PDF → <iframe>(用浏览器自带的阅读器)
* · 其它(Word / Excel / …)→ 根本不进这里:那段链接指向的是下载地址,点了就下。
*
* 右上角恒有一个「下载」按钮(用户原话:所有的预览页面,右上角都有一个下载按钮)。
*
* 触发方式是数据属性,不用给每个地方写一遍初始化:
* <a href="…" data-prev="image|video|pdf" data-src="…" data-dl="…" data-name="…">
*/
(function () {
'use strict';
var box = document.getElementById('pv');
if (!box) { return; }
var stage = box.querySelector('.pv-stage');
var titleEl = box.querySelector('.pv-name');
var metaEl = box.querySelector('.pv-meta');
var dlEl = box.querySelector('.pv-dl');
var closeEl = box.querySelector('.pv-close');
var opener = null;
function clear() {
// ⚠️ 换内容要**整个重建**节点,不能只改 src:
// <video> 改 src 不会自动卸载上一支(声音会叠着放),<iframe> 同理。
stage.innerHTML = '';
}
function open(trigger) {
var kind = trigger.getAttribute('data-prev') || 'image';
var src = trigger.getAttribute('data-src') || trigger.getAttribute('href') || '';
var dl = trigger.getAttribute('data-dl') || src;
if (!src) { return; }
opener = trigger;
clear();
var el;
if (kind === 'video') {
el = document.createElement('video');
el.className = 'pv-video';
el.src = src;
el.controls = true;
el.autoplay = true;
el.playsInline = true;
} else if (kind === 'pdf') {
el = document.createElement('iframe');
el.className = 'pv-pdf';
el.src = src;
// PDF 是"另一份文档",别让它拿到本页的 window
el.setAttribute('sandbox', 'allow-same-origin allow-scripts');
} else {
el = document.createElement('img');
el.className = 'pv-img';
el.src = src;
el.alt = '';
}
stage.appendChild(el);
titleEl.textContent = trigger.getAttribute('data-name') || '';
var sz = trigger.getAttribute('data-size') || '';
metaEl.textContent = sz;
dlEl.setAttribute('href', dl);
// 下载要带上真实文件名:download 属性 + 服务端 Content-Disposition 双保险
var nm = trigger.getAttribute('data-name') || '';
if (nm) { dlEl.setAttribute('download', nm); } else { dlEl.removeAttribute('download'); }
box.hidden = false;
box.setAttribute('aria-hidden', 'false');
closeEl.focus();
}
function close() {
box.hidden = true;
box.setAttribute('aria-hidden', 'true');
clear(); // 停掉视频 / 卸掉 PDF
if (opener && opener.focus) { opener.focus(); }
opener = null;
}
document.addEventListener('click', function (e) {
var t = e.target && e.target.closest ? e.target.closest('[data-prev]') : null;
if (t) {
// ⚠️ 只拦"可预览"的:Word/Excel 那类链接没有 data-prev,
// 浏览器照常走 href(就是下载地址),不会被这里挡住。
e.preventDefault();
open(t);
return;
}
// 点遮罩(stage 本身或弹层空白处)关闭;点内容不关
if (!box.hidden && (e.target === box || e.target === stage)) { close(); }
});
closeEl.addEventListener('click', close);
document.addEventListener('keydown', function (e) {
if (!box.hidden && e.key === 'Escape') { close(); }
});
})();