不用寫外掛也能惡搞網頁

有時候是不是覺得瀏覽器很智障?網頁很不人性? 要是網頁是自己設計的就好了? 除了寫超爆幹複雜的 plug-in 外, 還有方便的 greasemonkey,和無腦的 bookmarklet, 都可以達到類似的效果。


活動介紹

本次 gholk 要來分享上古時代的瀏覽器密技 小書籤 , 和簡單粗勇的 油猴腳本 , 讓 javascript 開發者再也不用在 F12 開發者工具裡瞎忙半天, 也不需要寫超爆幹複雜的瀏覽器外掛, 就能輕鬆惡搞網站。


ccca 活動介紹

【社課 / Activity】

學過網頁設計的你,是否曾對設計不良的網頁感到不滿? 除了按 F12 使用瀏覽器的開發者工具,手動鍵入 js 來修改網頁外, 你還知道有小書籤 (bookmarklet) 、油猴 (greasemonkey) 腳本 (*.user.js) , 可以用來達成各式各樣的功能嗎?

當然,附加元件(瀏覽器外掛)問世後, 很快以更多的功能、更全面的權限管理,站上了這一系列工具的頂端。 但無論如何,如果你常常在開發者工具對第三方網頁敲敲打打, 那你絕對會喜歡小書籤與油猴腳本的。

<不用寫外掛也能惡搞網頁 - 小書籤與油猴腳本簡介>

社課中會介紹開發者工具、小書籤、油猴腳本, 與開發、發布程式上的技巧。


簡報模式

切換樣式


顯示小書籤程式碼


翻頁按鈕

把按鈕移到螢幕右下角

翻頁函數


駭客文化


生活駭客


伸手可及的距離


軟體與他們內建的語言


開發者友好的瀏覽器


開發者工具

瀏覽器 F12 開啟或右鍵檢查, 各種意義上都很好用。


快速選擇元素

使用開發者工具的 挑選頁面中的元素 , 把畫面上的元素在 檢測器 中的文件樹中顯示, 可以用來快速查看 html 文件結構。

dev-tool-select.png


在主控台中存取元素

在檢測器中的選取的元素, 可以在 主控台 中使用變數 $0 存取。


鎖右鍵圖片時

https://dq.yam.com/post.php?id=9229

document.querySelectorAll('*[oncontextmenu]').forEach(node => {
    node.removeAttribute('oncontextmenu')
})

批次輸入多個輸入框

multiple-input-form.png


程式本體

let scoreList = scoreData.split(/\n/g)
document.querySelectorAll('input[type=text]').forEach((node, i) => {
    node.value = scoreList[i]
})

處理 io


多行字串的處理

console-insert-multiple-line.png


簡單與使用者互動


熟悉你的工具

如果你發現你常使用主控台做事,那找個時間好好認識一下開發者工具, 找篇文章或是 google、mdn 的文件來讀,會受益良多的。

copy-from-console.png


厭倦不斷貼上重複的程式碼了嗎?

firefox-console-code-snippet.png


小書籤

一種特殊的 url schema, 和 data: 一樣不指向某一位置, 而是本身帶有意義。

greet-js


技術細節


回傳值

hello


安裝小書籤


發布需知


範例


youtube 搜尋小書籤

const keyWord = prompt('youtube 關鍵字')
window.open('http://youtube.com/search?q=' + keyWord)

小書籤 youtube 關鍵字搜尋 , 為什麼第二次點擊就不能執行了?


作用域

只呼叫函數 ,收藏後還可以執行嗎?


把用到的函數包進來

void function() {
  function promptYoutube() {
    const keyWord=prompt("youtube 關鍵字");
    window.open("http://youtube.com/search?q="+keyWord)
  }
  promptYoutube()
}()

把函數也包進來


void 算符

undefined === void anyExpression

函數表達式

void function () {
  // do what you want
)()

打包程式碼


javascript url 的用途到底是什麼?

<a href="javascript:doAction('menu')">open menu</a>
<a href="javascript:doAction('save')">save change</a>
<a href="javascript:doAction('exit')">discard change</a>

相對 onclick

onclick 回傳 false 表示不處理本來應該處理的事件, 例如 <input type="submit"> 如果 onclick 回傳 false 時不會提交, <a href="//google.com" 如果 onclick 回傳 false 時不會前往新頁面。

greet


data url


小書籤的侷限


GreaseMonkey


功能


安裝與使用


pastebin 托管範例

pastebin 的好處是免註冊即可使用。

pastebin創建腳本後點擊 raw 直接取得原始碼 , 並 修改網址結尾為 x.user.js


gist 托管範例

在 gist 創建腳本 ,檔名取為 *.user.js點擊 raw 即可直接取得原始碼 , 且網址結尾為自動成為對應的檔名。

gist 曾經有一段時間免註冊,但垃圾太多所以又關起來了。


metadata header

https://wiki.greasespot.net/Metadata_Block

// ==UserScript==
// @name  chrome bbs javascript executor
// @namespace  http://gholk.github.io/
// @description  press J in term.ptt.cc can run JavaScript
// @require https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
// @match https://term.ptt.cc/*
// @match https://www.clam.ml/*
// @match https://www.ptt.cc/bbs/*
// @version  13
// @grant  GM.notification
// @grant  GM.xmlHttpRequest
// ==/UserScript==

執行環境


GM.* API

GM.notification('hello (1)')
  .then(() => {
    return GM.notification('hello (2)')
  })
  .then(() => console.log('after send 2 notify'))

功能鍵


擴充元件


擴充元件與油猴的安全性

plugin-permission-request.png

greasemonkey-permission-request.png


因為擴充元件太複雜

雖然我寫過,但今天就不介紹了。


總結


什麼時候該用擴充元件?


重用小書籤與 user.js 的程式碼

if (typeof GM == 'object') runInGreaseMonkey()
else runInBookmarklet()

許願池

你有什麼功能想做嗎? 或是想練手卻不知道做什麼嗎? 來許願吧!


簡單 grease monkey repl

Read Evaluate Print Loop, 可以輸入表達式,程式會調用 eval 然後印出求值結果。 如果輸入是 promise,會等 resolve 後才顯示結果。


FB 備份功能

把一份貼文備份成 JSON 或其它格式, 並在原文被刪除時可以重發, 在每層樓 tag 原本的留言者並附上當初的留言。


BBSJS

在 ptt 上執行 javascript, 類似當初 BBSLua 的概念, 但是跑在瀏覽器上而不是 server 上。


clean window

開啟一個沒有工具列、分頁列、網址列的乾淨視窗, 同義於 chromium --app=https://www.youtube.com/embed/dWKNW5lm3Ss 。 通常是用在看 youtube 時想空出多點空間。 http://youtu.be/dWKNW5lm3Ss