625 lines
24 KiB
JavaScript
625 lines
24 KiB
JavaScript
// 部分代码来自ZIBILL主题作者
|
|
// canvas生成海报
|
|
const poster = (function() {
|
|
|
|
const DEBUG = false
|
|
|
|
const WIDTH = 700
|
|
const HEIGHT = 850
|
|
|
|
/**
|
|
* 将图片URL加载为Image对象,并返回Promise
|
|
* @param {string} url - 图片URL
|
|
* @returns {Promise<Image>} - 加载完成的Image对象
|
|
*/
|
|
function loadImage(url) {
|
|
return new Promise((resolve, reject) => {
|
|
const img = new Image();
|
|
img.crossOrigin = "Anonymous";
|
|
img.onload = () => resolve(img);
|
|
img.onerror = () => reject(new Error('Failed to load image: ' + url));
|
|
img.src = url;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 核心初始化函数
|
|
* @param {object} config - 配置对象
|
|
*/
|
|
function init(config) {
|
|
const $container = config.container || document.querySelector(config.selector)
|
|
if (!$container) {
|
|
if (config.callback) {
|
|
config.callback(null)
|
|
}
|
|
return
|
|
}
|
|
// ------------------ 【修复点 2:清理容器,避免PJAX残余】 ------------------
|
|
// 在重新绘制前,确保清空容器,移除旧的 img 和 wrapper
|
|
$container.innerHTML = '';
|
|
// -----------------------------------------------------------------------
|
|
|
|
$container.style.border = '1px solid #f0f0f0'
|
|
const $wrapper = createDom('div', 'id', 'wrapper')
|
|
const $canvas = createDom('canvas', 'id', 'canvas', 'block')
|
|
const $day = createDom('canvas', 'id', 'day')
|
|
const $date = createDom('canvas', 'id', 'date')
|
|
const $title = createDom('canvas', 'id', 'title')
|
|
const $content = createDom('canvas', 'id', 'content')
|
|
const $logo = createDom('canvas', 'id', 'logo')
|
|
const $siteName = createDom('canvas', 'id', 'siteName')
|
|
const $description = createDom('canvas', 'id', 'description')
|
|
const $customText1 = createDom('canvas', 'id', 'customText1')
|
|
const $customText2 = createDom('canvas', 'id', 'customText2')
|
|
|
|
appendChilds($wrapper, $canvas, $day, $siteName, $date, $title, $content, $logo, $description, $customText1, $customText2)
|
|
$container.appendChild($wrapper)
|
|
|
|
const date = new Date()
|
|
|
|
// day canvas
|
|
const dayStyle = {
|
|
font: 'bold 80px Helvetica',
|
|
color: 'rgba(255, 255, 255, 1)',
|
|
position: 'right'
|
|
}
|
|
drawOneline($day, dayStyle, date.getDate());
|
|
|
|
// date canvas
|
|
const dateStyle = {
|
|
font: '23px Helvetica',
|
|
color: 'rgba(255, 255, 255, 1)',
|
|
position: 'right'
|
|
}
|
|
drawOneline($date, dateStyle, date.getFullYear() + '/' + (date.getMonth() + 1))
|
|
|
|
// title canvas
|
|
const titleStyle = {
|
|
font: '30px Helvetica',
|
|
lineHeight: 1.5,
|
|
color: 'rgba(255, 255, 255, 1)',
|
|
length: 2,
|
|
position: 'left'
|
|
}
|
|
titleStyle.font = (config.titleStyle && config.titleStyle.font) || titleStyle.font
|
|
titleStyle.color = (config.titleStyle && config.titleStyle.color) || titleStyle.color
|
|
titleStyle.position = (config.titleStyle && config.titleStyle.position) || titleStyle.position
|
|
drawMoreLines($title, titleStyle, config.title)
|
|
|
|
// site name canvas
|
|
const siteNameStyle = {
|
|
font: '40px Helvetica',
|
|
lineHeight: 1.3,
|
|
color: 'rgba(255, 255, 255, 0.95)',
|
|
position: 'left'
|
|
}
|
|
siteNameStyle.font = (config.siteNameStyle && config.siteNameStyle.font) || siteNameStyle.font
|
|
siteNameStyle.color = (config.siteNameStyle && config.siteNameStyle.color) || siteNameStyle.color
|
|
siteNameStyle.lineHeight = (config.siteNameStyle && config.siteNameStyle.lineHeight) || siteNameStyle.lineHeight
|
|
siteNameStyle.position = (config.siteNameStyle && config.siteNameStyle.position) || siteNameStyle.position
|
|
drawMoreLines($siteName, siteNameStyle, config.siteName)
|
|
|
|
// description canvas
|
|
const descriptionStyle = {
|
|
font: '25px Helvetica',
|
|
color: 'rgba(236, 241, 255, 1)',
|
|
lineHeight: 1.2,
|
|
position: 'left'
|
|
}
|
|
descriptionStyle.font = (config.descriptionStyle && config.descriptionStyle.font) || descriptionStyle.font
|
|
descriptionStyle.color = (config.descriptionStyle && config.descriptionStyle.color) || descriptionStyle.color
|
|
descriptionStyle.lineHeight = (config.descriptionStyle && config.descriptionStyle.lineHeight) || descriptionStyle.lineHeight
|
|
descriptionStyle.position = (config.descriptionStyle && config.descriptionStyle.position) || descriptionStyle.position
|
|
drawMoreLines($description, descriptionStyle, config.description)
|
|
|
|
// custom text 1 canvas
|
|
const customText1Style = {
|
|
font: '28px Helvetica',
|
|
lineHeight: 1.3,
|
|
position: 'left',
|
|
color: 'rgba(0, 0, 0, 1)'
|
|
}
|
|
customText1Style.font = (config.customText1Style && config.customText1Style.font) || customText1Style.font
|
|
customText1Style.color = (config.customText1Style && config.customText1Style.color) || customText1Style.color
|
|
customText1Style.lineHeight = (config.customText1Style && config.customText1Style.lineHeight) || customText1Style.lineHeight
|
|
customText1Style.position = (config.customText1Style && config.customText1Style.position) || customText1Style.position
|
|
drawMoreLines($customText1, customText1Style, config.customText1 || '')
|
|
|
|
// custom text 2 canvas
|
|
const customText2Style = {
|
|
font: '28px Helvetica',
|
|
lineHeight: 1.3,
|
|
position: 'left',
|
|
color: 'rgba(0, 0, 0, 1)'
|
|
}
|
|
customText2Style.font = (config.customText2Style && config.customText2Style.font) || customText2Style.font
|
|
customText2Style.color = (config.customText2Style && config.customText2Style.color) || customText2Style.color
|
|
customText2Style.lineHeight = (config.customText2Style && config.customText2Style.lineHeight) || customText2Style.lineHeight
|
|
customText2Style.position = (config.customText2Style && config.customText2Style.position) || customText2Style.position
|
|
drawMoreLines($customText2, customText2Style, config.customText2 || '')
|
|
|
|
// content canvas
|
|
const contentStyle = {
|
|
font: '22px Helvetica',
|
|
lineHeight: 1.5,
|
|
position: 'left',
|
|
color: 'rgba(236, 241, 255, 1)'
|
|
}
|
|
contentStyle.font = (config.contentStyle && config.contentStyle.font) || contentStyle.font
|
|
contentStyle.color = (config.contentStyle && config.contentStyle.color) || contentStyle.color
|
|
contentStyle.lineHeight = (config.contentStyle && config.contentStyle.lineHeight) || contentStyle.lineHeight
|
|
contentStyle.position = (config.contentStyle && config.contentStyle.position) || contentStyle.position
|
|
drawMoreLines($content, contentStyle, config.content);
|
|
|
|
|
|
// ------------------ 【修复点 1:使用 Promise.all 等待所有图片加载】 ------------------
|
|
Promise.all([
|
|
loadImage(config.banner),
|
|
loadImage(config.logo),
|
|
loadImage(config.qrcode)
|
|
]).then(([image, logo, qrcode]) => {
|
|
|
|
$canvas.width = WIDTH;
|
|
$canvas.height = HEIGHT;
|
|
const ctx = $canvas.getContext('2d')
|
|
|
|
// 1. 绘制背景
|
|
ctx.fillStyle = 'rgba(255, 255, 255, 1)';
|
|
ctx.fillRect(0, 0, $canvas.width, $canvas.height);
|
|
|
|
// 2. 绘制 Banner
|
|
const imgRect = coverImg($canvas.width - 40, $canvas.height / 1.2 - 40, image.width, image.height);
|
|
ctx.drawImage(image, imgRect.sx, imgRect.sy, imgRect.sWidth, imgRect.sHeight, 20, 20, $canvas.width - 40, $canvas.height / 1.2 - 40);
|
|
|
|
// 3. 绘制覆盖层
|
|
ctx.fillStyle="rgba(0, 0, 0, 0.6)";
|
|
ctx.fillRect(20, 20, $canvas.width - 40, $canvas.height / 1.2 - 40);
|
|
|
|
// 4. 绘制时间 (使用预先绘制好的 Canvas)
|
|
ctx.drawImage($day, -20, 50)
|
|
ctx.drawImage($date, -21, 125)
|
|
|
|
// 5. 绘制 Logo
|
|
var logoh = 140;
|
|
var cwidth = logoh * (logo.width / logo.height);
|
|
ctx.drawImage(logo, 20, $canvas.height / 1.2 - 10, cwidth, logoh);
|
|
|
|
// 6. 绘制二维码
|
|
ctx.drawImage(qrcode, $canvas.width - 150, $canvas.height / 1.2 + 10, 120, 120);
|
|
|
|
// 7. 绘制文字 (使用预先绘制好的 Canvas)
|
|
ctx.drawImage($siteName, 10, 60)
|
|
ctx.drawImage($description, 10, 120)
|
|
ctx.drawImage($customText1, 270, $canvas.height / 2 + 310)
|
|
ctx.drawImage($customText2, 215, $canvas.height / 2 + 360)
|
|
ctx.drawImage($title, 20, $canvas.height / 2 + 60)
|
|
ctx.drawImage($content, 20, $canvas.height / 2 + 120)
|
|
ctx.strokeStyle = 'rgba(122, 122, 122, 0.5)';
|
|
|
|
// 8. 转换并显示最终图片
|
|
const img = new Image();
|
|
img.crossOrigin = "Anonymous";
|
|
img.src = $canvas.toDataURL('image/png')
|
|
const radio = config.radio || 0.7
|
|
img.width = WIDTH * radio
|
|
img.height = HEIGHT * radio
|
|
img.className = 'poster_load';
|
|
|
|
// 清理 Canvas 避免在屏幕上停留
|
|
ctx.clearRect(0, 0, $canvas.width, $canvas.height)
|
|
$canvas.style.display = 'none'
|
|
|
|
// 移除旧的 wrapper 并添加最终海报图
|
|
$container.appendChild(img);
|
|
// 必须先移除再调用 callback,以确保 DOM 结构干净
|
|
$container.removeChild($wrapper)
|
|
|
|
if (config.callback) {
|
|
config.callback($container)
|
|
}
|
|
}).catch(error => {
|
|
console.error('海报图片加载失败:', error);
|
|
// 可在此处添加错误处理,例如显示一个错误信息
|
|
if ($wrapper.parentNode === $container) {
|
|
$container.removeChild($wrapper);
|
|
}
|
|
if (config.callback) {
|
|
// 即使失败也调用回调,传入 null 或错误信息,以便上层逻辑处理
|
|
config.callback(null);
|
|
}
|
|
});
|
|
// -----------------------------------------------------------------------
|
|
}
|
|
|
|
// 裁剪函数(不变)
|
|
function containImg(sx, sy, box_w, box_h, source_w, source_h) {
|
|
var dx = sx,
|
|
dy = sy,
|
|
dWidth = box_w,
|
|
dHeight = box_h;
|
|
if (source_w > source_h || (source_w == source_h && box_w < box_h)) {
|
|
dHeight = source_h * dWidth / source_w;
|
|
dy = sy + (box_h - dHeight) / 2;
|
|
|
|
} else if (source_w < source_h || (source_w == source_h && box_w > box_h)) {
|
|
dWidth = source_w * dHeight / source_h;
|
|
dx = sx + (box_w - dWidth) / 2;
|
|
}
|
|
return {
|
|
dx,
|
|
dy,
|
|
dWidth,
|
|
dHeight
|
|
}
|
|
}
|
|
|
|
// 覆盖函数:按目标区域等比缩放并居中裁切,尽量不留白
|
|
function coverImg(box_w, box_h, source_w, source_h) {
|
|
const scale = Math.max(box_w / source_w, box_h / source_h);
|
|
const sWidth = box_w / scale;
|
|
const sHeight = box_h / scale;
|
|
const sx = (source_w - sWidth) / 2;
|
|
const sy = (source_h - sHeight) / 2;
|
|
|
|
return {
|
|
sx,
|
|
sy,
|
|
sWidth,
|
|
sHeight
|
|
}
|
|
}
|
|
|
|
// 创建 DOM 元素(不变)
|
|
function createDom(name, key, value, display = 'none') {
|
|
const $dom = document.createElement(name)
|
|
$dom.setAttribute(key, value)
|
|
$dom.style.display = display
|
|
$dom.width = WIDTH
|
|
$dom.height = HEIGHT // 新增:确保 canvas 都有默认高度,尽管后续会重设
|
|
return $dom
|
|
}
|
|
|
|
// 追加子元素(不变)
|
|
function appendChilds(parent, ...doms) {
|
|
doms.forEach(dom => {
|
|
parent.appendChild(dom)
|
|
})
|
|
}
|
|
|
|
// 绘制单行文本(不变)
|
|
function drawOneline(canvas, style, content) {
|
|
const ctx = canvas.getContext('2d')
|
|
canvas.height = parseInt(style.font.match(/\d+/), 10) + 20
|
|
ctx.font = style.font
|
|
ctx.fillStyle = style.color
|
|
ctx.textBaseline = 'top'
|
|
|
|
let lineWidth = 0
|
|
let idx = 0
|
|
let truncated = false
|
|
for (let i = 0; i < content.length; i++) {
|
|
lineWidth += ctx.measureText(content[i]).width;
|
|
if (lineWidth > canvas.width - 60) {
|
|
truncated = true
|
|
idx = i
|
|
break
|
|
}
|
|
}
|
|
|
|
let padding = 30
|
|
|
|
if (truncated) {
|
|
content = content.substring(0, idx)
|
|
// 修正:如果内容被截断,应该重新计算截断后的文本宽度,再计算 padding
|
|
lineWidth = ctx.measureText(content).width;
|
|
if (style.position === 'center') {
|
|
padding = canvas.width / 2 - lineWidth / 2;
|
|
} else if (style.position === 'left') {
|
|
padding = 30; // 保持左侧间距
|
|
} else {
|
|
padding = canvas.width - 30; // 保持右侧间距
|
|
}
|
|
}
|
|
|
|
if (DEBUG) {
|
|
ctx.strokeStyle = "#6fda92";
|
|
ctx.strokeRect(0, 0, canvas.width, canvas.height);
|
|
}
|
|
|
|
if (style.position === 'center') {
|
|
ctx.textAlign = 'center';
|
|
ctx.fillText(content, canvas.width / 2, 0)
|
|
} else if (style.position === 'left') {
|
|
ctx.textAlign = 'left'
|
|
ctx.fillText(content, padding, 0)
|
|
} else {
|
|
ctx.textAlign = 'right'
|
|
ctx.fillText(content, canvas.width - padding, 0)
|
|
}
|
|
}
|
|
|
|
// 绘制多行文本(不变)
|
|
function drawMoreLines(canvas, style, content) {
|
|
const ctx = canvas.getContext('2d')
|
|
const fontHeight = parseInt(style.font.match(/\d+/), 10)
|
|
let totalLines = 0;
|
|
|
|
// 预计算行高并设置 Canvas 高度
|
|
let lineWidth = 0
|
|
let currentLine = 0
|
|
for (let i = 0; i < content.length; i++) {
|
|
lineWidth += ctx.measureText(content[i]).width;
|
|
if (lineWidth > canvas.width - 120) {
|
|
currentLine++;
|
|
lineWidth = 0
|
|
}
|
|
if (i === content.length - 1) {
|
|
currentLine++;
|
|
}
|
|
}
|
|
totalLines = currentLine;
|
|
canvas.height = (fontHeight * style.lineHeight) * totalLines + 20; // 留出一些底部边距
|
|
|
|
if (DEBUG) {
|
|
ctx.strokeStyle = "#6fda92";
|
|
ctx.strokeRect(0, 0, canvas.width, canvas.height);
|
|
}
|
|
|
|
ctx.font = style.font
|
|
ctx.fillStyle = style.color
|
|
ctx.textBaseline = 'top'
|
|
ctx.textAlign = 'center'
|
|
|
|
let alignX = 0
|
|
|
|
if (style.position === 'center') {
|
|
alignX = canvas.width / 2;
|
|
} else if (style.position === 'left') {
|
|
ctx.textAlign = 'left'
|
|
alignX = 40
|
|
} else {
|
|
ctx.textAlign = 'right'
|
|
alignX = canvas.width - 40
|
|
}
|
|
|
|
lineWidth = 0
|
|
let lastSubStrIndex = 0
|
|
let offsetY = 0
|
|
for (let i = 0; i < content.length; i++) {
|
|
lineWidth += ctx.measureText(content[i]).width;
|
|
if (lineWidth > canvas.width - 120) {
|
|
ctx.fillText(content.substring(lastSubStrIndex, i), alignX, offsetY);
|
|
offsetY += fontHeight * style.lineHeight
|
|
lineWidth = 0
|
|
lastSubStrIndex = i
|
|
}
|
|
if (i === content.length - 1) {
|
|
ctx.fillText(content.substring(lastSubStrIndex, i + 1), alignX, offsetY);
|
|
}
|
|
}
|
|
}
|
|
|
|
return {
|
|
init
|
|
}
|
|
})()
|
|
|
|
|
|
// ajax生成文章海报
|
|
// 此处调用部分需要确保在 PJAX 环境下,该事件监听器能够重新绑定(如果使用传统的 document.ready,在 PJAX 中需要改为监听 pjax:success 等事件)
|
|
$('body').on('click', '.cr_poster', function () {
|
|
let closeLoading = null;
|
|
closeLoading = cocoMessage.loading('海报生成中...');
|
|
var $trigger = $(this);
|
|
var post_id = $(this).attr('poster-data');
|
|
var banner = $(this).attr('banner');
|
|
var single_content = $('.single-content');
|
|
var t_content = $('#post-'+post_id+' .t_content');
|
|
var modal = '#share_modal_' + post_id;
|
|
var $modalList = $(modal);
|
|
var $modal = $trigger.closest(modal);
|
|
if ($modal.length === 0) {
|
|
$modal = $(modal + ':visible').first();
|
|
}
|
|
if ($modal.length === 0) {
|
|
$modal = $modalList.first();
|
|
}
|
|
|
|
if ($modal.length === 0) {
|
|
return;
|
|
}
|
|
|
|
// 确保 content 区域存在
|
|
var content_element = single_content.length > 0 ? single_content[0] : (t_content.length > 0 ? t_content[0] : null);
|
|
|
|
if (!content_element) {
|
|
// 如果没有内容元素,则不执行后续操作或给出提示
|
|
console.error('无法获取文章内容元素。');
|
|
return;
|
|
}
|
|
|
|
var content = content_element.innerText;
|
|
var content_length = content.length;
|
|
var permalink = t_content.length > 0 ? window.location.origin + '/moments/' + post_id : window.location.origin + window.location.pathname;
|
|
var title = t_content.length > 0 ? '瞬间' : (document.title || '').split(' - ')[0];
|
|
var siteName = Theme.site_title;
|
|
|
|
// 确保 QRious 库可用
|
|
if (typeof QRious === 'undefined') {
|
|
console.error('QRious 库未加载。');
|
|
return;
|
|
}
|
|
|
|
// 检查 #twoCode 是否存在,如果不存在需要动态创建,否则 QRious 会失败
|
|
let twoCodeCanvas = document.getElementById("twoCode");
|
|
if (!twoCodeCanvas) {
|
|
twoCodeCanvas = document.createElement('canvas');
|
|
twoCodeCanvas.id = 'twoCode';
|
|
twoCodeCanvas.style.display = 'none';
|
|
document.body.appendChild(twoCodeCanvas); // 插入到 DOM 中
|
|
}
|
|
|
|
new QRious({ element: twoCodeCanvas, value: permalink, size: 260, });
|
|
|
|
var $posterBoxAp = $modal.find('.poster_box_ap').first();
|
|
if ($posterBoxAp.length === 0) {
|
|
return;
|
|
}
|
|
|
|
// ------------------ 【修复点 2:清理容器】 ------------------
|
|
// 仅在当前弹窗作用域内移除旧容器,避免影响 PJAX 残留节点
|
|
$posterBoxAp.find('.poster_box').remove();
|
|
// 重新创建并插入新的 poster_box
|
|
var $posterBox = $('<div class="poster_box"></div>');
|
|
$posterBoxAp.append($posterBox);
|
|
// -----------------------------------------------------------------------
|
|
|
|
if (content_length > 120) {
|
|
content = content.substring(0, 82) + '...'
|
|
}
|
|
|
|
// 海报生成回调
|
|
function Posterdown(e) {
|
|
// 检查海报是否成功生成
|
|
if (e && $posterBox.find('img').length > 0) {
|
|
closeLoading?.()
|
|
cocoMessage.success("海报生成成功!") // 图片加载完成后才触发
|
|
var url = $posterBox.find('img').attr('src');
|
|
var $shareBox = $modal.find('.post_share_box');
|
|
|
|
$shareBox.removeClass('hide');
|
|
$modal.find('.poster_download').attr('href', url).attr('download', 'poster_' + post_id + '.png');
|
|
} else {
|
|
// 错误处理,如果海报生成失败
|
|
closeLoading?. ();
|
|
cocoMessage.error("海报生成失败,请重试!")
|
|
}
|
|
}
|
|
|
|
poster.init({
|
|
banner: banner,
|
|
selector: modal + ' .poster_box',
|
|
container: $posterBox[0],
|
|
title: title,
|
|
siteName: siteName,
|
|
description: Theme.admin_des,
|
|
content: content,
|
|
logo: Theme.site_logo,
|
|
qrcode: $('#twoCode').attr('src'),
|
|
customText1: '扫描右侧二维码',
|
|
customText2: '或访问:https://anian.net',
|
|
customText1Style: {
|
|
font: '24px Helvetica',
|
|
color: 'rgba(0, 0, 0, 1)'
|
|
},
|
|
customText2Style: {
|
|
font: '24px Helvetica',
|
|
color: 'rgba(0, 0, 0, 1)'
|
|
},
|
|
callback: Posterdown
|
|
});
|
|
});
|
|
|
|
$(document).on('pjax:success', function (event) {
|
|
// 清理 PJAX 残留的 modal:只删除那些在当前页面没有对应按钮的 modal
|
|
var allModals = $('[id^="share_modal_"]');
|
|
var currentPostIds = {};
|
|
|
|
// 收集当前页面所有的 post_id
|
|
$('.cr_poster').each(function() {
|
|
var pid = $(this).attr('poster-data');
|
|
if (pid) {
|
|
currentPostIds[pid] = true;
|
|
}
|
|
});
|
|
|
|
// 只删除残留的 modal(不在当前页面按钮列表中的)
|
|
allModals.each(function() {
|
|
var $m = $(this);
|
|
var modalId = $m.attr('id');
|
|
var postId = modalId ? modalId.replace('share_modal_', '') : null;
|
|
|
|
if (postId && !currentPostIds[postId]) {
|
|
$m.remove();
|
|
}
|
|
});
|
|
});
|
|
|
|
|
|
function convertImgToBase64(url, callback) {
|
|
var canvas = document.createElement('canvas');
|
|
var img = new Image();
|
|
img.crossOrigin = 'Anonymous';
|
|
img.onload = function () {
|
|
canvas.width = img.width;
|
|
canvas.height = img.height;
|
|
var ctx = canvas.getContext('2d');
|
|
ctx.drawImage(img, 0, 0);
|
|
var ext = img.src.substring(img.src.lastIndexOf('.') + 1).toLowerCase();
|
|
// 修正:确保 toDataURL 使用正确的 MIME type,如果是 jpg/jpeg 应使用 image/jpeg
|
|
var mimeType = (ext === 'jpg' || ext === 'jpeg') ? 'image/jpeg' : 'image/png';
|
|
var dataURL = canvas.toDataURL(mimeType);
|
|
callback(dataURL);
|
|
canvas = null;
|
|
};
|
|
img.onerror = function() {
|
|
console.error('convertImgToBase64: 无法加载图片 ' + url);
|
|
callback(null);
|
|
}
|
|
img.src = url;
|
|
}
|
|
|
|
|
|
function handleShare(e, pic, title, pathname) {
|
|
var permalink = window.location.origin + pathname;
|
|
|
|
// 确保 cocoMessage 库可用
|
|
if (typeof cocoMessage === 'undefined') {
|
|
console.error('cocoMessage 库未加载。');
|
|
// 如果 cocoMessage 不可用,可以替换为原生的 alert
|
|
if (e === 'copy') {
|
|
alert("链接已复制到剪贴板!");
|
|
}
|
|
}
|
|
|
|
switch (e) {
|
|
case 'wb':
|
|
var url = `https://service.weibo.com/share/share.php?url=${encodeURIComponent(permalink)}&type=button&language=zh_cn&pic=${encodeURIComponent(pic)}&title=${encodeURIComponent(title)}`
|
|
window.open(url);
|
|
break
|
|
case 'qzone':
|
|
var url = `https://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey?url=${encodeURIComponent(permalink)}&title=${encodeURIComponent(title)}&pics=${encodeURIComponent(pic)}`
|
|
window.open(url);
|
|
break
|
|
case "qq":
|
|
var url = `http://connect.qq.com/widget/shareqq/index.html?url=${encodeURIComponent(permalink)}&title=${encodeURIComponent(title)}&pics=${encodeURIComponent(pic)}`
|
|
window.open(url);
|
|
break;
|
|
case "copy":
|
|
if (navigator.clipboard) {
|
|
navigator.clipboard.writeText(permalink).then(function() {
|
|
cocoMessage.success("链接已复制到剪贴板!");
|
|
}, function(err) {
|
|
cocoMessage.error("复制失败,请手动复制链接");
|
|
});
|
|
} else {
|
|
// 兼容旧浏览器
|
|
var tempInput = document.createElement('input');
|
|
tempInput.value = permalink;
|
|
document.body.appendChild(tempInput);
|
|
tempInput.select();
|
|
try {
|
|
document.execCommand('copy');
|
|
cocoMessage.success("链接已复制到剪贴板!");
|
|
} catch (err) {
|
|
cocoMessage.error("复制失败,请手动复制链接");
|
|
}
|
|
document.body.removeChild(tempInput);
|
|
}
|
|
break;
|
|
default:
|
|
break
|
|
}
|
|
|
|
}
|