Greasy Fork

Greasy Fork is available in English.

看漫画手机版阅读辅助

看漫画手机版阅读辅助,瀑布流阅读连续载入图片,自动点击载入更多,在新分页打开漫画链接(自用)。

当前为 2023-03-15 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         看漫畫手機版閱讀輔助
// @name:zh-CN   看漫画手机版阅读辅助
// @version      1.4.3
// @description  看漫畫手機版閱讀輔助,瀑布流閱讀連續載入圖片,自動點擊載入更多,在新分頁打開漫畫鏈接(自用)。
// @description:zh-CN  看漫画手机版阅读辅助,瀑布流阅读连续载入图片,自动点击载入更多,在新分页打开漫画链接(自用)。
// @author       tony0809
// @match        *://m.manhuagui.com/*
// @icon         https://www.google.com/s2/favicons?domain=m.manhuagui.com
// @grant        none
// @run-at       document-end
// @license GPL
// @namespace http://greasyfork.icu/users/20361
// ==/UserScript==

(() => {
    'use strict';
    const options = { //true 開啟,false 關閉
        lM: true, //最近更新、漫畫大全、排行榜、書架,自動點擊載入更多。
        oint: true, //在新分頁打開漫畫鏈接。
        aH: true, //載入下一話時添加瀏覽器歷史紀錄。
        remove: [true, 4] //!!!不能小於2!!!閱讀載入超過n話時刪除前面話數的圖片。
    },
          ge = e => document.querySelector(e),
          gae = e => document.querySelectorAll(e),
          runCode = code => new Function('return ' + code)(),
          lp = location.pathname,
          update = /^\/update\/$/.test(lp),
          list = /^\/list\//.test(lp),
          rank = /^\/rank\/$/.test(lp),
          search = /^\/s\/[^.]+\.html$/.test(lp),
          read = /^\/comic\/\d+\/\d+\.html$/.test(lp),
          chapter = /^\/comic\/\d+\/$/.test(lp),
          user = /^\/user\/book\//.test(lp),
          addGlobalStyle = css => {
              let style = document.createElement('style');
              style.type = 'text/css';
              style.innerHTML = css;
              document.head.appendChild(style);
          },
          css = `
.goback {
    background: url(/images/bg_main.png) -258px -80px no-repeat;
    position: fixed;
    left: 50%;
    margin-left: -20px;
    bottom: 0px;
    width: 40px;
    height: 40px;
}
.action-list li {
    width: 50% !important
}
#action>ul>li:nth-child(n+2):nth-child(-n+3),
.manga-page,
.clickforceads {
    display: none !important
}
.manga-box img {
    border-top: 0px !important;
    border-bottom: 0px !important
}
.loading {
    font-size: 20px;
    font-family: Arial,sans-serif!important;
    height: 32px;
    line-height: 30px;
    border: none!important;
}
.chapterTitle {
    width: auto;
    height: 30px;
    font-size: 20px;
    font-family: Arial,sans-serif!important;
    line-height: 32px;
    text-align: center;
    margin: 10px 5px;
    border: 1px solid #e0e0e0;
    background-color: #f0f0f0;
    background: -webkit-gradient(linear, 0 0, 0 100%, from(#f9f9f9), to(#f0f0f0));
    background: -moz-linear-gradient(top, #f9f9f9, #f0f0f0);
    box-shadow: 0 0 5px rgba(0, 0, 0, 0.6);
    border-radius: 5px;
}
    `;
    addGlobalStyle(css);
    const openInNewTab = () => gae('#topSlider a:not([target=_blank]),.main-list a:not([target=_blank]),.cont-list a:not([target=_blank])').forEach(a => {
        a.setAttribute('target', '_blank');
    }),
          addGoBack = () => {
              let goback = document.createElement('div');
              goback.className = 'goback';
              goback.setAttribute('title', '返回頂部');
              goback.addEventListener('click', () => {
                  window.scrollTo({
                      top: 0,
                      behavior: "smooth"
                  });
              });
              document.body.appendChild(goback);
              const goBackOpacity = () => {
                  let dd = document.documentElement,
                      gb = ge('.goback'),
                      scrollTotal = dd.scrollHeight - dd.clientHeight;
                  if ((dd.scrollTop / scrollTotal) > 0.8) {
                      gb.style.opacity = 0.7;
                  } else {
                      gb.style.opacity = 0.2;
                  }
              };
              document.addEventListener('scroll', goBackOpacity);
          },
          autoLoadMore = () => {
              let loadMore = ge('#more:not([style*=none])>.more-go');
              new IntersectionObserver(entries => {
                  if (entries[0].isIntersecting) {
                      loadMore.click();
                  }
              }).observe(loadMore);
          },
          addHistory = (title, url) => {
              history.pushState(null, title, url);
              document.title = title;
          },
          addLoad = () => {
              let load = document.createElement('p');
              load.className = 'loading';
              load.innerText = 'Loading...';
              ge('#manga').appendChild(load);
          },
          removeLoad = () => {
              ge('.loading').remove();
          },
          addTitle = title => {
              let t = document.createElement('div');
              t.className = 'chapterTitle';
              t.innerText = title;
              let load = ge('.loading');
              load.parentNode.insertBefore(t, load);
          },
          insertData = d => {
              const code = Array.from(d.scripts).find(s => s.innerHTML.search(/x6c/) > -1).innerHTML.trim().slice(26),
                    jsonData = JSON.parse(runCode(code).slice(11, -12)),
                    hostArray = ['i', 'eu', 'us'],
                    getRandom = max => Math.floor(Math.random() * Math.floor(max)),
                    randomHost = () => {
                        let choose = getRandom(hostArray.length);
                        let rValue = hostArray[choose];
                        return rValue;
                    },
                    imagesObserver = new IntersectionObserver((entries, observer) => {
                        entries.forEach(entry => {
                            if (entry.isIntersecting) {
                                observer.unobserve(entry.target);
                                let realSrc = entry.target.dataset.src;
                                if (realSrc) {
                                    entry.target.src = realSrc;
                                    entry.target.removeAttribute('data-src');
                                }
                                let nE = entry.target.nextElementSibling;
                                if (nE && nE.tagName == 'IMG' && nE.dataset.src) {
                                    nE.src = nE.dataset.src;
                                    nE.removeAttribute('data-src');
                                }
                            }
                        });
                    }),
                    F = new DocumentFragment();
              jsonData.images.forEach(e => {
                  let domain = location.protocol + "//" + randomHost() + ".hamreus.com";
                  let img = new Image();
                  img.src = 'data:image/png;base64,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';
                  img.dataset.src = `${domain+e}?e=${jsonData.sl.e}&m=${jsonData.sl.m}`;
                  imagesObserver.observe(img);
                  F.appendChild(img);
              });
              let load = ge('.loading');
              if (load) {
                  let title = d.querySelector('#mangaTitle').innerHTML.replace(/<.+>\s?/g, '');
                  addTitle(title);
                  if (options.remove[0] && options.remove[1] > 1) {
                      removeOldChapter();
                  }
                  setTimeout(() => {
                      load.parentNode.insertBefore(F, load);
                      removeLoad();
                  }, 300);
              } else {
                  let E = ge('#manga');
                  E.innerHTML = '';
                  E.appendChild(F);
              }
              let curl = lp.replace(/\d+\.html$/, ''),
                  next = ge("a[data-action='chapter.next']"),
                  prev = ge("a[data-action='chapter.prev']");
              if (jsonData.nextId == 0) {
                  next.href = curl;
                  next.innerText = '返回目录';
              } else {
                  next.href = curl + jsonData.nextId + '.html';
              }
              if (jsonData.prevId > 0) {
                  prev.href = curl + jsonData.prevId + '.html';
              }
          },
          parseHTML = str => {
              let doc;
              try {
                  doc = new DOMParser().parseFromString(str, 'text/html');
              } catch (e) {}
              if (!doc) {
                  doc = document.implementation.createHTMLDocument('');
                  doc.documentElement.innerHTML = str;
              }
              return doc;
          },
          fetchData = url => {
              fetch(url).then(res => res.text()).then(res => {
                  let doc = parseHTML(res),
                      title = doc.title;
                  if (options.aH) {
                      addHistory(title, url);
                  }
                  insertData(doc);
                  setTimeout(() => {
                      addNextObserver();
                  }, 1300);
              }).catch((err) => {
                  console.log('出錯鏈接:' + url, err);
                  ge('.loading').innerText = '連線出錯,請返回頂部重新載入。';
              });
          },
          /*fetchData = url => {
            let xhr = new XMLHttpRequest();
            xhr.responseType = 'text';
            xhr.open('GET', url);
            xhr.timeout = 10000;
            xhr.onload = () => {
                if (xhr.status == 200) {
                    let doc = parseHTML(xhr.responseText);
                    let title = doc.title;
                    if (options.aH) {
                        addHistory(title, url);
                    }
                    insertData(doc);
                    setTimeout(() => {
                        addNextObserver();
                    }, 1200);
                } else if (xhr.status > 400) {
                    console.log('HTTP連線狀態碼:' + xhr.status + '\n鏈接:' + url);
                    ge('.loading').innerText = 'HTTP連線狀態碼:' + xhr.status + ',獲取過程中出錯。';
                }
            };
            xhr.ontimeout = (e) => {
                console.log(e);
                ge('.loading').innerText = '連線逾時,請返回頂部重新載入。';
            };
            xhr.onerror = (e) => {
                console.log(e);
                ge('.loading').innerText = '連線出錯,請返回頂部重新載入。';
            }
            xhr.send();
        },*/
          addNextObserver = () => {
              //let imgChild = ge('#manga>img:nth-last-child(1)');
              let lastImg = [...ge('#manga').querySelectorAll('img')].pop(); //用最後一張圖片作為觀察對象。
              new IntersectionObserver((entries, observer) => {
                  if (entries[0].isIntersecting) {
                      observer.unobserve(lastImg);
                      let next = ge("a[data-action='chapter.next'][href$=html]");
                      if (next) {
                          console.log('觸發載入下一話');
                          addLoad();
                          fetchData(next.href);
                      }
                  }
              }).observe(lastImg);
          },
          removeOldChapter = () => {
              let titles = gae('.chapterTitle');
              if (titles.length > options.remove[1]) {
                  titles[0].remove();
                  let removes = gae('#manga>*');
                  for (let i in removes) {
                      if (/chapterTitle/.test(removes[i].className)) {
                          break;
                      }
                      removes[i].remove();
                  }
              }
          };

    if (read) {
        addGoBack();
        let loop = setInterval(() => {
            let set = ge('#manga img');
            if (set) {
                clearInterval(loop);
                insertData(document);
                addNextObserver();
            }
        }, 100);
    }

    if (options.oint && !read && !chapter) {
        openInNewTab();
        console.log('看漫画在新分頁打開漫畫鏈接');
        new MutationObserver(() => {
            openInNewTab();
        }).observe(document.body, {
            childList: true,
            subtree: true
        });
    }

    if (options.lM && (update || user || list || rank || search)) {
        autoLoadMore();
    }

})();