Greasy Fork

鼠标悬停图片放大预览-大师兄

电脑端可以跟随鼠标悬停图片放大预览,找了很多图片放大的脚本,都没有一个能用的,只有自己写。大部分网站的图片都可以已支持悬浮放大了。完美适应大小屏幕,图片超大也会图片等比例自适应浏览器。鼠标跟随也优化。欢迎好评反馈,有时间就更新

目前为 2022-10-09 提交的版本。查看 最新版本

// ==UserScript==
// @name        鼠标悬停图片放大预览-大师兄
// @date        05/27/2021
// @namespace    https://greasyfork.org/zh-CN/users/724782-caogen1207
// @match       *://*/*
// @version     3.22
// @author      大师兄 [email protected]  VX:caogen
// @license     2022年1月8日22:30:21
// @description 电脑端可以跟随鼠标悬停图片放大预览,找了很多图片放大的脚本,都没有一个能用的,只有自己写。大部分网站的图片都可以已支持悬浮放大了。完美适应大小屏幕,图片超大也会图片等比例自适应浏览器。鼠标跟随也优化。欢迎好评反馈,有时间就更新
// @note        2.5 2021年10月4日更新超大图片显示问题
// @note        2.6 2021年10月14日解决某些网站不能正常使用问题
// @note        3.0 2021年11月6日已更新大部分网站不能识别图片放大功能
// @note        3.1 2022年10月8日18:42:41 解决淘宝缩略图问题,例如详情页里主图缩略图悬浮,猜你喜欢的悬浮放大出原图
// @note        3.2 2022年10月9日18:28:17 解决某些网站图片显示成直线问题
// @run-at      document-idle
// @require     https://code.jquery.com/jquery-3.6.0.min.js
// @icon        http://inews.gtimg.com/newsapp_bt/0/14677352341/641
// @grant       none
// ==/UserScript==
(function() {
    console.log("鼠标悬停图片放大预览-大师兄");

    fangdatupian();
    function fangdatupian() {
        //添加图片盒子
        $(document.body).append("<div id='dashixiong_preview' style='display:none;pointer-events:none;padding:0px;margin:0px;left:0px;top:0px;background-color:#00000000;position:fixed;z-index:9999999998;'><img /></div>"); //弹出一个div里面放着图片
        jiantingimg();
        //jiantingWEIimg();
    }

    function jiantingimg(){
        $("body").on("mouseenter mousemove mouseout", "img,div[style*='background']", function(e){
            e.stopPropagation();
            let imgw,imgh;
            //console.log($(this)[0]);
            let imgsrc = $(this)[0].tagName == "IMG" ? $(this).attr("src") : $(this).css('backgroundImage').replace('url("','').replace('")','');

            //解决淘宝缩略图问题
            if(/_(\d+)x(\d+).jpg_.webp/i.test(imgsrc)){
                imgsrc = imgsrc.replace(/_(\d+)x(\d+).jpg_.webp/i,'')
            }else if(/_(\d+)x(\d+)q90.jpg_.webp/i.test(imgsrc)){
                imgsrc = imgsrc.replace(/_(\d+)x(\d+)q90.jpg_.webp/i,'')
            }else if(/.jpg_(\d+)x(\d+).jpg/i.test(imgsrc)){
                imgsrc = imgsrc.replace(/_(\d+)x(\d+).jpg/i,'')
            }

            $("#dashixiong_preview img").attr("src", imgsrc).attr("style","width: auto").attr("style","height: auto");
            imgw = $("#dashixiong_preview img").width();
            imgh = $("#dashixiong_preview img").height();
            //try{[imgw, imgh] = getImageWidth(imgsrc);}catch(e){return;};

            if(e.type == "mouseenter"){
                tupianweizhi(e, imgw, imgh);
                $("#dashixiong_preview").stop(true, false).show();
            }else if(e.type == "mousemove"){
                //console.log(imgw, imgh);
                tupianweizhi(e, imgw, imgh);
            }else if(e.type == "mouseout"){
                $("#dashixiong_preview").stop(true, false).hide();
            };
        });
    }

    function jiantingWEIimg(){
        $("body").on("mouseenter", "div", function(e){
            if($(this).css('position') == "absolute"){
                //console.log($(this).css('backgroundImage') == "none");
                e.stopPropagation();
                let aa = $(this);
                let x1 = aa.offset().left;
                let y1 = aa.offset().top;
                let x2 = aa.offset().left + aa.width();
                let y2 = aa.offset().top + aa.height();

                if(e.type == "mouseenter"){
                    aa.stop(false, false).hide();
                    $(document).mousemove(function(de){
                        let x = de.pageX, y = de.pageY;
                        if( x < x1 || y < y1 || x > x2 || y > y2){
                            //console.log(x, y, x1, y1);
                            aa.stop(false, false).fadeIn();
                            $(document).unbind(de);
                        }
                    });
                }
            }
        });
    }

    function tupianweizhi(e, img_width, img_height) {
        $("#dashixiong_preview img").width(img_width);
        $("#dashixiong_preview img").height(img_height);

        let jianxi = 20;
        let window_height = $(window).height();
        let window_width = $(window).width();

        if (img_height > window_height || img_width > window_width) {
            if (window_width*img_height/img_width > window_height) {
                $("#dashixiong_preview img").css({
                    "height": window_height,
                    "width": img_width * window_height / img_height
                });
            }else {
                $("#dashixiong_preview img").css({
                    "height": img_height * window_width / img_width,
                    "width": window_width
                });
            };
        };

        img_height = $("#dashixiong_preview img").height();
        img_width = $("#dashixiong_preview img").width();

        if (img_height + e.clientY < window_height && img_width + e.clientX < window_width){
            //console.log("显示在鼠标右下");
            $("#dashixiong_preview").css({
                top: e.clientY + jianxi,
                left: (e.clientX + img_width + jianxi > window_width) ? window_width - img_width - jianxi : e.clientX + jianxi,
            });
        } else if (img_height + e.clientY > window_height && img_width + e.clientX < window_width) {
            //console.log("显示高度超过屏幕,显示在鼠标左右两侧");
            if (img_height + e.clientY + jianxi > window_height) {
                $("#dashixiong_preview").css({
                    top: (e.clientY - img_height - jianxi) < 0 ? 0 : e.clientY - img_height - jianxi,
                    left: ((e.clientX - img_width - jianxi) < 0 && e.clientX + jianxi + img_width > window_width) ? window_width - img_width - jianxi : e.clientX + jianxi
                });
            }
        } else if (img_width + e.clientX + jianxi > window_width && img_height + e.clientY < window_height) {
            //console.log("显示宽度超过屏幕,显示在鼠标上下两侧");
            $("#dashixiong_preview").css({
                top: (e.clientY - img_height - jianxi) < 0 ? 0 : e.clientY + jianxi,
                left: (e.clientX - img_width - jianxi) < 0 ? 0 : e.clientX - img_width - jianxi,
            });
        } else if (img_width + e.clientX > window_width && img_height + e.clientY > window_height) {
            //console.log("显示高度和宽度均超过屏幕");
            if (e.clientX - img_width - jianxi > 0 && e.clientY - img_height - jianxi > 0) {//左上角
                $("#dashixiong_preview").css({
                    top: e.clientY - img_height - jianxi,
                    left: e.clientX - img_width - jianxi,
                });
            } else if (e.clientX - img_width - jianxi < 0 && e.clientY - img_height - jianxi > 0) {//宽度超大左上角,左边固定
                $("#dashixiong_preview").css({
                    top: e.clientY - img_height - jianxi,
                    left: 0,
                });
            } else if (e.clientX - img_width - jianxi > 0 && e.clientY - img_height - jianxi < 0) {//高度超大左上角,顶边固定
                $("#dashixiong_preview").css({
                    top: 0,
                    left: e.clientX - img_width - jianxi,
                });
            } else if (e.clientX - img_width - jianxi < 0 && e.clientY - img_height - jianxi < 0) {//高宽均超大,固定左上角边
                $("#dashixiong_preview").css({
                    top: 0,
                    left: 0,
                });
            };

        }
    }

    function getImageWidth(img_url) {
        // 创建对象
        var img = new Image();
        // 改变图片的src
        img.src = img_url;
        // 判断是否有缓存
        if(img.complete){
            return [img.width,img.height];
        }else{
            // 加载完成执行
            img.onload = function(){
                return [img.width,img.height];
            };
        }
    }

    function Toast(msg,duration){
        duration=isNaN(duration)?3000:duration;
        let m = document.createElement('div');
        m.innerHTML = msg;
        m.style.cssText="max-width:60%;min-width: 150px;padding:0 14px;height: 40px;color: rgb(255, 255, 255);line-height: 40px;text-align: center;border-radius: 4px;position: fixed;top: 50%;left: 50%;transform: translate(-50%, -50%);z-index: 999999;background: rgba(0, 0, 0,.7);font-size: 16px;";
        document.body.appendChild(m);
        setTimeout(function() {
            let d = 0.5;
            m.style.webkitTransition = '-webkit-transform ' + d + 's ease-in, opacity ' + d + 's ease-in';
            m.style.opacity = '0';
            setTimeout(function() { document.body.removeChild(m) }, d * 1000);
        }, duration);
    }

    function getViewprotOffset() {
        if (window.innerWidth) {
            return [window.innerWidth,window.innerHeight]
        } else {
            if (document.compatMode == "BackCompat") {
                return [document.body.clientWidth, document.body.clientHeight]
            } else {
                return [document.documentElement.clientWidth, document.documentElement.clientHeight]
            }
        }
    }

})();