Sleazy Fork is available in English.

JAVBUS助手

JAVBUS网站增加自动翻页,论坛页面精简

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

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

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

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

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

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         JAVBUS助手
// @namespace    http://tampermonkey.net/
// @version      1.5
// @description  JAVBUS网站增加自动翻页,论坛页面精简
// @author       A9
// @match        https://www.javbus.com/
// @include      /^https?:\/\/(?:[A-Za-z0-9]+\.)*(?:javbus|busjav|busfan|fanbus|buscdn|cdnbus|dmmsee|seedmm|busdmm|dmmbus|javsee|seejav)(?:\.[A-Za-z0-9]+)(?:[\S]*)$/
// @grant        GM_addStyle
// @icon         data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABFElEQVQ4ja2TMU4CQRSGvzfuKkQ2bqORRpKNV6CjIaGgovQK1LRs7R24AoECbrAHWE7glhQkJO4SEgt1GQsCBhmG1fjKee//8v/zZiSGJ+AZeOR3lQChxPDyB/EeIjFo28SuKSf6jk0sjoPXaHDh+6yjiDzLjmaUDaDKZe77fR4GAy5rNaNVK2DnQlwXEXOIs4Bz9f8AU85TG4CfW1AKv93mul7ndTjkfT4HETSgN5sCAK256XS47XZRlQrrKOIqCMjTlDxNjU7UoV6TTSZ8Lpfc9XoEoxFutUo6HvOxWBgdHL1EcRy8ZhOv1UKVSrzNZmTTKflqVQwA2wOBbX6trZeo2P6qQ+p3JqsYSBQQmiAFKgHCL3I+UIXeDJynAAAAAElFTkSuQmCC
// @license      MIT
// ==/UserScript==

