PixivPreviewer

在搜索页显示较大的预览图(请注意阅读详细信息)。Show preview of pictures in serach page.

当前为 2017-08-07 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         PixivPreviewer
// @namespace
// @version      1.10
// @description  在搜索页显示较大的预览图(请注意阅读详细信息)。Show preview of pictures in serach page.
// @author       Ocrosoft
// @match        https://www.pixiv.net/search.php*
// @match        https://www.pixiv.net/member_illust.php?mode=medium*
// @match        https://www.pixiv.net/member_illust.php?mode=ugoira_view*
// @match        https://www.pixiv.net/ranking.php*
// @grant        none
// @require      http://code.jquery.com/jquery-2.1.4.min.js
// @namespace
// @namespace 
// ==/UserScript==

var mousePos;

function log(text) {
    console.log(text);
}

function activePreview() {
    $('._layout-thumbnail').parent().mouseover(function (e) {
        if (e.ctrlKey) {
            return;
        }
        var imgNode = this.children[0];
        // 鼠标位置
        mousePos = { x: e.pageX, y: e.pageY };
        // Div
        var previewDiv = document.createElement('div');
        $(previewDiv).css({ 'position': 'absolute', 'z-index': '999999' });
        $(previewDiv).addClass('pixivPreview');
        // 添加Div
        $('body')[0].appendChild(previewDiv);
        // 加载中图片
        var loadingImg = new Image();
        loadingImg.src = 'https://raw.githubusercontent.com/shikato/pixiv_sk/master/loading.gif';
        $(loadingImg).css('position', 'absolute');
        previewDiv.appendChild(loadingImg);
        // 要显示图片
        var loadImg = new Image();
        previewDiv.appendChild(loadImg);
        // 表示显示的是原图的图标
        var originIcon = new Image();
        originIcon.src = 'https://source.pixiv.net/www/images/pixivcomic-favorite.png';
        $(originIcon).css({ 'position': 'absolute', 'bottom': '0px', 'right': '0px', 'display': 'none' });
        previewDiv.appendChild(originIcon);
        // 点击图标新网页打开原图
        $(originIcon).click(function () {
            window.open($(previewDiv).children('img')[1].src);
        });
        $(previewDiv).css({ 'left': mousePos.x + 'px', 'top': mousePos.y + 'px' });

        function viewImages(imgs, index, imgsOrigin) {
            if (!imgs || imgs.length == 0) return;
            if (index < 0) return;
            if (!imgsOrigin || imgsOrigin.length == 0 || imgs.length != imgsOrigin.length) return;
            if (!index) index = 0;

            if ($(previewDiv).children('script').length == 0) {
                // 绑定点击事件,Ctrl+左键 单击切换原图
                loadImg.addEventListener('click', function (ev) {
                    // 按住 Ctrl 来回切换原图
                    if (ev.ctrlKey) {
                        if (loadImg.src.indexOf('origin') == -1) {
                            viewImages(allImgsOrigin, parseInt($($('.pixivPreview').children('img')[1]).attr('data-index')), allImgs);
                        } else {
                            viewImages(allImgs, parseInt($($('.pixivPreview').children('img')[1]).attr('data-index')), allImgsOrigin);
                        }
                    }
                    // 按住 Shift 点击图片新标签页打开原图
                    else if (ev.shiftKey) {
                        window.open(allImgsOrigin[parseInt($($('.pixivPreview').children('img')[1]).attr('data-index'))]);
                    }
                });
            }
            // 多图时绑定点击事件,点击图片切换到下一张
            if (index == 0 && imgs.length != 1 && $(previewDiv).children('._work').length == 0) {
                loadImg.addEventListener('click', function (e) {
                    if (e.ctrlKey || e.shiftKey) return;
                    var newIndex = parseInt($($('.pixivPreview').children('img')[1]).attr('data-index')) + 1;
                    if (newIndex == allImgs.length) newIndex = 0;
                    $('.pixivPreview').children('div').children('div').children('span')[0].innerHTML = (newIndex + 1) + '/' + allImgs.length;
                    if (loadImg.src.indexOf('origin') == -1) {
                        viewImages(allImgs, newIndex, allImgsOrigin);
                    } else {
                        viewImages(allImgsOrigin, newIndex, allImgs);
                    }
                });
            }

            // 右上角张数标记
            if (imgs.length != 1 && index == 0 && $(previewDiv).children('._work').length == 0) {
                var iconDiv = document.createElement('div');
                iconDiv.innerHTML = '<div class="page-count"><div class="icon"></div><span>1/' + imgs.length + '</span></div>';
                $(iconDiv).addClass('_work');
                $(iconDiv).css({ 'position': 'absolute', 'top': '0px', 'display': 'none' });
                previewDiv.appendChild(iconDiv);
            }

            // 预加载
            loadImg.src = '';
            $(loadImg).css({ 'width': '', 'height': '', 'display': 'none' });
            $(loadingImg).css('display', '');
            $(originIcon).css('display', 'none');
            $(iconDiv).css({ 'display': 'none' });
            loadImg.addEventListener('load', function () {
                if (loadImg.src.indexOf('githubusercontent') != -1) return;
                // 调整图片大小
                var width = loadImg.width, screenWidth = document.documentElement.clientWidth;
                var height = loadImg.height, screenHeight = document.documentElement.clientHeight;
                var viewHeight, viewWidth;
                // 长图
                if (height > width) {
                    viewHeight = screenHeight / 2;
                    viewWidth = viewHeight / height * width;
                    var scale = 1.0;
                    while (viewWidth * scale > screenWidth / 2) {
                        scale -= 0.01;
                    }
                }
                // 宽图
                else {
                    viewWidth = screenWidth / 2;
                    viewHeight = viewWidth / width * height;
                    var scale = 1.0;
                    while (viewHeight * scale > screenHeight / 2) {
                        scale -= 0.01;
                    }
                }
                $(loadImg).css({ 'height': viewHeight * scale + 'px', 'width': viewWidth * scale + 'px' });
                $(previewDiv).css({ 'height': viewHeight * scale + 'px', 'width': viewWidth * scale + 'px' });
                $(loadingImg).css({ 'left': viewWidth * scale / 2 - 24 + 'px', 'top': viewHeight * scale / 2 - 24 + 'px' });
                $(loadImg).css('display', '');
                $(loadingImg).css('display', 'none');
                $(iconDiv).css({ 'display': '' });
                if (loadImg.src.indexOf('origin') != -1) {
                    $(originIcon).css({ 'display': '' });
                } else {
                    $(originIcon).css({ 'display': 'none' });
                }
                // 调整图片位置
                var divX = mousePos.x, divY = mousePos.y;
                if (mousePos.x > screenWidth / 2) {
                    divX -= $(loadImg).css('width').split('px')[0];
                }
                if ((mousePos.y - document.body.scrollTop) >
                    screenHeight / 2) {
                    divY -= $(loadImg).css('height').split('px')[0];
                }
                $(previewDiv).css({ 'left': divX + 'px', 'top': divY + 'px' });
                // 第一次显示预览时将图片列表添加到末尾
                if ($(previewDiv).children('script').length == 0) {
                    var s = document.createElement('script');
                    // 输出预览图URL
                    var tmp = "var allImgs=['";
                    tmp += imgs[0];
                    for (var i = 1; i < imgs.length; ++i) {
                        tmp += "','" + imgs[i];
                    }
                    tmp += "'];";
                    // 输出原图URL
                    tmp += "var allImgsOrigin=['";
                    tmp += imgsOrigin[0];
                    for (var i = 1; i < imgsOrigin.length; ++i) {
                        tmp += "','" + imgsOrigin[i];
                    }
                    tmp += "'];";
                    // 输出
                    s.innerHTML = tmp;
                    previewDiv.appendChild(s);
                }
            });
            $(loadImg).attr('data-index', index);
            loadImg.src = imgs[index];
        }

        var xmlHttp = new XMLHttpRequest();
        xmlHttp.onreadystatechange = function () {
            if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
                var resText = xmlHttp.responseText;
                // 单图
                try {
                    // 取得图片地址
                    // 预览图
                    var imgSource = RegExp('<div class="_layout-thumbnail ui-modal-trigger">[^>]*>').
                        exec(resText)[0].split('<')[2].split('\"')[1];
                    // 原图
                    var imgOrigin = RegExp('<div class="_illust_modal.*class="original-image').
                        exec(resText)[0].split('data-src="')[1].split('\"')[0];
                    viewImages([imgSource], 0, [imgOrigin]);
                    return;
                } catch (e) {
                    // empty
                }
                // 多图
                try {
                    var img, imgs = [];
                    var reg = new RegExp('https://i.pximg.net/img-master[^\"]*', 'g');
                    while ((img = reg.exec(resText.split('<section class=\"manga\">')[1].
                        split('</section>')[0])) !== null) {
                        imgs.push(img[0]);
                    }
                    // 推出来的原图URL,暂时没有想到效率高的办法(imgs.length 次xmlHttpRequest)
                    var imgsOrigin = [];
                    for (var i = 0; i < imgs.length; ++i) {
                        imgsOrigin.push(imgs[i].replace('img-master', 'img-original'));
                        imgsOrigin[i] = imgsOrigin[i].replace('_master1200', '');
                    }
                    viewImages(imgs, 0, imgsOrigin);
                    return;
                } catch (e) {
                    // empty
                }
            }
        };
        // 动图
        if ($(this).hasClass('ugoku-illust')) {
            $(previewDiv).children().remove();
            previewDiv.innerHTML = '<iframe width="600px" height="50%" src="https://www.pixiv.net/member_illust.php?mode=ugoira_view&illust_id=' +
                $(imgNode.children[0]).attr('data-id') + '#animePreview"/>';
            $(previewDiv).children('iframe').css('display', 'none');
            var loadingImg = new Image();
            loadingImg.src = 'https://raw.githubusercontent.com/shikato/pixiv_sk/master/loading.gif';
            $(loadingImg).css('position', 'absolute');
            previewDiv.appendChild(loadingImg);
            return;
        }
        // 多图
        else if ($(imgNode.parentNode.parentNode).children('a').hasClass('multiple')) {
            xmlHttp.open('GET', 'https://www.pixiv.net/member_illust.php?mode=manga&illust_id=' +
                $(imgNode.children[0]).attr('data-id'), true);
        }
        // 单图
        else {
            xmlHttp.open('GET', 'https://www.pixiv.net/member_illust.php?mode=medium&illust_id=' +
                $(imgNode.children[0]).attr('data-id'), true);
        }
        xmlHttp.send(null);
    });
    $('._layout-thumbnail').parent().mouseout(function (e) {
        //if (true) return;
        // 鼠标移动到预览图上
        if ($(e.relatedTarget).hasClass('pixivPreview') || $(e.relatedTarget).parents().hasClass('pixivPreview')) {
            $('.pixivPreview').mouseleave(function () {
                $('.pixivPreview').remove();
            });
        }
        // 非预览图上
        else {
            $('.pixivPreview').remove();
        }
    });
    $('._layout-thumbnail').addClass('prev');
}

