Greasy Fork is available in English.

知乎一键素质三连

知乎 长按 点赞, 一键点赞喜欢收藏

// ==UserScript==
// @name         知乎一键素质三连
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  知乎 长按 点赞, 一键点赞喜欢收藏
// @author       liubiantao
// @match        https://*.zhihu.com/*
// @run-at       document-end
// @grant        none
// ==/UserScript==

;(function () {
  'use strict'

  const getTimeNow = () => new Date().getTime()

  let timeStart, timeEnd, time
  let playing = false

  function addAnimationStyle() {
    let style = document.createElement('style')
    style.type = 'text/css'
    style.innerHTML = `
    @keyframes shake {
        2% {
            transform: translate(.5px,-.5px) rotate(.5deg)
        }
    
        4% {
            transform: translate(-.5px,2.5px) rotate(.5deg)
        }
    
        6% {
            transform: translate(-1.5px,2.5px) rotate(-.5deg)
        }
    
        8% {
            transform: translate(-1.5px,.5px) rotate(1.5deg)
        }
    
        10% {
            transform: translate(1.5px,2.5px) rotate(.5deg)
        }
    
        12% {
            transform: translate(-1.5px,2.5px) rotate(1.5deg)
        }
    
        14% {
            transform: translate(1.5px,1.5px) rotate(-.5deg)
        }
    
        16% {
            transform: translate(2.5px,-.5px) rotate(1.5deg)
        }
    
        18% {
            transform: translate(1.5px,.5px) rotate(.5deg)
        }
    
        20% {
            transform: translate(1.5px,-1.5px) rotate(-.5deg)
        }
    
        22% {
            transform: translate(-1.5px,-1.5px) rotate(-.5deg)
        }
    
        24% {
            transform: translate(-.5px,-1.5px) rotate(.5deg)
        }
    
        26% {
            transform: translate(-1.5px,2.5px) rotate(-.5deg)
        }
    
        28% {
            transform: translate(2.5px,1.5px) rotate(1.5deg)
        }
    
        30% {
            transform: translate(.5px,-.5px) rotate(1.5deg)
        }
    
        32% {
            transform: translate(1.5px,2.5px) rotate(1.5deg)
        }
    
        34% {
            transform: translate(-1.5px,-1.5px) rotate(-.5deg)
        }
    
        36% {
            transform: translate(-.5px,.5px) rotate(-.5deg)
        }
    
        38% {
            transform: translate(1.5px,-1.5px) rotate(1.5deg)
        }
    
        40% {
            transform: translate(-.5px,.5px) rotate(1.5deg)
        }
    
        42% {
            transform: translate(2.5px,-.5px) rotate(1.5deg)
        }
    
        44% {
            transform: translate(-1.5px,2.5px) rotate(.5deg)
        }
    
        46% {
            transform: translate(-.5px,2.5px) rotate(-.5deg)
        }
    
        48% {
            transform: translate(1.5px,-.5px) rotate(1.5deg)
        }
    
        50% {
            transform: translate(1.5px,-.5px) rotate(1.5deg)
        }
    
        52% {
            transform: translate(.5px,.5px) rotate(-.5deg)
        }
    
        54% {
            transform: translate(-.5px,-1.5px) rotate(-.5deg)
        }
    
        56% {
            transform: translate(1.5px,-1.5px) rotate(1.5deg)
        }
    
        58% {
            transform: translate(.5px,1.5px) rotate(1.5deg)
        }
    
        60% {
            transform: translate(-.5px,-.5px) rotate(1.5deg)
        }
    
        62% {
            transform: translate(-.5px,.5px) rotate(1.5deg)
        }
    
        64% {
            transform: translate(.5px,-.5px) rotate(1.5deg)
        }
    
        66% {
            transform: translate(2.5px,.5px) rotate(1.5deg)
        }
    
        68% {
            transform: translate(1.5px,-.5px) rotate(1.5deg)
        }
    
        70% {
            transform: translate(.5px,2.5px) rotate(1.5deg)
        }
    
        72% {
            transform: translate(1.5px,-.5px) rotate(.5deg)
        }
    
        74% {
            transform: translate(2.5px,-.5px) rotate(.5deg)
        }
    
        76% {
            transform: translate(2.5px,-.5px) rotate(1.5deg)
        }
    
        78% {
            transform: translate(-1.5px,-.5px) rotate(-.5deg)
        }
    
        80% {
            transform: translate(-1.5px,.5px) rotate(-.5deg)
        }
    
        82% {
            transform: translate(-1.5px,2.5px) rotate(.5deg)
        }
    
        84% {
            transform: translate(-.5px,.5px) rotate(1.5deg)
        }
    
        86% {
            transform: translate(-1.5px,1.5px) rotate(.5deg)
        }
    
        88% {
            transform: translate(-.5px,-.5px) rotate(1.5deg)
        }
    
        90% {
            transform: translate(-1.5px,-1.5px) rotate(1.5deg)
        }
    
        92% {
            transform: translate(2.5px,1.5px) rotate(.5deg)
        }
    
        94% {
            transform: translate(2.5px,1.5px) rotate(-.5deg)
        }
    
        96% {
            transform: translate(2.5px,-.5px) rotate(.5deg)
        }
    
        98% {
            transform: translate(1.5px,.5px) rotate(-.5deg)
        }
    
        0%,to {
            transform: translate(0) rotate(0)
        }
    }
    `

    document.getElementsByTagName('head')[0].appendChild(style)
  }
  addAnimationStyle()

  function getComboButtons(voteButton) {
    const parentEl = voteButton.parentElement.parentElement
    const starButton = parentEl.childNodes[3]
    const likeButton = parentEl.childNodes[4]

    return [voteButton, starButton, likeButton]
  }

  function getSvg(node) {
    return node.childNodes[0].childNodes[1]
  }

  function playAnimation(svg) {
    playing = true
    svg.style.animation = 'shake 1s ease-in-out infinite'
  }

  function stopAnimation(svg) {
    playing = false
    svg.style.animation = ''
  }

  function combo(comboButtons) {
    comboButtons.forEach((el) => {
      el.click()
    })
  }

  function holdDown(voteButton) {
    const comboButtons = getComboButtons(voteButton)

    timeStart = getTimeNow()
    time = setInterval(function () {
      timeEnd = getTimeNow()

      if (timeEnd - timeStart > 200 && !playing) {
        comboButtons.forEach((el) => {
          const svg = getSvg(el)
          playAnimation(svg)
        })
      }

      if (timeEnd - timeStart > 1500) {
        clearInterval(time)
        combo(comboButtons)
        comboButtons.forEach((el) => {
          const svg = getSvg(el)
          stopAnimation(svg)
        })
      }
    }, 100)
  }

  function holdUp(voteButton) {
    const comboButtons = getComboButtons(voteButton)
    clearInterval(time)
    if (playing) {
      comboButtons.forEach((el) => {
        const svg = getSvg(el)
        stopAnimation(svg)
      })
    }
  }

  const voteButtons = document.querySelectorAll('.VoteButton--up')

  voteButtons.forEach((voteButton) => {
    voteButton.addEventListener('mousedown', () => holdDown(voteButton))
    voteButton.addEventListener('mouseup', () => holdUp(voteButton))
  })
})()