您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
主图、SKU、详情和视频打包下载
当前为
// ==UserScript== // @name 淘宝天猫图片打包下载 // @version 0.6.0 // @description 主图、SKU、详情和视频打包下载 // @author lelf(原作者)suren(修改) // @match *://item.taobao.com/* // @match *://detail.tmall.com/* // @require https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js // @require https://cdn.bootcss.com/materialize/1.0.0-rc.2/js/materialize.min.js // @require https://cdn.bootcss.com/jszip/3.2.2/jszip.min.js // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/FileSaver.min.js // @require https://cdn.bootcss.com/jszip-utils/0.1.0/jszip-utils.min.js // @resource lelf-materialcss https://cdn.jsdelivr.net/gh/lelf2005/cdn@master/material.css?v=20200630 // @grant GM_addStyle // @grant GM_getResourceText // @license MIT // @namespace https://greasyfork.org/users/786427 // ==/UserScript== (function() { 'use strict'; var $ = $ || window.$; var materialcss = GM_getResourceText('lelf-materialcss'); GM_addStyle(materialcss); addMenu(); var zipImgs; var zipDetailImgs; let splitImgZip //=====<-在详情页面添加下载图标->===== function addMenu() { var DLBtn = ` <div class="fixed-action-btn"> <a id="lelf_tb" class="btn-floating light-blue darken-3 modal-trigger" style="left: -50px;" href="#lelf_modal2" title="详情打包下载"> <div class="lelf-icon-download"></div> </a> </div>`; $("body").append(DLBtn);//用append在body内加入DLBtn $("#lelf_tb").click(function(){ getTBPics();//获取所有图片 $('#lelf_modal2').modal();//打开弹窗 }); } //=====<-获取所有内容->===== function getTBPics(){ zipImgs = [];//定义压缩包内主图、SKU图片数组 zipDetailImgs = [];//定义压缩包内详情页图片数组 var mainVideoHtml = '';//定义视频代码 var imgHtml = '';//定义主图html代码 var skuImgHtml = '';//定义SKU图html代码 var detailImgHtml = '';//定义详情页html代码 var imgSrc = '';//定义主图地址 var skuImgSrc = '';//定义SKU图地址 var detailImgSrc = '';//定义详情页图片地址 var NewOROld = document.getElementById("J_SiteNav");//通过旧版ID:J_SiteNav定义判断值 //=====<-判断新旧版本并获取资源位置->===== var isBlobVideo = false; if(NewOROld){ var mainVideo = $("video").find("source");//旧版视频位置 var mainImg = $("#J_UlThumb").find("img");//旧版主图位置 var skuImg = $(".tb-sku .tm-img-prop").find("a");//旧版SKU图位置 var detailImg = $("#description > .content").find("img");//旧版详情页位置 } else{ var mainVideo = $(".lib-video").find("video");//新版视频位置 var mainImg = $("ul").find("img");//新版主图位置 var skuImg = $(".skuCate").find("img");//新版SKU位置 var detailImg = $(".desc-root").find("img");//新版详情页位置 } //=====<-获取视频内容->===== if(mainVideo.length > 0){ mainVideo[0].src = mainVideo[0].src.substring(0, mainVideo[0].src.lastIndexOf("?")); mainVideoHtml = ''+ ' <div class="row" style="margin-left:0px;margin-top:10px;background-color:rgba(0, 0, 0, 0.1);"><p style="font-size:24px;margin-left:10px;">| 主图视频:</p></div>'+ ' <div class="row" style="margin-left:10px;">'+ ' <video class="responsive-video" width="300" height="400" style="border-radius: 10px;" controls>'+ ' <source src="'+mainVideo[0].src+'" type="video/mp4">'+ ' </video>'+ ' </div>'; zipImgs.push(mainVideo[0].src);//将视频放入压缩包 } else if($("video").length > 0){ mainVideoHtml = '<div class="row" style="margin-left:0px;margin-top:10px;background-color:rgba(0, 0, 0, 0.1);"><p style="color:#888888;font-size:24px;margin-left:10px;text-decoration: line-through;">| 糟糕!视频被藏起来了!</p></div>'; } //=====<-获取主图内容->===== for(var i =0; i< mainImg.length;i++){ imgSrc = mainImg[i].src; if(imgSrc.lastIndexOf("webp")>-1){ imgSrc = imgSrc.substring(0, imgSrc.lastIndexOf('_', imgSrc.lastIndexOf('_') - 1)); } else{ imgSrc = imgSrc.substring(0, imgSrc.lastIndexOf("_")); } zipImgs.push(imgSrc);//将主图放入压缩包 imgHtml += '<div class="col s2"><img class="materialboxed" style="width:100%;border-radius: 10px;margin: 10px;" src="'+imgSrc+'"></div>'; } //=====<-获取SKU内容->===== if(NewOROld){ if(skuImg.length == 0){//旧版 skuImg = $(".tb-skin .tb-img").find("a"); } for(var n =0; n< skuImg.length;n++){ if(skuImg[n].style.background){ skuImgSrc = skuImg[n].style.background.split("(")[1].split(")")[0]; skuImgSrc = skuImgSrc.substring(1,skuImgSrc.lastIndexOf("_")); zipImgs.push(skuImgSrc);//将SKU图放入压缩包 skuImgHtml += '<div class="col s2"><img class="materialboxed" style="width:100%;padding:10px;" src="'+skuImgSrc+'"></div>'; } } } else{ for(var i =0; i< skuImg.length;i++){//新版 skuImgSrc = skuImg[i].src; if(skuImgSrc.lastIndexOf("webp")>-1){ skuImgSrc = skuImgSrc.substring(0, skuImgSrc.lastIndexOf('_', skuImgSrc.lastIndexOf('_') - 1)); } else{ skuImgSrc = skuImgSrc.substring(0, skuImgSrc.lastIndexOf("_")); } zipImgs.push(skuImgSrc);//将SKU图放入压缩包 skuImgHtml += '<div class="col s2"><img class="materialboxed" style="width:100%;border-radius: 10px;margin: 10px;" src="'+skuImgSrc+'"></div>'; } } //=====<-获取详情页内容->===== for(var k =0; k< detailImg.length;k++){ if(detailImg[k].getAttribute("data-ks-lazyload") !== null){ detailImgSrc = detailImg[k].getAttribute("data-ks-lazyload"); } else{ detailImgSrc = detailImg[k].src; } if(detailImg[k].naturalWidth > 100 ){ zipDetailImgs.push(detailImgSrc);//将详情图放入压缩包 detailImgHtml += '<div class="col s12"><img class="materialboxed" style="width:790px;margin: auto;" src="'+detailImgSrc+'"></div>'; } } addTBHtml(mainVideoHtml,imgHtml,skuImgHtml,detailImgHtml); $('.materialboxed').materialbox(); } //=====<-将内容在弹窗内展现->===== function addTBHtml(video,imgs,skuImgs,detailImgs){ var isAdded = $("#lelf_modal2"); if(isAdded.length > 0){ isAdded.remove(); } var s = ''+ '<div id="lelf_modal2" class="modal modal-fixed-footer" style="height:100%;max-height:80%;">'+ ' <div class="modal-content">'+ ' <h4 class="h4" style="text-align: center;">—— 详情套图打包下载工具 ——</h4>'+ ' <div class="row">'+ ' <div class="col s12">'+ ' <ul class="tabs">'+ ' <li class="tab col s2"><a class="active" href="#main_pics">视频、主图、SKU图</a></li>'+ ' <li class="tab col s2"><a href="#detail_pics">详情页预览</a></li>'+ ' <li class="tab col s2"><a href="#detail_pics_splitter">切片合并</a></li>'+ ' </ul>'+ ' </div>'+ ' <div id="main_pics" class="col s12">'+video+'<div class="row" style="margin-left:0px;margin-top:10px;background-color:rgba(0, 0, 0, 0.1);">'+ ' <p style="font-size:24px;margin-left:10px;">| 主图:</p></div>'+ ' <div class="row">'+imgs+'</div>'+ ' <div class="row" style="margin-left:0px;margin-top:10px;background-color:rgba(0, 0, 0, 0.1);">'+ ' <p style="font-size:24px;margin-left:10px;">| SKU图:</p>'+ ' </div>'+ ' <div class="row">'+skuImgs+'</div>'+ ' </div>'+ ' <div id="detail_pics" class="col s12">'+detailImgs+'</div>'+ ' <div id="detail_pics_splitter" class="col s12">'+ ' <div style="display:flex;justify-content:center;margin:10px;align-items:center;">'+ ' <a class="waves-effect waves-light btn" style="margin-right:10px;margin-top:10px;font-size:24px;" id="mergeImgs">合并成长版</a>'+ ' </div>'+ ' <div style="display:flex;justify-content:center;margin:10px;align-items:start;">'+ ' <div id="mergePreview"></div>'+ ' </div>'+ ' </div>'+ ' <canvas id="mycanvas" style="display:none;"></canvas>'+ '</div>'+ '</div>'+ ' <div class="modal-footer">'+ ' <a href="#!" id="lelf-msg" class="modal-close waves-effect waves-green btn-flat"></a>'+ ' <a id="lelf_tbpic_download" class="waves-effect waves-light btn">下载</a>'+ ' <a href="#!" class="modal-close waves-effect red lighten-1 waves-green btn-flat">关闭</a>'+ ' </div>'+ '</div>'; $("body").append(s);//向body内插入上述代码 var instance = M.Tabs.init($('.tabs'), '{}'); $('.tabs').tabs('updateTabIndicator'); var itemId = window.location.href.split("id=")[1].split('&')[0]; if(itemId === null && itemId.toString().length<0){ itemId="unknown"; } $("#lelf_tbpic_download").click(function(){ var zip = new JSZip(); var mainImgs = zip.folder("main"); var detailImgs = zip.folder("detail"); var suffix = ''; var totalAssets = zipImgs.length + zipDetailImgs.length; var currentAsset = 0; for(var i=0;i<zipImgs.length;i++){ suffix = zipImgs[i].substring(zipImgs[i].lastIndexOf(".") + 1, zipImgs[i].length); mainImgs.file(i.toString()+'.'+suffix, urlToPromise(zipImgs[i]), {binary:true}); currentAsset++; $("#lelf-msg").text("处理中:"+currentAsset+"/"+totalAssets); } for(var j=0;j<zipDetailImgs.length;j++){ suffix = zipDetailImgs[j].substring(zipDetailImgs[j].lastIndexOf(".") + 1, zipDetailImgs[j].length); detailImgs.file(j.toString()+'.'+suffix, urlToPromise(zipDetailImgs[j]), {binary:true}); currentAsset++; $("#lelf-msg").text("处理中:"+currentAsset+"/"+totalAssets); } zip.generateAsync({type:"blob"}) .then(function callback(blob) { $("#lelf-msg").text("打包中:"+currentAsset+"/"+totalAssets); saveAs(blob, itemId+".zip"); $("#lelf-msg").text("已完成:"+currentAsset+"/"+totalAssets); }); }); $('#mergeImgs').click(function(){ let merger = new Merger(document.getElementById('mycanvas'), Image); merger.merge(zipDetailImgs, imgPreview); document.getElementById("splitImg").classList.remove('disabled'); }); } function urlToPromise(url) { return new Promise(function(resolve, reject) { JSZipUtils.getBinaryContent(url, function (err, data) { if(err) { reject(err); } else { resolve(data); } }); }); } class Merger { constructor(canvas, Image) { this.canvas = canvas; this.Image = Image; this.ctx = this.canvas.getContext("2d"); } async merge(urls, cb) { const imgs = await this.loadImages(urls); const map = []; const gap = 0; const scale = 1; const maxWidth = imgs.reduce((m, x) => Math.max(m, x.width), 0); const maxHeight = imgs.reduce((m, x) => m + x.height + gap, 0); let canvash = 0; for (let i = 0; i < urls.length; i += 1) { const url = urls[i]; const { width , height } = imgs[i] ; canvash += (height / width) * 790 + gap; } this.canvas.width = 790; this.canvas.height = canvash; let y = 0; const x = 0; for (let i = 0; i < urls.length; i += 1) { const url = urls[i]; let name = ""; if (typeof File === "function" && url instanceof File) { name = url.name.split(".").shift(); } else { name = url .split("/") .pop() .split(".") .shift(); } const { width , height } = imgs[i] ; this.ctx.drawImage(imgs[i], x, y, 790, (height / width) * 790); map.push([name, x, y, width, height]); y += (height / width) * 790 + gap; } cb(); } loadImages(urls) { const imgs = []; let count = 0; const { length } = urls; return new Promise((resolve, reject) => { for (let i = 0; i < urls.length; i += 1) { const img = new this.Image(); img.setAttribute("crossOrigin",'Anonymous') const url = urls[i]; img.onerror = reject; img.onload = () => { imgs[i] = img; count += 1; if (count === length) resolve(imgs); }; if (typeof File === "function" && url instanceof File) { const reader = new FileReader(); reader.addEventListener( "load", () => { img.src = reader.result; }, false ); reader.readAsDataURL(url); } else { img.src = url; } } }); } } function imgPreview(){ const preview = document.createElement('img'); preview.src = document.getElementById("mycanvas").toDataURL(); preview.style.width = "100%"; preview.style.border = "1px solid #a2de96"; document.getElementById("mergePreview").appendChild(preview); $('#mergeImgs').html('长版详情分辨率:('+document.getElementById("mycanvas").width+'*'+document.getElementById("mycanvas").height+') / 右键另存为'); } // Your code here... })();