自定义注入css和js脚本(广告屏蔽等)

可自定义css选择器屏蔽页面广告,注入js脚本

当前为 2021-01-10 提交的版本,查看 最新版本

// ==UserScript==
// @name         自定义注入css和js脚本(广告屏蔽等)
// @description  可自定义css选择器屏蔽页面广告,注入js脚本
// @namespace    _cus_ad_sp
// @version      1.0.0
// @author       vizo
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js
// @require      https://cdn.jsdelivr.net/npm/vio-utils/utils.js
// @include      /https?:\/\/[^localhost|127.0.0.1|192.168]+/
// @run-at       document-start
// @grant        GM_getResourceText
// @grant        GM_addStyle
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_listValues
// @grant        GM_registerMenuCommand
// @noframes

// ==/UserScript==

;(function() {
  if (vio.isMobile()) return
  let k = GM_getValue(`cus_${location.host}`) || {}
  if (k.css) {
    let css = `<style class="sty9z1p52">${k.css}</style>`
    document.head.insertAdjacentHTML('beforeend', css)
  }
})()
  
GM_addStyle(`
  img {
    display:none !important;
    height: 0 !important;
    overflow: hidden !important;
    pointer-events: none;
  }
  #modal5sn, #modal5sn * {
    margin: 0;
    padding: 0;
    box-sizing: border-box !important;
  }
  #modal5sn {
    width: 28vw;
    height: 68vh;
    min-width: 400px;
    padding: 30px;
    background: #fff;
    border-radius: 3px;
    line-height: 1.5;
    font-size: 12px;
    box-shadow: 0 0 5px #ccc;
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 50050;
    margin: auto;
  }
  #modal5sn .md-wp {
    height: 100%;
    display: flex;
    flex-direction: column;
  }
  #modal5sn .tit {
    color: #555;
    font-size: 18px;
    text-align: center;
    margin-bottom: 15px;
  }
  #modal5sn .c-item {
    margin-bottom: 10px;
    display: flex;
    flex-direction: column;
    flex-wrap: wrap;
  }
  #modal5sn .css-item,
  #modal5sn .js-item,
  #modal5sn .allset-item {
    flex: 1;
  }
  #modal5sn .sti {
    font-size: 15px;
    margin-bottom: 3px;
    position: relative;
  }
  #modal5sn .view-all-set {
    color: #09e;
    cursor: pointer;
    user-select: none;
    position: absolute;
    top: 0;
    right: 0;
  }
  #modal5sn .inpy {
    flex: 0 0 auto;
    height: 32px;
    border: 1px solid #ddd;
    color: #555;
    border-radius: 2px;
    padding: 0 10px;
    outline: none;
  }
  #modal5sn .inpy:focus {
    border: 1px solid #c1c1c1;
  }
  #modal5sn .txtr1z {
    flex: 1;
    color: #555;
    padding: 6px;
    overflow-x: hidden;
    overflow-y: auto;
    border-radius: 2px;
    border: 1px solid #ddd;
    font-size: 12px;
    resize: none;
    white-space: pre-line;
    outline: none;
    font-family: Consolas,sans-serif,"Helvetica Neue",Helvetica,"PingFang SC","Microsoft YaHei";
  }
  #modal5sn .txtr1z:focus {
    border: 1px solid #c1c1c1;
  }
  #modal5sn .txtr1z::-webkit-scrollbar {
    width: 4px;
  }
  #modal5sn .txtr1z::-webkit-scrollbar-corner,
  #modal5sn .txtr1z::-webkit-scrollbar-track {
    background-color: #fff;
  }
  #modal5sn .txtr1z::-webkit-scrollbar-thumb {
    background: #fff;
  }
  #modal5sn .txtr1z:hover::-webkit-scrollbar-thumb {
    background: #e1e1e1;
  }
  #modal5sn .txtr1z:hover::-webkit-scrollbar-corner,
  #modal5sn .txtr1z:hover::-webkit-scrollbar-track {
    background-color: #f7f7f7;
  }
  #modal5sn .btn-w {
    margin-top: 5px;
    display: flex;
    flex-direction: row-reverse;
  }
  #modal5sn .btn-w .c-btn {
    width: 90px;
    height: 32px;
    border-radius: 2px;
    margin-right: 10px;
    color: #555;
    background-color: #f1f1f1;
    cursor: pointer;
    outline: none;
    border: 0;
  }
  #modal5sn .btn-w .c-btn.b1 {
    color: #fff;
    background-color: #09e;
  }
  #modal5sn .btn-w .c-btn:first-child {
    margin-right: 0;
  }
  #modal5sn .btn-w .c-btn:focus {
    border: 0;
  }
  #modal5sn .btn-w .c-btn:hover {
    opacity: 0.9;
  }
`)

