// ==UserScript== // @name 禁用电商平台图片缩放效果 // @name:en Disable E-commerce Image Zoom Effect // @namespace https://greasyfork.org/users/3001-hanjian-wu // @version 1.3.3 // @description 禁用淘宝、天猫、1688等电商平台的js-image-zoom效果,方便右键保存图片。修复动态类名问题 // @description:en Disable js-image-zoom effect on Taobao, Tmall, 1688 and other e-commerce platforms for easy right-click image saving. Fixed dynamic class names issue // @author hanjian wu // @homepage https://greasyfork.org/users/3001-hanjian-wu // @supportURL https://greasyfork.org/users/3001-hanjian-wu // @license MIT // @match https://*.taobao.com/item.htm* // @match https://*.tmall.com/item.htm* // @match https://*.1688.com/offer/*.html* // @match https://item.taobao.com/* // @match https://detail.tmall.com/* // @match https://detail.1688.com/* // @icon data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjQiIGhlaWdodD0iNjQiIHZpZXdCb3g9IjAgMCA2NCA2NCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0IiByeD0iOCIgZmlsbD0iIzAwN0FGRiIvPgo8cGF0aCBkPSJNMTYgMTZIMzJWMzJIMTZWMTZaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNMzYgMTZINDhWMjhIMzZWMTZaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNMTYgMzZIMjhWNDhIMTZWMzZaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNMzIgMzJINDhWNDhIMzJWMzJaIiBmaWxsPSJ3aGl0ZSIgZmlsbC1vcGFjaXR5PSIwLjciLz4KPC9zdmc+ // @grant none // @run-at document-start // @noframes // @compatible chrome // @compatible firefox // @compatible edge // @compatible safari // @downloadURL none // ==/UserScript== (function() { 'use strict'; console.log('电商图片缩放禁用脚本已启动 v1.3.3 (动态类名修复版)'); // 检测当前平台 const is1688 = window.location.hostname.includes('1688.com'); const isTaobaoTmallCommon = window.location.hostname.includes('taobao.com') || window.location.hostname.includes('tmall.com'); let zoomEventBlocked = false; let rightClickFixed = false; // 通用的类名匹配函数 function hasClassContaining(element, substring) { if (!element.classList) return false; return Array.from(element.classList).some(cls => cls.includes(substring)); } // 查找包含特定子串的元素 function findElementsWithClassContaining(substring, parent = document) { const elements = []; const allElements = parent.querySelectorAll('*'); allElements.forEach(el => { if (hasClassContaining(el, substring)) { elements.push(el); } }); return elements; } // 禁用图片缩放的主要函数 function disableImageZoom() { if (is1688) { handle1688Zoom(); } else if (isTaobaoTmallCommon) { handleTaobaoTmallZoom(); } } // 处理1688的缩放 function handle1688Zoom() { const zoomElements = document.querySelectorAll('.scale-img, .scaled-img'); zoomElements.forEach(el => { if (el.style.display !== 'none') { el.style.setProperty('display', 'none', 'important'); el.style.setProperty('visibility', 'hidden', 'important'); el.style.setProperty('opacity', '0', 'important'); el.style.setProperty('pointer-events', 'none', 'important'); } }); const previewImg = document.querySelector('.detail-gallery-preview .preview-img'); if (previewImg) { enableImageRightClick(previewImg); } } // 处理淘宝/天猫的缩放 - 使用动态类名匹配 function handleTaobaoTmallZoom() { // 隐藏缩放相关元素 const zoomElements = document.querySelectorAll('.js-image-zoom__zoomed-area, .js-image-zoom__zoomed-image, #lensDiv'); zoomElements.forEach(el => { el.style.setProperty('display', 'none', 'important'); el.style.setProperty('visibility', 'hidden', 'important'); el.style.setProperty('opacity', '0', 'important'); el.style.setProperty('pointer-events', 'none', 'important'); }); // 使用动态类名查找主图片容器 const mainPicWrappers = findElementsWithClassContaining('--mainPicWrap--'); console.log('找到主图片容器数量:', mainPicWrappers.length); mainPicWrappers.forEach(wrapper => { // 让容器事件穿透 wrapper.style.setProperty('pointer-events', 'none', 'important'); console.log('容器事件已设置为穿透:', wrapper.className); // 查找容器内的主图片 const mainPics = Array.from(wrapper.querySelectorAll('img')).filter(img => hasClassContaining(img, '--mainPic--') ); console.log('在容器中找到主图片数量:', mainPics.length); mainPics.forEach(mainPic => { // 恢复图片的鼠标事件 mainPic.style.setProperty('pointer-events', 'auto', 'important'); mainPic.style.setProperty('position', 'relative', 'important'); mainPic.style.setProperty('z-index', '9999', 'important'); enableImageRightClick(mainPic); console.log('已修复图片右键功能:', mainPic.src); }); }); // 确保其他交互元素正常工作 fixOtherInteractiveElements(); } // 修复其他交互元素 function fixOtherInteractiveElements() { // 缩略图 const thumbnails = findElementsWithClassContaining('--thumbnail--'); thumbnails.forEach(thumb => { thumb.style.setProperty('pointer-events', 'auto', 'important'); const thumbImgs = Array.from(thumb.querySelectorAll('img')).filter(img => hasClassContaining(img, '--thumbnailPic--') ); thumbImgs.forEach(thumbImg => { thumbImg.style.setProperty('pointer-events', 'auto', 'important'); }); }); // 切换标签 const switchTabs = findElementsWithClassContaining('--switchTabsItem--'); switchTabs.forEach(tab => { tab.style.setProperty('pointer-events', 'auto', 'important'); }); // 视频元素 const videoContainers = document.querySelectorAll('.videox-container'); videoContainers.forEach(container => { container.style.setProperty('pointer-events', 'auto', 'important'); const video = container.querySelector('video'); if (video) { video.style.setProperty('pointer-events', 'auto', 'important'); } }); } // 彻底启用图片右键功能 function enableImageRightClick(img) { if (!img || img.dataset.rightClickFixed) return; console.log('正在为图片启用右键功能:', img.src); // 标记已处理 img.dataset.rightClickFixed = 'true'; // 设置样式属性 img.style.setProperty('pointer-events', 'auto', 'important'); img.style.setProperty('user-select', 'auto', 'important'); img.style.setProperty('-webkit-user-select', 'auto', 'important'); img.style.setProperty('-moz-user-select', 'auto', 'important'); img.style.setProperty('-ms-user-select', 'auto', 'important'); img.style.setProperty('-webkit-touch-callout', 'default', 'important'); img.style.setProperty('position', 'relative', 'important'); img.style.setProperty('z-index', '9999', 'important'); // 移除所有可能阻止右键的事件处理器 img.oncontextmenu = null; img.ondragstart = null; img.onselectstart = null; img.onmousedown = null; img.onmouseup = null; // 添加强制右键事件 img.addEventListener('contextmenu', function(e) { e.stopImmediatePropagation(); console.log('图片右键菜单已强制启用'); return true; }, { capture: true, passive: false }); img.addEventListener('mousedown', function(e) { if (e.button === 2) { // 右键 e.stopImmediatePropagation(); console.log('图片右键点击已强制启用'); return true; } }, { capture: true, passive: false }); // 阻止父元素的事件冒泡 img.addEventListener('click', function(e) { e.stopPropagation(); }, { capture: true }); } function blockZoomEvents() { if (zoomEventBlocked) return; zoomEventBlocked = true; // 禁用缩放相关函数 if (window.ImageZoom) { window.ImageZoom = function() { console.log('ImageZoom 被禁用'); return {}; }; } if (typeof jQuery !== 'undefined' && jQuery.fn.imagezoom) { jQuery.fn.imagezoom = function() { console.log('jQuery.fn.imagezoom 被禁用'); return this; }; } // 拦截事件监听器 const originalAddEventListener = Element.prototype.addEventListener; Element.prototype.addEventListener = function(type, listener, options) { // 检查是否是主图片容器 const isMainPicContainer = hasClassContaining(this, '--mainPicWrap--'); const isZoomMouseEvent = ['mousemove', 'mouseover', 'mouseenter', 'mouseleave', 'mouseout'].includes(type); if (isMainPicContainer && isZoomMouseEvent) { const listenerStr = listener.toString(); if (listenerStr.includes('zoom') || listenerStr.includes('scale') || listenerStr.includes('lens') || listenerStr.includes('magnif')) { console.log(`拦截了容器的缩放事件: ${type}`); return; } } // 1688缩放元素 const is1688ZoomElement = this.classList && (this.classList.contains('scale-img') || this.classList.contains('scaled-img')); if (is1688ZoomElement) { console.log(`拦截了1688缩放事件: ${type}`); return; } return originalAddEventListener.call(this, type, listener, options); }; } // 添加强化的CSS样式 - 使用属性选择器 function addZoomDisableStyles() { const style = document.createElement('style'); style.id = 'zoom-disable-styles-enhanced'; let cssText = ''; if (is1688) { cssText = ` .detail-gallery-preview .scale-img, .detail-gallery-preview .scaled-img { display: none !important; visibility: hidden !important; opacity: 0 !important; pointer-events: none !important; } .detail-gallery-preview .preview-img { pointer-events: auto !important; user-select: auto !important; -webkit-user-select: auto !important; position: relative !important; z-index: 9999 !important; }`; } else if (isTaobaoTmallCommon) { cssText = ` /* 彻底隐藏缩放元素 */ .js-image-zoom__zoomed-area, .js-image-zoom__zoomed-image, #lensDiv { display: none !important; visibility: hidden !important; opacity: 0 !important; pointer-events: none !important; position: absolute !important; top: -9999px !important; left: -9999px !important; } /* 容器事件穿透 - 使用属性选择器匹配动态类名 */ [class*="--mainPicWrap--"] { pointer-events: none !important; } /* 主图片强制可交互 - 使用属性选择器 */ [class*="--mainPicWrap--"] img[class*="--mainPic--"] { pointer-events: auto !important; user-select: auto !important; -webkit-user-select: auto !important; -moz-user-select: auto !important; -ms-user-select: auto !important; position: relative !important; z-index: 9999 !important; -webkit-touch-callout: default !important; -khtml-user-select: auto !important; cursor: default !important; } /* 视频元素恢复交互 */ .videox-container, .videox-container video, .videox-container .videox-control, .videox-container .videox-control * { pointer-events: auto !important; } /* 其他交互元素 - 使用属性选择器 */ [class*="--thumbnail--"], [class*="--thumbnailPic--"] { pointer-events: auto !important; } [class*="--switchTabsItem--"] { pointer-events: auto !important; } [class*="--thumbnailsWrap--"], [class*="--thumbnails--"] { pointer-events: auto !important; } [class*="--bottomSwitchTabsWrap--"], [class*="--switchTabsWrap--"] { pointer-events: auto !important; } `; } style.textContent = cssText; const existingStyle = document.getElementById('zoom-disable-styles-enhanced'); if (!existingStyle) { (document.head || document.documentElement).appendChild(style); } else { existingStyle.textContent = cssText; } console.log('CSS样式已应用 (使用动态类名匹配)'); } // 全局右键修复 function forceEnableRightClickGlobally() { if (rightClickFixed) return; rightClickFixed = true; // 移除全局右键阻止 document.oncontextmenu = null; document.onselectstart = null; document.ondragstart = null; if (document.body) { document.body.oncontextmenu = null; document.body.onselectstart = null; document.body.ondragstart = null; } // 拦截可能阻止右键的事件 ['contextmenu', 'selectstart', 'dragstart'].forEach(eventType => { document.addEventListener(eventType, function(e) { if (e.target.tagName === 'IMG' && e.target.src && (e.target.src.includes('alicdn.com') || e.target.src.includes('taobao.com') || e.target.src.includes('tmall.com'))) { e.stopImmediatePropagation(); return true; } }, { capture: true, passive: false }); }); console.log('全局右键功能已强制启用'); } // 监控动态变化 function setupObserver() { const observer = new MutationObserver(function(mutations) { let needsReapply = false; mutations.forEach(function(mutation) { if (mutation.type === 'childList' && mutation.addedNodes.length > 0) { mutation.addedNodes.forEach(function(node) { if (node.nodeType === 1) { // 检查是否包含相关类名 if (hasClassContaining(node, '--mainPicWrap--') || hasClassContaining(node, '--mainPic--') || hasClassContaining(node, 'videox-container') || (node.matches && node.matches('.js-image-zoom__zoomed-area, .js-image-zoom__zoomed-image, #lensDiv, .scale-img, .scaled-img'))) { needsReapply = true; } else if (node.querySelector) { if (node.querySelector('[class*="--mainPicWrap--"], [class*="--mainPic--"], .videox-container, .js-image-zoom__zoomed-area, .js-image-zoom__zoomed-image, #lensDiv, .scale-img, .scaled-img')) { needsReapply = true; } } } }); } }); if (needsReapply) { console.log('检测到DOM变化,重新应用修复'); setTimeout(() => { addZoomDisableStyles(); disableImageZoom(); forceEnableRightClickGlobally(); }, 100); } }); observer.observe(document.documentElement || document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['class', 'style'] }); console.log('DOM变化监控已启动'); } // 初始化函数 function init() { console.log('初始化电商图片缩放禁用脚本 (动态类名修复版)...'); blockZoomEvents(); addZoomDisableStyles(); disableImageZoom(); forceEnableRightClickGlobally(); if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => { console.log('DOMContentLoaded: 应用修复'); addZoomDisableStyles(); disableImageZoom(); forceEnableRightClickGlobally(); setupObserver(); }); } else { console.log('Document已加载: 应用修复并设置观察者'); setupObserver(); } // 多次延迟执行确保修复生效 [500, 1000, 2000, 3000].forEach(delay => { setTimeout(() => { console.log(`延迟修复 (${delay}ms)`); addZoomDisableStyles(); disableImageZoom(); forceEnableRightClickGlobally(); }, delay); }); } init(); // 定期维护 const maintenanceInterval = setInterval(() => { addZoomDisableStyles(); disableImageZoom(); }, 3000); window.addEventListener('unload', () => { if (maintenanceInterval) { clearInterval(maintenanceInterval); } }); console.log('电商图片缩放禁用脚本加载完成 v1.3.3 (动态类名修复版)'); })();