(function () {
  "use strict";

  //脚本设置项
  let settings = {
    enable_forum_style_override: 1, // 是否开启论坛排版样式优化,0 关闭;1 开启。开启后页面间距更紧凑,可使浏览更加高效
    enable_forum_auto_pager: 1, // 是否开启论坛自动翻页功能,0 关闭;1 开启
    enable_main_auto_pager: 1, // 是否开启主站自动翻页功能,0 关闭;1 开启
    enable_hide_sign_image: 0, // 是否开启隐藏签名图
    enable_debug_mode: 0,
  };

  /**
   * 当前页面的浏览模式 forumdisplay 板块列表页 | viewthread 帖子详情页 | default 默认适用于其他所有页面 | actresses 演员页 | favorite 收藏页(论坛) | forum 论坛搜索结果 | thread 个人主题/回复页 | guide 新帖导读页 | friend 好友页 | notice 我的通知
   * @type { "forumdisplay" | "viewthread" | "default" | "actresses" | "favorite" | "forum" | "thread" | "guide" | "friend" | "notice"}
   */
  let PAGE_MOD = "default";
  let CURRENT_SETTING = null; //当前页翻页规则
  let isForum = false; //当前页是否是论坛页面
  let authorLink = null; //楼主个人空间链接(用于判断用户是否为楼主)
  let loadedURLSet = null; //已加载过的页面URL(防止重复加载)
  const PAGE_SETTINGS = {
    default: {
      listDomSelector: "#waterfall.masonry",
      itemDomSelector: "#waterfall > .item:has(.movie-box)",
      pagerDomSelector: ".pagination.pagination-lg",
      nextPageDomSelector: "#next",
      nodeAfterAddCall: () => {
        //重新计算瀑布流的布局
        jQuery("#waterfall").masonry("reload");
      },
    },
    actresses: {
      listDomSelector: "#waterfall.masonry",
      itemDomSelector: "#waterfall > .item:has(.avatar-box)",
      pagerDomSelector: ".pagination.pagination-lg",
      nextPageDomSelector: "#next",
      nodeAfterAddCall: () => {
        //重新计算瀑布流的布局
        jQuery("#waterfall").masonry("reload");
      },
    },
    viewthread: {
      listDomSelector: "#postlist",
      itemDomSelector: "#postlist > .nthread_postbox:not(.nthread_firstpostbox)",
      pagerDomSelector: ".mn > .pgs.mtm.mbm.cl > .pg",
      nextPageDomSelector: ".nxt",
      nodeBeforeAddCall: (node) => {
        node.querySelector(".imicn a[title='查看個人網站']")?.remove(); //删除多余的元素
        node.querySelector(".showmenu").style.display = "none"; //隐藏‘使用道具’菜单
        //标记楼主
        markAuthor(node);
        //删除签名图
        if (settings.enable_hide_sign_image) {
          removeSignImage(node);
        }
        //移动‘举报’按钮
        moveReportButton(node);
      },
    },
    forumdisplay: {
      listDomSelector: "#threadlisttableid",
      itemDomSelector: "#threadlisttableid > tbody",
      pagerDomSelector: "#fd_page_bottom > .pg",
      nextPageDomSelector: ".nxt",
    },
    forum: {
      listDomSelector: "#threadlist ul",
      itemDomSelector: "#threadlist ul > li",
      pagerDomSelector: "div.pgs.cl.mbm > .pg",
      nextPageDomSelector: ".nxt",
    },
    guide: {
      listDomSelector: "#threadlist table",
      itemDomSelector: "#threadlist table > tbody",
      pagerDomSelector: ".pg:has(.nxt)",
      nextPageDomSelector: ".nxt",
    },
    favorite: {
      listDomSelector: "#favorite_ul",
      itemDomSelector: "#favorite_ul > li",
      pagerDomSelector: "div.pgs.cl.mtm > .pg",
      nextPageDomSelector: ".nxt",
    },
    thread: {
      listDomSelector: ".tl table tbody",
      itemDomSelector: ".tl table tbody > tr:not(.th)",
      pagerDomSelector: "div.pgs.cl.mtm > .pg",
      nextPageDomSelector: ".nxt",
    },
    friend: {
      listDomSelector: "ul.buddy.cl",
      itemDomSelector: "ul.buddy.cl > li",
      pagerDomSelector: "div.mtm.pgs.cl > .pg",
      nextPageDomSelector: ".nxt",
    },
    notice: {
      listDomSelector: "div.nts",
      itemDomSelector: "div.nts > dl",
      pagerDomSelector: "div.pgs.cl > .pg",
      nextPageDomSelector: ".nxt",
    },
  };

  //脚本入口点,排除frame或iframe
  if (window !== window.top) return;

  initialized();
  overrideForumStyle();
  autoPager();

  function initialized() {
    let url = new URL(window.location.href);
    //根据 url 中的 mod 参数来判断当前页面类型
    let mod = url.searchParams.get("mod");
    if (mod) {
      isForum = true;
      //论坛中的二级页面
      let doType = url.searchParams.get("do");
      if (doType) {
        PAGE_MOD = doType;
      } else {
        PAGE_MOD = mod;
      }
    } else if (
      url.pathname.includes("actresses") ||
      url.pathname.includes("searchstar")
    ) {
      PAGE_MOD = "actresses";
    }
    //根据不同的页面,使用不同的翻页规则
    CURRENT_SETTING = PAGE_SETTINGS[PAGE_MOD];

    //帖子查看模式
    if (PAGE_MOD === "viewthread") {
      //读取楼主个人空间链接
      authorLink = document.querySelector(".authi.mb5 .au")?.href;
    }

    //将当前页面添加到已加载过的页面集合中
    loadedURLSet = new Set([window.location.href]);
  }

  function autoPager() {
    if (!CURRENT_SETTING) return;

    //翻页dom
    const obTarget = document.querySelector(CURRENT_SETTING.pagerDomSelector);
    //当前页面只有一页或已经是最后一页,无需翻页
    if (!obTarget || !obTarget.querySelector(CURRENT_SETTING.nextPageDomSelector)) {
      log("当前页面只有一页或已经是最后一页,无需翻页");
      return;
    }

    //观察器配置
    const observerOptions = {
      root: null,
      rootMargin: "0px",
    };
    //观察器回调
    const intersectionCallback = function (entries) {
      if (entries[0].intersectionRatio <= 0) return;
      //下一页的链接
      let nextPageLink = obTarget.querySelector(
        CURRENT_SETTING.nextPageDomSelector
      )?.href;
      //到尾页,停止观察器
      if (!nextPageLink) {
        autoPagerOB.disconnect();
        log("停止观察器");
      } else {
        //加载下一页的内容
        loadNextPage(nextPageLink);
      }
    };
    //创建交叉观察器
    let autoPagerOB = new IntersectionObserver(intersectionCallback, observerOptions);

    //在顶部导航栏的右侧增加控制按钮
    let navBar = document.querySelector(isForum ? "#toptb" : "#navbar");
    let toggleAutoPager = document.createElement("a");
    toggleAutoPager.href = "javascript:void(0)";
    toggleAutoPager.innerText = `${
      settings.enable_main_auto_pager ? "关闭" : "开启"
    }自动翻页`;
    toggleAutoPager.className = "nav navbar-nav navbar-right";
    toggleAutoPager.style.cssText = `
      display: block;
      padding: ${isForum ? "11" : "15"}px;
      color: rgb(119, 119, 119);
      float: right;
      font-size: 14px;
    `;

    toggleAutoPager.addEventListener("click", () => {
      if (settings.enable_main_auto_pager) {
        autoPagerOB?.unobserve(obTarget); //停止观察
        settings.enable_main_auto_pager = 0;
      } else {
        autoPagerOB?.observe(obTarget); //继续观察
        settings.enable_main_auto_pager = 1;
      }
      toggleAutoPager.innerText = `${
        settings.enable_main_auto_pager ? "关闭" : "开启"
      }自动翻页`;
    });
    navBar?.append(toggleAutoPager);
    if (
      (settings.enable_main_auto_pager && !isForum) ||
      (settings.enable_forum_auto_pager && isForum)
    )
      autoPagerOB.observe(obTarget);
  }

  function loadNextPage(nextPageURL, retryTime = 2, isRetry = false) {
    log(
      "nextPageURL:" +
        nextPageURL +
        "\t此次是否为重试请求:" +
        isRetry +
        "\t重试次数: " +
        retryTime
    );
    //忽略掉已加载过的页面地址,和当前正在加载的URL
    if (loadedURLSet.has(nextPageURL) && isRetry === false) {
      log("已加载过此页面的数据或正在加载此页面的数据,忽略本次请求");
      return;
    }
    if (isRetry === false) {
      //将第一次发起的请求页面添加到已访问页面集合中(非重试请求)
      loadedURLSet.add(nextPageURL);
    }
    fetch(nextPageURL)
      .then((resp) => {
        if (resp.redirected) {
          //服务器有一定概率会在访问时出现重定向
          log("请求被重定向\r\n目标链接: " + nextPageURL + "\r\n重定向地址: " + resp.url);
          if (loadedURLSet.has(resp.url) && retryTime > 0) {
            //重试
            return loadNextPage(nextPageURL, --retryTime, true);
          }
        }
        return resp.text();
      })
      .then((text) => {
        if (!text) return;
        let nextPageDocument = convertTextToDOM(text);
        log(
          "title:" + nextPageDocument?.head.getElementsByTagName("title")[0]?.innerText
        );
        const comments = nextPageDocument.querySelectorAll(
          CURRENT_SETTING.itemDomSelector
        );
        //追加内容之前对每个item的预处理回调
        if (CURRENT_SETTING.nodeBeforeAddCall) {
          comments.forEach(CURRENT_SETTING.nodeBeforeAddCall);
        }
        let postlist = document.querySelector(CURRENT_SETTING.listDomSelector);
        //用新页面的分页DOM元素来替换上一页的分页DOM
        document.querySelector(CURRENT_SETTING.pagerDomSelector).innerHTML =
          nextPageDocument.querySelector(CURRENT_SETTING.pagerDomSelector).innerHTML;
        postlist?.append(...Array.from(comments));
        //追加内容之后的处理回调
        if (CURRENT_SETTING.nodeAfterAddCall) {
          CURRENT_SETTING.nodeAfterAddCall.call();
        }
      })
      .catch((e) => {
        log("加载内容出错");
        //从集合中删除请求地址
        loadedURLSet.delete(nextPageURL);
        return;
      });
  }

  function convertTextToDOM(text) {
    const parser = new DOMParser();
    return parser.parseFromString(text, "text/html");
  }

  /**
   * 标记楼主
   * @param {HTMLElement} node 回复消息元素
   */
  function markAuthor(node) {
    const authorDom = node.querySelector(".authi .xw1");
    //如果与作者的个人空间链接相同,则说明当前回复内容是由楼主发布的
    if (authorDom?.href === authorLink) {
      authorDom.insertAdjacentElement("afterend", _createOPTag());
    }
    //点评区域的内容也同样进行楼主标记
    node.querySelectorAll(".pstl.xs1.cl a:is(.xi2.xw1)").forEach((commentAuthorDom) => {
      if (commentAuthorDom?.href === authorLink) {
        commentAuthorDom.insertAdjacentElement(
          "afterend",
          _createOPTag("margin:0 0 0 4px")
        );
      }
    });
    //创建一个标识楼主的Tag元素
    function _createOPTag(tagStyle = "") {
      //楼主标识元素,用于在帖子中显示楼主
      let authorTagDOM = document.createElement("span");
      authorTagDOM.style.cssText = `
        color: #55b624;
        border: 1px solid #55b624;
        padding: 1px 3px;
        border-radius: 2px;
        margin: 0 6px;
      `;
      if (tagStyle) {
        authorTagDOM.style.cssText += tagStyle;
      }
      authorTagDOM.textContent = "楼主";
      return authorTagDOM;
    }
  }

  /**
   * 在新位置添加举报按钮,并将原始位置的容器元素隐藏,从而使页面布局更加紧凑
   * @param {HTMLElement} node 回复消息元素
   */
  function moveReportButton(node) {
    //如果当前回复没有‘点评’和‘回复’按钮,也没有‘管理’按钮;则表明帖子已经被归档,无法修改,此时可以移动举报按钮到右上角来节省空间
    if (
      node.querySelector(".fastre") ||
      node.querySelector(".cmmnt") ||
      node.querySelector(".po.hin")?.innerText.includes("管理")
    )
      return;
    //移动‘举报’按钮的位置
    const report = node.querySelector("td.plc p > a:nth-child(2)");
    if (report?.innerText === "舉報") {
      report.style.marginTop = "-2px";
      report.style.color = "#ccc";
      node.querySelector("td.plc > div.pi strong")?.appendChild(report);
      node.querySelector(".po.hin")?.style.setProperty("display", "none");
    }
  }

  /**
   * 删除签名图
   * @param {HTMLElement} node 回复消息元素
   */
  function removeSignImage(node) {
    node.querySelector(".sign")?.remove();
  }

  function overrideForumStyle() {
    //只对论坛页面生效
    if (!isForum) return;

    if (PAGE_MOD === "viewthread") {
      //将上传图片和发表评论组合到一起
      //#Form1.parentElement 表示的是上传图片附件的DOM元素
      let f_pst = document.querySelector("#f_pst");
      f_pst?.append(document.querySelector("#Form1").parentElement);
      let firstPost = document.querySelector(".nthread_firstpost"); //#1楼的帖子
      //将回复帖子的Form移动到1楼下面
      firstPost?.insertAdjacentElement("afterend", f_pst);

      //增加一个快速定位回复框的按钮
      let goReply = document.createElement("a");
      goReply.id = "goReply";
      goReply.href = "javascript:void(0)";
      goReply.addEventListener("click", () => {
        f_pst.scrollIntoView();
      });
      goReply.style.cssText = `
        display: block;
        position: fixed;
        bottom: 370px;
        width: 50px;
        height: 50px;
        background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAAAD1BMVEUAAADvSETxSETySEPxSEOfb+sGAAAABHRSTlMAQIC/o1TdDAAAAGJJREFUeNrty4EGgEAQBuFp/3v/Zw4r54rVL6LuBgx8tDsFvQW+DiLT8BUgi+EfgdypQd0CPwKKou0KRN0ZCA8IDwgPiKNodQmEB4QHhAl4D9TJBcgFhAW6wBW4AlfgClyxA0shFWNNOTW7AAAAAElFTkSuQmCC) no-repeat 50% 50%;
        background-color: #fff;
        background-size: 28px 28px;
      `;
      document.querySelector(".biaoqi-fix-area").appendChild(goReply);

      //遍历第一页的所有帖子消息
      const nodes = document.querySelectorAll("#postlist > .nthread_postbox");
      for (const node of nodes) {
        if (settings.enable_hide_sign_image) {
          //删除签名图
          removeSignImage(node);
        }
        //标记楼主
        markAuthor(node);
        //移动‘举报’按钮
        moveReportButton(node);
      }
    }

    let styleRules = `
      #goReply:hover{background-blend-mode: screen;background-color: #F14843 !important;}
      #toptb{position: sticky; top: 0; z-index: 99;}
    `;

    if (settings.enable_forum_style_override) {
      styleRules += `
        .psth {margin:1em 0 1em 0px}
        .pls .avatar img { border-radius:50%; height: 50px; }
        tr .plm { padding-top: 10px !important }        
        .hin .pob { padding-bottom: 4px; padding-top: 4px;}
        .nthread_postbox .pi strong a { margin-top: -6px; }
        .t_fsz { min-height: auto; }
        .pct { padding-bottom: 0em; }
        #postlist .ad .pls, #postlist .ad .plc { display: none; }
        .pcb .cm .psth { margin-top: 0px; }
        .pcb .cm .psth { margin-bottom: 10px; }
        .t_f, .t_f td { line-height: 1.6; }
        .pcb .psth { font-size: 14px !important; font-weight: 500; }
        #p_btn { padding:0 0 10px 0; }
        .jav-footer { display: none; }        
        #postlist { padding: 0 20px 0px 20px; }
        a[rel="nofollow"]{display:none;}        
        .ct2 .mn {margin-bottom: 0;}
        .authi em { color:#ccc; }
        .pob { line-height: 32px; }
      `;
    }
    GM_addStyle(styleRules);
  }

  function log(msg) {
    if (settings.enable_debug_mode == true) {
      if (typeof msg === "object") {
        console.dir(msg);
      } else {
        console.log(msg);
      }
    }
  }
})();