const G = {
  html: `
    <div id="modal5sn" v-show="dialog1s">
      <div class="md-wp">
        <div class="tit">设置</div>
        <div class="c-item">
          <p class="sti">打开面板快捷键 <span class="view-all-set" @click="hdlViewAllSet">{{ viewSetText }}</span></p>
          <input type="text" class="inpy" v-model="eKey" placeholder="请输入a-z的任意字母">
        </div>
        <div class="c-item css-item" v-show="!showAllSet">
          <p class="sti">注入css(不用写style标签)</p>
          <textarea class="txtr1z" v-model="texCssVal" placeholder="请输入css代码"></textarea>
        </div>
        <div class="c-item js-item" v-show="!showAllSet">
          <p class="sti">注入js(不用写script标签)</p>
          <textarea class="txtr1z" v-model="texJsVal" placeholder="请输入js代码"></textarea>
        </div>
        <div class="c-item allset-item" v-show="showAllSet">
          <p class="sti">全部网站已注入的css和js</p>
          <textarea class="txtr1z" v-model="allSetJson"></textarea>
        </div>
        <div class="btn-w">
          <button class="c-btn b2" @click="hdlCancel">取消</button>
          <button class="c-btn b1" @click="hdlSave">保存</button>
        </div>
      </div>
    </div>
  `,
}
const vm = new Vue({
  data() {
    return {
      // 模态框状态
      dialog1s: false,
      // 快捷键名称
      eKey: '',
      showAllSet: false,
      // css代码
      texCssVal: '',
      // js代码
      texJsVal: '',
      // 全部设置
      allSetJson: '',
    }
  },
  computed: {
    viewSetText() {
      return this.showAllSet ? '查看当前网站' : '查看全部网站'
    },
  },
  watch: {
    eKey(nVal) {
      this.eKey = /[a-z]/.test(nVal) ? nVal.slice(0, 1) : ''
      GM_setValue('cusBKEkey', this.eKey)
    },
    dialog1s(nVal) {
      if (!nVal) {
        this.showAllSet = false
      }
    },
  },
  methods: {
    setGmVal(val) {
      return GM_setValue(`cus_${location.host}`, val)
    },
    getGmVal() {
      return GM_getValue(`cus_${location.host}`) || {}
    },
    hdlSave() {
      this.injectCssAndRemoveOld()
      this.injectJsAndRemoveOld()
      this.initAllCssJsJson()
      this.dialog1s = false
    },
    hdlCancel() {
      this.dialog1s = false
    },
    injectCssAndRemoveOld() {
      let css = `<style class="sty9z1p52">${this.texCssVal}</style>`
      document.head.insertAdjacentHTML('beforeend', css)
      
      this.setGmVal({
        ...this.getGmVal(),
        css: this.texCssVal
      })
      
      Array.from(document.querySelectorAll('.sty9z1p52')).forEach((v, i, y) => {
        if (i !== y.length - 1) {
          v.remove()
        }
      })
    },
    injectJsAndRemoveOld() {
      let st = document.createElement('script')
      st.classList.add('js7z1p32')
      st.textContent = this.texJsVal
      document.body.appendChild(st)
      
      this.setGmVal({
        ...this.getGmVal(),
        js: this.texJsVal
      })
      
      Array.from(document.querySelectorAll('.js7z1p32')).forEach((v, i, y) => {
        if (i !== y.length - 1) {
          v.remove()
        }
      })
    },
    tgCfgDialog() {
      this.dialog1s = !this.dialog1s
    },
    hdlViewAllSet() {
      this.showAllSet = !this.showAllSet
      // GM_listValues()
    },
    resetInjectCss() {
      this.texCssVal = ''
      this.setGmVal({
        ...this.getGmVal(),
        css: '',
      })
      location.reload()
    },
    resetInjectJs() {
      this.texJsVal = ''
      this.setGmVal({
        ...this.getGmVal(),
        js: '',
      })
      location.reload()
    },
    initEvt() {
      window.addEventListener('keydown', e => {
        if (
          !(/text|search|number/.test(e.target.type)) &&
          e.target.tagName !== 'TEXTAREA' &&
          !e.altKey && 
          !e.ctrlKey &&
          e.key === this.eKey
        ) {
          this.tgCfgDialog()
        }
      })
    },
    initEkey() {
      this.eKey = GM_getValue('cusBKEkey') || ''
    },
    initCssJsVal() {
      this.texCssVal = this.getGmVal().css || ''
      this.texJsVal = this.getGmVal().js || ''
    },
    initAllCssJsJson() {
      const res = GM_listValues()
        .filter(v => v.includes('cus_'))
        .reduce((acc, v) => {
          return {
            ...acc,
            [v.slice(4)]: GM_getValue(v)
          }
        }, {})
      this.allSetJson = JSON.stringify(res, null, 2)
    },
    initInjectedScript() {
      let js = this.getGmVal().js
      if (js) {
        let st = document.createElement('script')
        st.classList.add('js7z1p32')
        st.textContent = js
        document.body.appendChild(st)
      }
    },
  },
  mounted() {
    this.initEvt()
    this.initEkey()
    this.initCssJsVal()
    this.initAllCssJsJson()
    this.initInjectedScript()
  },
})

const initFunc = () => {
  if (vio.isMobile()) return
  document.body.insertAdjacentHTML('beforeend', G.html)
  vm.$mount('#modal5sn')
  GM_registerMenuCommand('打开设置面板', vm.tgCfgDialog)
  GM_registerMenuCommand('重置注入的css', vm.resetInjectCss)
  GM_registerMenuCommand('重置注入的js', vm.resetInjectJs)
}

initFunc()

QingJ © 2025

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