🎉 欢迎访问GreasyFork.Org 镜像站!本镜像站由公众号【爱吃馍】搭建,用于分享脚本。联系邮箱📮

Greasy fork 爱吃馍镜像

B站 周姐

B站首页看各个分区!

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 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         B站 周姐
// @namespace    https://space.bilibili.com/15516023
// @version      1.2.2
// @description  B站首页看各个分区!
// @author       You
// @match        https://www.bilibili.com/*
// @icon         https://www.google.com/s2/favicons?domain=bilibili.com
// @grant        GM_addStyle
// @grant        GM_setValue
// @grant        GM_getValue
// @license      MIT
// ==/UserScript==

;(function () {
  'use strict'
  GM_addStyle(`
    #bili_custom .popover-video-card {
      display: none;
    }
    #bili_custom a:hover+.popover-video-card {
      display: block;
    }
    .pgc-rank-dropdown {
      position: relative;
      display: inline-block;
      vertical-align: middle;
      background-color: #fff;
      font-size: 12px;
      cursor: default;
      padding: 0 7px;
      height: 22px;
      line-height: 22px;
      border: 1px solid #ccd0d7;
      border-radius: 4px;
      margin-right: 12px;
  }
  
  .pgc-rank-dropdown:hover {
      border-radius: 4px 4px 0 0;
      -webkit-box-shadow: rgba(0,0,0,.16) 0 2px 4px;
      box-shadow: 0 2px 4px rgba(0,0,0,.16)
  }
  
  .pgc-rank-dropdown:hover .dropdown-list {
      display: block
  }
  
  .pgc-rank-dropdown .selected {
      display: inline-block;
      vertical-align: top
  }
  
  .pgc-rank-dropdown .icon-arrow-down {
      background-image: url(//static.hdslb.com/images/base/icons.png);
      background-position: -475px -157px;
      display: inline-block;
      vertical-align: middle;
      width: 12px;
      height: 6px;
      margin-left: 5px;
      margin-top: -1px
  }
  
  .pgc-rank-dropdown .dropdown-list {
      position: absolute;
      width: 100%;
      background: #fff;
      border: 1px solid #ccd0d7;
      border-top: 0;
      left: -1px;
      top: 22px;
      z-index: 10;
      display: none;
      border-radius: 0 0 4px 4px
  }
  
  .pgc-rank-dropdown .dropdown-list .dropdown-item {
      cursor: pointer;
      margin: 0;
      padding: 3px 7px
  }
  
  .pgc-rank-dropdown .dropdown-list .dropdown-item:hover {
      background-color: #e5e9ef
  }
  
  `)

  const USERS = [
    {
      key_words: '周淑怡',
      channel_id: 780447,
      bigFans: [
        366314, //夕寒君
        408794610, //周姐日常事
        279220304, //米小莔
        2662674, //不2不叫火龙果
        30405149, //AA丶翼夜
        178505026, //AA丶熊熊
        1578665974, //全村最野的狗
        65888156, //hy弘月
        27330407, //拆城南宝
      ],
    },
    {
      key_words: 'A-SOUL',
      channel_id: 4429874,
      bigFans: [
        672328094, //嘉然今天吃什么
        672346917, //向晚大魔王
        672353429, //贝拉kira
        351609538, //珈乐Carol
        672342685, //乃琳Queen
      ],
    }
  ]

  let currentUserIndex = 0

  let currentPage = 1
  let page = 0
  let videoList = []

  const API = {
    getDetail: async (bvid) => {
      let res = await fetch(
        `https://api.bilibili.com/x/web-interface/archive/stat?bvid=${bvid}`,
      )
      return (await res.json()).data
    },
    getNewVideo: async () => {
      let res = await fetch(
        `https://api.bilibili.com/x/web-interface/search/type?context=&order=pubdate&keyword=${
          USERS[currentUserIndex].key_words
        }&search_type=video&page=${currentPage++}`,
      )
      videoList = videoList.concat((await res.json()).data.result)
    },
    getHotVideo: async () => {
      let res = await fetch(
        `https://api.bilibili.com/x/web-interface/web/channel/multiple/list?channel_id=${USERS[currentUserIndex].channel_id}&sort_type=hot&offset=&page_size=10`,
      )
      return (await res.json()).data.list[0].items
    },
  }

  function bigNumber(num) {
    return num > 10000 ? `${(num / 10000).toFixed(2)}万` : num
  }

  function s2d(string) {
    return new DOMParser().parseFromString(string, 'text/html').body
      .childNodes[0]
  }

  function timeFormat(time) {
    let res = []
    let [s = 0, m = 0, h = 0] = time.split(':').reverse()

    res.unshift(String(s).padStart(2, '0'))
    res.unshift(String(m % 60).padStart(2, '0'))
    res.unshift(String(h % 60).padStart(2, '0'))

    return res.join(':')
  }

  async function refresh() {
    console.log(`page:`, page, videoList.length)
    page++
    if (videoList.length <= page * 10 + 10) {
      await API.getNewVideo()
    }
    drawVideos()
  }

  function drawVideos() {
    const VIDEO_DOM = document.querySelector('#bili_custom .zone-list-box')
    VIDEO_DOM.innerHTML = ''

    videoList
      .slice(page * 10, page * 10 + 10)
      .sort((a, b) => {
        return USERS[currentUserIndex].bigFans.includes(b.mid) ? 1 : -1
      })
      .forEach((item) => {
        let title = item.title.replace(/<em class="keyword">(.*?)<\/em>/g, '$1')
        let DOM = s2d(`
        <div class="video-card-common">
          <div class="card-pic card-pic-hover"><a href="//www.bilibili.com/video/${
            item.bvid
          }" target="_blank"><img
              src="${item.pic}"
              alt="">
            <div class="count">
              <div class="left"><span><i class="bilifont bili-icon_shipin_bofangshu"></i>
                  ${item.play}
                </span><span><i class="bilifont bili-icon_shipin_dianzanshu"></i>${
                  item.favorites
                }</span></div>
              <div class="right"><span>${timeFormat(item.duration)}</span></div>
            </div><i class="crown ${
              USERS[currentUserIndex].bigFans.includes(item.mid) ? 'gold' : ''
            }"></i>
          </a>
          <div class="watch-later-video van-watchlater black"><span class="wl-tips" style="display: none;"></span>
          </div>
        </div><a href="//www.bilibili.com/video/${
          item.bvid
        }" target="_blank" title="${title}"
          class="title">
          ${title}
        </a><a href="//space.bilibili.com/${
          item.mid
        }/" target="_blank" class="up"><i
            class="bilifont bili-icon_xinxi_UPzhu"></i>${item.author}
        </a>
      </div>`)
        VIDEO_DOM.append(DOM)
      })
  }

  async function drawFirst(item) {
    const RANK_DOM = document.querySelector('#bili_custom .rank-list')
    let firstDetail = await API.getDetail(item.bvid)
    let firstTitle = item.name.replace(/<em class="keyword">(.*?)<\/em>/g, '$1')
    let first = `
    <div class="rank-wrap"><span class="number on">1</span>
      <div class="preview">
        <div class="pic">
          <a href="//www.bilibili.com/video/${
            item.bvid
          }" target="_blank" class="link">
            <img src="${item.cover}" alt="${firstTitle}">
          </a>
          <div class="watch-later-video van-watchlater black"><span class="wl-tips" style="display: none;"></span>
          </div>
        </div>
        <div class="txt"><a href="//www.bilibili.com/video/${
          item.bvid
        }" target="_blank" class="link">
            <p title="${firstTitle}">${firstTitle}</p>
          </a><span>播放次数:${bigNumber(firstDetail.view)}</span></div>
      </div>
      <div class="popover-video-card pvc" style="display: none;">
        <div class="content"><img src="${item.cover}" alt="">
          <div class="info">
            <p class="f-title">${firstTitle}</p>
            <p class="subtitle"><span class="name">${item.author_name}</span>
              <span class="point">·</span><span class="time">2021-11-22</span></p>
          </div>
        </div>
        <div class="count">
          <ul>
            <li><i class="bilifont bili-icon_shipin_bofangshu"></i><span>${bigNumber(
              firstDetail.view,
            )}</span></li>
            <li><i class="bilifont bili-icon_shipin_danmushu"></i><span>${bigNumber(
              firstDetail.danmaku,
            )}</span></li>
            <li><i class="bilifont bili-icon_shipin_shoucangshu"></i><span>${bigNumber(
              firstDetail.favorite,
            )}</span></li>
            <li><i class="bilifont bili-icon_shipin_yingbishu"></i><span>${bigNumber(
              firstDetail.coin,
            )}</span></li>
          </ul>
        </div>
      </div>
    </div>
    `
    RANK_DOM.append(s2d(first))
  }

  async function drawHot() {
    const RANK_DOM = document.querySelector('#bili_custom .rank-list')

    let rankList = await API.getHotVideo()
    await drawFirst(rankList.shift())
    rankList.forEach((item, index) => {
      let title = item.name.replace(/<em class="keyword">(.*?)<\/em>/g, '$1')
      let DOM = s2d(`
      <div class="rank-wrap"><span class="number ${index < 2 && 'on'}">${
        index + 2
      }</span>
        <a href="//www.bilibili.com/video/${
          item.bvid
        }" target="_blank" class="link">
          <p title="${title}" class="title">${title}</p>
        </a>
        <div class="popover-video-card pvc">
          <div class="content"><img
              src="${item.cover}" alt="">
            <div class="info">
              <p class="f-title">${title}</p>
              <p class="subtitle"><span class="name">${
                item.author_name
              }</span><span class="point">·</span><span
                  class="time">${timeFormat(item.duration)}</span></p>
            </div>
          </div>
          <div class="count">
            <ul>
              <li><i class="bilifont bili-icon_shipin_bofangshu"></i><span>${
                item.view_count
              }</span></li>
              <li><i class="bilifont bili-icon_shipin_danmushu"></i><span>-</span></li>
              <li><i class="bilifont bili-icon_shipin_shoucangshu"></i><span>-</span></li>
              <li><i class="bilifont bili-icon_shipin_yingbishu"></i><span>-</span></li>
            </ul>
          </div>  
        </div>
      </div>`)
      RANK_DOM.append(DOM)
    })
  }
  const drawSelector = () => {
    const HEADER_DOM = document.querySelector('#bili_custom .exchange-btn')
    let DOM = s2d(`
    <div class="pgc-rank-dropdown rank-dropdown"><span class="selected">${
      USERS[currentUserIndex].key_words
    }</span> 
      <i class="icon icon-arrow-down"></i> 
      <ul class="dropdown-list">
        ${USERS.map(
          (item, index) =>
            ` <li class="dropdown-item" index="${index}">${item.key_words}</li> `,
        ).join('')}
      </ul>
    </div>
    `)
    HEADER_DOM.prepend(DOM)

    document
      .querySelector('.dropdown-list')
      .addEventListener('click', injectDOM)
  }

  async function injectDOM(e) {
    currentUserIndex = e ? e.target.getAttribute('index') : 0
    videoList = []
    currentPage = 1
    page = 0

    const DOM = `
    <div id="bili_custom">
      <div class="space-between report-wrap-module report-scroll-module" id="bili_report_douga" scrollshow="true">
        <div class="card-list">
          <header class="storey-title">
          <div class="l-con"> <a
          href="https://search.bilibili.com/all?keyword=${USERS[currentUserIndex].key_words}" target="_blank" class="name">${USERS[currentUserIndex].key_words}</a></div>
          <div class="exchange-btn">
              <div class="btn btn-change custom-refresh"><i class="bilifont bili-icon_caozuo_huanyihuan"></i> 换一换 </div>
              <a href="https://search.bilibili.com/all?keyword=${USERS[currentUserIndex].key_words}&order=pubdate" target="_blank" class="btn more">
                更多 <i class="bilifont bili-icon_caozuo_qianwang"></i>
              </a>
            </div>
          </header>
          <div class="zone-list-box"> </div>
        </div>
        <div class="rank-list">
          <header class="rank-header"><span class="name">排行榜</span><a
              href="https://www.bilibili.com/v/channel/${USERS[currentUserIndex].channel_id}?tab=multiple" target="_blank" class="more">更多<i
                class="bilifont bili-icon_caozuo_qianwang"></i></a></header>
        </div>
      </div>
    </div>`
    let content = document.querySelector('.first-screen')
    let anchor = document.querySelector('#reportFirst2')
    let init = s2d(DOM)
    document.querySelector('#bili_custom') &&
      document.querySelector('#bili_custom').remove()
    // 插入初始模版
    console.log(`init:`, currentUserIndex)
    content.insertBefore(init, anchor)
    // 插入选择器
    drawSelector()
    // 插入最新视频
    await API.getNewVideo()
    drawVideos()
    // 插入热门视频
    drawHot()
    // 点击事件
    document.querySelector('.custom-refresh').addEventListener('click', refresh)
  }

  window.addEventListener(
    'load',
    async () => {
      await injectDOM()
    },
    false,
  )
})()