(function () {
    // 动图预览辅助
    if (location.href.indexOf('medium') != -1 && location.href.indexOf('animePreview') != -1) {
        location.href = location.href.replace('medium', 'ugoira_view');
        return;
    } else if (location.href.indexOf('ugoira_view') != -1 && location.href.indexOf('animePreview') != -1) {
        var height = parseInt($('canvas').css('height').split('px'));
        var width = parseInt($('canvas').css('width').split('px'));
        var newHeight = 580 / width * height;
        $('canvas').css({ 'height': newHeight + 'px', 'width': 580 + 'px' });
        window.parent.iframeLoaded(newHeight, 580);
        return;
    }
    // 下载模式按钮
    var downloadButton = document.createElement('li');
    downloadButton.innerHTML = '<i class="_icon-12 _icon-up" style="transform: rotateX(180deg);border-radius: 100%;"></i>';
    downloadButton.className = 'item';
    $(downloadButton).css({ 'margin-bottom': '10px', 'opacity': '0.2' });
    $('#back-to-top').parent()[0].insertBefore(downloadButton, $($('#back-to-top').parent()[0]).children()[0]);
    // 点击开闭下载模式
    $(downloadButton).click(function () {
        if ($(downloadButton).css('opacity') == '0.2') {
            $(downloadButton).css('opacity', '0.5');
            $($(downloadButton).children()[0]).css({ 'background': 'green' });
            // 开启下载模式
            $('._layout-thumbnail').each(function () {
                $($(this).parent().children('img')[0]).css('display', '');
            }); // 显示多选框
            var t = $('._layout-thumbnail').parent().parent();
            for (var i = 0; i < t.length; ++i) {
                // 新的容器
                var checkDiv = document.createElement('div');
                // 覆盖在<a>上面的图
                var layer = new Image();
                layer.src = 'https://source.pixiv.net/www/images/common/transparent.gif';
                checkDiv.appendChild(layer);
                // 插入Div
                t[i].insertBefore(checkDiv, $(t[i]).children()[0]);
                // <a>移动进Div
                checkDiv.appendChild($(t[i]).children()[1]);
                $(layer).css({ 'height': $(layer).parent().css('height'), 'width': $(layer).parent().css('width'), 'position': 'absolute', 'z-index': '999999' });
                $(layer).click(function () {
                    if ($(this).parent().children('a').children('img')[0].src.indexOf('unchecked')!=-1) {
                        $(this).parent().children('a').children('img')[0].src = 'https://raw.githubusercontent.com/Ocrosoft/PixivPreviewer/master/checked.png';
                    } else {
                        $(this).parent().children('a').children('img')[0].src = 'https://raw.githubusercontent.com/Ocrosoft/PixivPreviewer/master/unchecked.png';
                    }
                });
            }
        } else {
            $(downloadButton).css('opacity', '0.2');
            $($(downloadButton).children()[0]).css({ 'background': '' });
            // 关闭下载模式
            var imgOriginList = []; var linkList = []; var imgCount = 0;
            var t = $('._layout-thumbnail').parent().parent().parent();
            for (var i = 0; i < t.length; ++i) {
                if ($(t[i]).children('div').children('a').children('img')[0].src.indexOf('unchecked') == -1) {
                    var imgNode = $(t[i]).find('._layout-thumbnail').children('img')[0];
                    // 多图
                    if ($(imgNode.parentNode.parentNode).hasClass('multiple')) {
                        linkList.push('https://www.pixiv.net/member_illust.php?mode=manga&illust_id=' +
                            $(imgNode).attr('data-id'));
                    }
                    // 单图
                    else {
                        linkList.push('https://www.pixiv.net/member_illust.php?mode=medium&illust_id=' +
                            $(imgNode).attr('data-id'));
                    }
                }
                t[i].insertBefore($($(t[i]).children()[0]).children()[1], $(t[i]).children()[0]);
                $(t[i]).children('div').remove();
            }
            var xmlHttp = new XMLHttpRequest();
            xmlHttp.onreadystatechange = function () {
                if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
                    var resText = xmlHttp.responseText;
                    // 单图
                    try {
                        // 取得图片地址
                        // 预览图
                        var imgSource = RegExp('<div class="_layout-thumbnail ui-modal-trigger">[^>]*>').
                            exec(resText)[0].split('<')[2].split('\"')[1];
                        // 原图
                        var imgOrigin = RegExp('<div class="_illust_modal.*class="original-image').
                            exec(resText)[0].split('data-src="')[1].split('\"')[0];
                        imgOriginList.push(imgOrigin);
                    } catch (e) {
                        // empty
                    }
                    // 多图
                    try {
                        var img, imgs = [];
                        var reg = new RegExp('https://i.pximg.net/img-master[^\"]*', 'g');
                        while ((img = reg.exec(resText.split('<section class=\"manga\">')[1].
                            split('</section>')[0])) !== null) {
                            imgs.push(img[0]);
                        }
                        // 推出来的原图URL,暂时没有想到效率高的办法(imgs.length 次xmlHttpRequest)
                        var imgsOrigin = [];
                        for (var i = 0; i < imgs.length; ++i) {
                            imgsOrigin.push(imgs[i].replace('img-master', 'img-original'));
                            imgsOrigin[i] = imgsOrigin[i].replace('_master1200', '');
                            imgOriginList.push(imgsOrigin[i]);
                        }
                    } catch (e) {
                        // empty
                    }
                    if (++imgCount == linkList.length) {
                        $('._layout-thumbnail').each(function () {
                            $(this).parent().children('img')[0].src = 'https://raw.githubusercontent.com/Ocrosoft/PixivPreviewer/master/unchecked.png';
                            $($(this).parent().children('img')[0]).css('display', 'none');
                        });
                        var s = '';
                        $(imgOriginList).each(function () {
                            s += this + '\n';
                        });
                        prompt('复制到下载工具下载', s);
                    } else {
                        xmlHttp.open('GET', linkList[imgCount], true);
                        xmlHttp.send(null);
                    }
                }
            }
            if (linkList.length != 0) {
                xmlHttp.open('GET', linkList[0], true);
                xmlHttp.send(null);
            } else {
                $('._layout-thumbnail').each(function () {
                    $($(this).parent().children('img')[0]).css('display', 'none');
                });
            }
        }
    });
    // 主要功能
    setInterval(function () {
        var t = $('._layout-thumbnail');
        if (!$(t[t.length - 1]).hasClass('prev')) {
            // 开启预览
            activePreview();
            // 表示是否选中的图标
            $('._layout-thumbnail').parent().each(function () {
                var checkIcon = new Image();
                checkIcon.src = 'https://raw.githubusercontent.com/Ocrosoft/PixivPreviewer/master/unchecked.png';
                $(checkIcon).css({ 'position': 'absolute', 'top': '0px', 'left': '0px', 'display': 'none' });
                this.appendChild(checkIcon);
            });
        }
    }, 500);
})();

function iframeLoaded(height, width) {
    log('loaded');
    $('.pixivPreview').children('iframe').css({ 'width': width + 20 + 'px', 'height': height + 20 + 'px' });
    // 调整位置
    var divX = mousePos.x, divY = mousePos.y;
    var screenWidth = document.documentElement.clientWidth;
    var screenHeight = document.documentElement.clientHeight;
    if (mousePos.x > screenWidth / 2) {
        divX -= width;
    }
    if ((mousePos.y - document.body.scrollTop) >
        screenHeight / 2) {
        divY -= height;
    }
    $('.pixivPreview').css({ 'left': divX + 'px', 'top': divY + 'px' });
    $('.pixivPreview').children('iframe').css('display', '');
    $('.pixivPreview').children('img').remove();
}