我的第一個油猴腳本--微博超話自動簽到


簡介

用戶腳本是一段代碼,它們能夠優化您的網頁瀏覽體驗。安裝之后,有些腳本能為網站添加新的功能,有些能使網站的界面更加易用,有些則能隱藏網站上煩人的部分內容。其中常見的有 油猴插件ChromeExtentions

由於油猴腳本只用一個JS文檔,因而相對於ChromeExtentions比較簡單。因此便從油猴腳本開始,首先基本的文件架構是:

// ==UserScript==
// @name New Script  
// @namespace Violentmonkey Scripts
// @match http://ju.outofmemory.cn/entry/360333
// @grant none
// ==/UserScript==

其中一些屬性的含義:

@name :

腳本名稱

@description:

腳本功能的描述,顯示在腳本標題下面,必填項。

@namespace:

@namespace@name 這兩個屬性被作為腳本的唯一標識符,用戶腳本管理器根據它們來判斷一個腳本是否已安裝

@include, @exclude, @match:

描述腳本會在哪些網站上運行。該列表會被解析和展示到腳本的簡介頁面,並用於腳本的分類。

@supportURL:

該腳本的技術支持鏈接(如:錯誤反饋系統、論壇、電子郵件等),該鏈接將顯示在腳本的反饋頁面。

 

具體的注釋信息

腳本簡介

第一次編寫的腳本是微博超話自動簽到,主要借鑒bilibili助手的基本邏輯。本腳本功能實現每日自動簽到微博超話

界面圖:

微博自動簽到

總結:

1.基於$.ajax()對Deferred理解。

主要借鑒$.ajax()引發的對Deferred的總結回調、使用Promise封裝ajax()、Promise入門

ajax()是一種網頁中常用的異步操作,其寫法有兩種

