知乎首页信息流过滤

可以按照标签过滤知乎首页信息流,隐藏含不喜欢标签的回答。

目前為 2021-08-06 提交的版本,檢視 最新版本

// ==UserScript==
// @name         知乎首页信息流过滤
// @namespace    https://zhaoji.wang/
// @version      0.1.1
// @description  可以按照标签过滤知乎首页信息流,隐藏含不喜欢标签的回答。
// @author       Zhaoji Wang
// @license      Apache-2.0
// @match        https://www.zhihu.com/
// @match        https://www.zhihu.com/follow
// @icon         https://www.google.com/s2/favicons?domain=zhihu.com
// @grant        none
// @require      https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js
// @require      https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.min.js
// @require      https://cdn.bootcdn.net/ajax/libs/localforage/1.9.0/localforage.min.js
// ==/UserScript==

"use strict";

$(() => {
  $(".Topstory-mainColumn").prepend('<div id="filter-rules"></div>');
  const app = new Vue({
    el: "#filter-rules",
    template: `
        <div
            id="filter-rules"
            style="background: #fff; box-shadow: 0 1px 3px rgb(18 18 18 / 10%); padding: 20px; border-bottom: 1px solid #f0f2f7; margin-bottom: 10px; border-radius: 2px;"
            v-if="isLoadConfigDone"
        >
            <div class="header" style="position: relative;">
                <div style="font-size: 18px; font-weight: 600; line-height: 1.6;">
                    过滤规则
                </div>
                <div
                    class="action-bar"
                    style="position: absolute; right: 0; top: 2px;"
                >
                    <button
                        @click="addRule()"
                        style="line-height: 2; padding: 0 12px; color: #06f; text-align: center; border: 1px solid; border-radius: 3px; cursor: pointer; font-size: 12px;"
                    >
                        添加标签
                    </button>
                    <button
                        @click="toggleBarDisplayStatus()"
                        style="line-height: 2; padding: 0 12px; color: #06f; text-align: center; border: 1px solid; border-radius: 3px; cursor: pointer; font-size: 12px;"
                    >
                        {{ barIsShown ? '折叠' : '展开' }}
                    </button>
                </div>
            </div>
            <div
                v-show="barIsShown"
                style="line-height: 1.67; margin-top: 9px;"
            >
                <div
                    class="rule-tag"
                    title="点击可删除该标签"
                    style="position: relative; display: inline-block; height: 30px; padding: 0 12px; font-size: 14px; line-height: 30px; color: #06f; border-radius: 100px; background: rgba(0,102,255,.1); margin: 3px 5px 3px 0; vertical-align: middle; cursor: pointer;"
                    v-if="rules.length"
                    v-for="(v, i) in rules"
                    :key="v"
                    @click="removeRule(i)"
                >
                    {{ v }}
                </div>
                <p v-if="!rules.length">
                    当前尚未设置规则
                </p>
            </div>
        </div>
        `,

    data() {
      return {
        isLoadConfigDone: false,
        rules: [],
        titles: [],
        tags: {},
        barIsShown: true
      };
    },

    methods: {
      async loadConfig() {
        let config = await localforage.getItem("zhihu-filter-config");

        if (!config) {
          config = await localforage.setItem("zhihu-filter-config", {
            barIsShown: true,
            rules: []
          });
        }

        this.barIsShown = config.barIsShown;
        this.rules = config.rules;
        this.isLoadConfigDone = true;
      },

      async saveConfig() {
        await localforage.setItem("zhihu-filter-config", {
          barIsShown: this.barIsShown,
          rules: this.rules
        });
      },

      async toggleBarDisplayStatus() {
        this.barIsShown = !this.barIsShown;
        await this.saveConfig();
      },

      async addRule() {
        const newTag = prompt("请输入需要被过滤的标签");

        if (newTag) {
          this.rules = Array.from(new Set([...this.rules, newTag]));
          await this.saveConfig();
        }
      },

      async removeRule(index) {
        this.rules.splice(index, 1);
        await this.saveConfig();
      },

      updateTitles() {
        this.titles = Array.from(
          $('.TopstoryItem [data-za-detail-view-element_name="Title"]')
        ).map((v) => ({
          title: $(v).text(),
          href: $(v).attr("href")
        }));
        setTimeout(this.updateTitles, 100);
      },

      updateTags() {
        this.titles.forEach(async (v) => {
          if (!this.tags[v.title]) {
            if (v.href.includes("question")) {
              const html = await $.get(v.href);
              const tags = Array.from($(".QuestionTopic", html)).map((e) =>
                $(e).text()
              );
              this.tags[v.title] = tags;
            } else {
              this.tags[v.title] = true;
            }
          }
        });
        setTimeout(this.updateTags, 1000);
      },

      updateQuestionsDisplayStatus() {
        Array.from($(".TopstoryItem")).forEach((v, i) => {
          const title = $(v)
            .find('[data-za-detail-view-element_name="Title"]')
            .text();

          if (
            !$(v).is(":hidden") &&
            this.tags[title] &&
            this.tags[title] !== true &&
            this.tags[title].some((tag) => this.rules.includes(tag))
          ) {
            $(v).hide();
            console.log("已过滤问题:", title);
          }
        });
        setTimeout(this.updateQuestionsDisplayStatus, 100);
      }
    },

    async created() {
      await this.loadConfig();
      this.updateTitles();
      this.updateTags();
      this.updateQuestionsDisplayStatus();
    }
  });
});

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址