标题: 【网页插件】图片点击加载(测试版 r8)
时间: 2022-07-28发布,2022-07-31修改
自动更新代码(推荐使用):
导入网页插件:图片点击加载(自动更新)(当前用户:14,总安装次数:24)<script src="https://hu60.cn/q.php/api.webplug-file.1_public_img_click_load.js"></script>
如果你有多个插件,请将图片点击加载插件移到插件列表的开头,以达到更好的流量节省效果。
如果图片点击加载插件位于其他插件之后,可能会导致部分图片在插件生效前就加载完成,节省流量的目的就不能完全实现。
完整代码仅供参考,不能直接执行
(() => {
function getSizeFromUrl(url) {
url = hu60_decode_url64(url);
var parts = url.match(/\/file\/(?:hash\/[^\/]+\/[a-f0-9]{32}|uuid\/[^\/]+\/[a-f0-9-]{36})(\d+)\b/);
return parts ? parseInt(parts[1]) : 0;
}
function getImgSize(img) {
if (img.alt) {
var parts = img.alt.match(/([0-9]+(:?\.[0-9]+)?\s*(?:[KMGT]B|bytes))/);
if (parts) return parts[1];
}
var size = getSizeFromUrl(img.src);
return size > 0 ? humanize.filesize(size) : '';
}
document.querySelectorAll('.userimg').forEach(x => {
// 暂时抑制外层链接
if (x.parentNode.href) {
x.parentNode._href = x.parentNode.href;
x.parentNode.href = `javascript:void(0);`;
}
// 保存原始URL
x._url = x.src;
// 图片替换为文字SVG
var outLink = x.parentNode.href ? `<text x="15" y="125" fill="red">再次点击打开链接</text>` : '';
var alt = x.alt ? escapeHtml(x.alt) : '';
var size = getSizeFromUrl(x.src);
size = getImgSize(x);
x.src = `data:image/svg+xml;utf8,
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<text x="15" y="35" fill="red">${alt}</text>
<text x="15" y="65" fill="red">${size}</text>
<text x="15" y="95" fill="red">点击加载图片</text>
${outLink}
</svg>`;
});
})();
$(document).ready(() => {
// 加这个延时,就可以保证晚于任何其他插件执行,以解决和viewer.js的冲突
setTimeout(() => {
document.querySelectorAll('.userimg').forEach(x => {
// 替换掉虎绿林的点击查看大图事件
x._onclick = x.onclick;
x.onclick = function () {
this.src = this._url;
// 再次点击就触发虎绿林的点击查看大图事件
x.onclick = x._onclick;
// 恢复被抑制的图片外层链接
if (x.parentNode._href) {
// 为了防止外层链接被立即触发,所以加个延时
setTimeout(() => x.parentNode.href = x.parentNode._href);
}
};
});
}, 10);
});
『回复列表(72|显示机器人聊天)』
对markdown link+img 无效
[![]()]()
测试帖 https://hu60.cn/q.php/bbs.topic.103447.html
HUAWEI Mate X2(冰晶蓝)兔兔图床
感觉还存在以下问题:
不知道有没有直接获取文件大小的方法。
目前是用fetch
以HEAD
方法再发送一次请求,解析content-length
判定文件大小。
HEAD
当GET
看,直接返回整个文件?还是和图片浏览器插件冲突。
按理说,我保留了原始img
节点,onclick
啥的应该都还保留着?
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<script>
const blocks = {
userimg: {type: 'img', icon: 'image'},
iframe_box: {type: 'iframe', icon: 'web'},
audio_box: {type: 'audio', icon: 'audiotrack'},
video_box: {type: 'video', icon: 'movie'},
};
function formatSize(size) {
const i = size && Math.floor(Math.log(size) / Math.log(1024));
return (size / (1 << (10 * i))).toFixed(i && 2) + ' ' + ' KMGT'[i].trim() + 'B';
}
customElements.define('my-button', class extends HTMLElement {
#ref = {};
#orig_node;
#media_src;
#media_node;
#createElementFromObject(obj) {
let el = document.createElement(obj.tag);
for (const k in obj) {
if (k === 'children')
obj.children.forEach(c => el.appendChild(this.#createElementFromObject(c)));
else if (k === 'text')
el.textContent = obj[k];
else if (k === 'ref')
this.#ref[obj[k]] = el;
else if (k !== 'tag')
el.setAttribute(k, obj[k]);
}
return el;
}
constructor() {
super();
// 创建一个 shadow root
let shadow = this.attachShadow({mode: 'open'});
[
{tag: 'link', rel: 'stylesheet', href: 'https://unpkg.com/material-components-web@latest/dist/material-components-web.min.css'},
{tag: 'link', rel: 'stylesheet', href: 'https://fonts.googleapis.com/icon?family=Material+Icons'},
{tag: 'script', src: 'https://unpkg.com/material-components-web@latest/dist/material-components-web.min.js'},
{tag: 'button', class: 'mdc-fab mdc-fab--extended', style: 'margin: 10px', children: [
{tag: 'div', class: 'mdc-fab__ripple'},
{tag: 'span', class: 'material-icons mdc-fab__icon', ref: 'icon'},
{tag: 'span', class: 'mdc-fab__label', ref: 'text'},
]},
{tag: 'style', text: `
:host {
/* --mdc-theme-primary: #e74c3c; */
--mdc-theme-secondary: #fafafa;
/* --mdc-theme-background: #f00; */
/* --mdc-theme-on-primary: #fff; */
--mdc-theme-on-secondary: #2c3e50;
}
`},
].forEach(x => shadow.appendChild(this.#createElementFromObject(x)));
this.onclick = this.recover;
}
get text() {
return this.#ref.text.textContent;
}
set text(s) {
this.#ref.text.textContent = s;
}
get icon() {
return this.#ref.icon.textContent;
}
set icon(s) {
this.#ref.icon.textContent = s;
}
// onclick() { // 为什么不能这样重写方法??
recover() {
this.#media_node.src &&= this.#media_src;
this.parentNode.replaceChild(this.#orig_node, this);
delete this;
}
// 替换掉旧节点,展示本按钮
replace(root_node, media_node) {
this.#orig_node = root_node.parentNode.replaceChild(this, root_node);
this.#media_node = media_node;
this.#media_src = media_node.src;
media_node.src &&= ' ';
// 询问目标链接大小,太大则等待用户选择,较小直接显示
if (this.#media_src) {
fetch(this.#media_src, {method: 'HEAD'}).then(resp => {
if (resp.ok) {
const size = parseInt(resp.headers.get('content-length'));
if (size < (1 << 20) && this.icon === blocks.userimg.icon)
this.recover();
else if (size > 0)
this.text += `(${formatSize(size)})`;
}
});
}
}
});
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll(Object.keys(blocks).map(x => `.${x}`).join()).forEach(x => {
// 获取 element 类型、显示按钮时的图标
const {type, icon} = Object.entries(blocks).find(([k]) => x.classList.contains(k))[1];
// 若图片已下载完毕,就让它显示吧
if (type === 'img' && x.complete)
return;
// 获取真正的多媒体节点
const media_node = ['audio', 'video'].includes(type) ? x.querySelector(type) : x;
// 图片有外层链接,则准备替换整个外层
if (type === 'img' && x.parentNode.href)
x = x.parentNode;
// 创建按钮
let el = document.createElement('my-button');
el.icon = icon;
el.text = type === 'iframe' ? '内嵌网页' : media_node.alt || media_node.src;
el.replace(x, media_node);
});
});
</script>
@无名啊,有没有直接获取文件大小的方法
,有,file.hu60.cn
的文件大小在URL末尾。此外新上传的图片,alt
里也会有文件大小。
function getSizeFromUrl(url) {
url = hu60_decode_url64(url);
var parts = url.match(/\/file\/(?:hash\/[^\/]+\/[a-f0-9]{32}|uuid\/[^\/]+\/[a-f0-9-]{36})(\d+)\b/);
return parts ? parseInt(parts[1]) : 0;
}
function getImgSize(img) {
if (img.alt) {
var parts = img.alt.match(/([0-9]+(:?\.[0-9]+)?\s*(?:[KMGT]B|bytes))/);
if (parts) return parts[1];
}
var size = getSizeFromUrl(img.src);
return size > 0 ? humanize.filesize(size) : '';
}
function getSizeFromUrl(url) {
url = hu60_decode_url64(url);
var parts = url.match(/\/file\/(?:hash\/[^\/]+\/[a-f0-9]{32}|uuid\/[^\/]+\/[a-f0-9-]{36})(\d+)\b/);
return parts ? parseInt(parts[1]) : 0;
}
获取文件大小。
文件路径是这样生成的:
if ($fileMd5 !== null) {
$key = 'file/hash/' . $type . '/' . $fileMd5 . $fileSize . $ext;
} else {
$uuid = str::guidv4();
$key = 'file/uuid/' . $type . '/' . $uuid . $fileSize . $ext;
}