//第一種,傳統寫法
$.ajax({
   url:"/xxx",
   type:"get",
   success:function(data){//成功調用后的回調函數},
   error:function(){//失敗調用后的回調函數}
});
//第二種
$.ajax({
   url:"/xxx",
   type:"get"
}).then(success,fail);//$.ajax()返回的是promise對象

Deffered是一種延遲對象 $.Deffered(),返回Deffered對象

done(fn) 當成功后調用fn

fail(fn) 當失敗后調用fn

then(done,fail) done和fail的總寫方式

always(fn) 不管成功或失敗都執行

 

resolve和reject執行,便執行done、fail、then、always方法。

resolve(value) 告訴對象執行done回調,value是參數,傳入done的回調函數 reject(value) 告訴對象執行fail回調,value是參數.傳入fail的回調函數

 

采用第二種寫法可以實現鏈式編程

const fn=()=>{const p =$.Deferred()
$.ajax({
   url:"/xxx",
   type:"get"
}).then(
  (data)=>{p.resolve(data)},
  ()=>{p.reject()}
);
return p}

fn().then((data)=>{
   //成功后的操作,data是resolve傳入的參數
   //如果還需要異步執行,可以再定義Deferred對象,以此來實現有順序的執行
},()=>{
   //失敗后的操作
})
2.跨域問題

由於JavaScript同源策略的限制,腳本只能讀取和所屬文檔來源相同的窗口和文檔。ajax請求時可能會請求不同源的網址。

首先以weibo.com為例說明同源

URL 結果 原因
https://www.weibo.com/dir1/other.html Success 同源
https://www.weibo.com/dir2/another.html Success 同源
https://m.weibo.com/1.html Fail 主機不同
http://www.weibo.com/2.html Fail 協議不同
https://www.weibo.com:80/3.html Fail 端口不同

這里用到了兩種:

  1. document.domain

默認情況下,document.domain存放的是載入文檔的服務器的主機名,但不能設置為頂級域名,如www.weibo.com 可以設置為weibo.com 但不能設置為com

 

具有相同的document.domain就處在同域名的服務器上

此處借鑒:通過document.domain實現跨域訪問

  1. CORS(跨域資源共享)

CROS是一種跨域訪問機制,可以實現Ajax的跨域訪問

需配置

//ajax中的配置
xhrFields.withCredentials = true
crossDomain = true
3.添加DOM元素

如果需要向網頁中添加按鍵、css樣式等等,就需要添加DOM元素,

添加方法

如果需要引入CSS樣式鏈接

$('head').append('<link rel="stylesheet" href="樣式的鏈接" />')

上面的方法主要采取的jquery的方法,也可以用原生JS

const addCSS = (context) => {
       const style = document.createElement('style');
       style.type = 'text/css';
       style.innerHTML = context;
       document.getElementsByTagName('head')[0].appendChild(style);
  };//該方法用於添加CSS樣式

 

4.檢查類型

一種是通過typeof,可以判斷undefined、boolean、string、number、function

用typeof判斷數據類型

可以看到typeof對 對象、數組、null判定為object,有一定的缺陷。

另一種方法用Object.prototype.toString.call判斷

 

用Object.prototype.toString.call來判斷

可以看到用此方法可以解決之前的混淆

除此之外,腳本也用到了isNaN()判斷是否為數字,如果為數字則為false,如果不是數字,則為true。

 

parseInt(string,radis)將其它類型轉換為Int類型,第二個參數為進制

注意: 只有字符串中的第一個數字會被返回。

注意: 開頭和結尾的空格是允許的。

注意:如果字符串的第一個字符不能被轉換為數字,那么 parseInt() 會返回 NaN。

5.localStorage

window的localStoragesessionStorage儲存k/v對的數據,localStorage 中的鍵值對總是以字符串的形式存儲。

localStorage用於長久保存整個網站數據。

方法:

localStorage.setItem('對象名','存儲的數據') 存儲

localStorage.getItem('對象名') 讀取

localStorage.removeItem('對象名') 移除

localStorage.clear() 移除所有

 

如果存儲的數據是JSON的類型,這可以用JSON.stringify()

JSON.parse()來進行JSON對象和String對象的類型轉換

 

6.一些以后可能用到的方法
const tz_offset = new Date().getTimezoneOffset() + 480;

const ts_s = () => Math.round(ts_ms() / 1000);

const ts_ms = () => Date.now();

const checkNewDay = (ts) => {
       // 檢查是否為新的一天,以UTC+8為准
       const t = new Date(ts);
       t.setMinutes(t.getMinutes() + tz_offset);
       t.setHours(0, 0, 0, 0);
       const d = new Date();
       d.setMinutes(t.getMinutes() + tz_offset);
       return (d - t > 86400e3);//86400秒為一天的時間
  };

const runUntilSucceed = (callback, delay = 0, period = 100) => {
       setTimeout(() => {
           if (!callback()) runUntilSucceed(callback, period, period);
      }, delay);
   //如果執行的函數返回值為空,就繼續執行,直到callback返回值
  };

let API={
processing: 0,
ajax: (settings) => {
if (settings.xhrFields === undefined) settings.xhrFields = {};
settings.xhrFields.withCredentials = true;
           jQuery.extend(settings, {
               url: (settings.url.substr(0, 2) === '//' ? '' : '//weibo.com/') + settings.url,
               method: settings.method || 'GET',
               crossDomain: true,
               dataType: settings.dataType || 'json'
          });//jquery.extend用於對象的連接
           const p = jQuery.Deferred();
           API.runUntilSucceed(() => {
               if (API.processing > 8) return false;
               ++API.processing;
               return jQuery.ajax(settings).then((arg1, arg2, arg3) => {
                   --API.processing;
                   p.resolve(arg1, arg2, arg3);
                   return true;
              }, (arg1, arg2, arg3) => {
                   --API.processing;
                   p.reject(arg1, arg2, arg3);
                   return true;
              });
          });
           return p;
      }  
}
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM