前言
今天(2012-10-22)的搶書熱潮算是過去了,不過很遺憾的告訴大家,我算是失敗了,可惜呀可惜,博客園果然不是蓋的,湯姆大叔的書果然不是賣的(是送的)呀。失敗就得總結經驗,根據目測用工具的人那叫一個多呀,既然大家都玩到這程度了,肯定精確到秒那是不夠的了,不是還有4天嗎,為了搶到書,所以咱得改進改進。
經過測試博客園的時間要晚於北京時間2到3秒,比我本地時間要晚1秒850毫秒左右,盡管精確到這個點了,還是搶不到,為什么呢,除了因為人氣旺,還有一點當然是提交的延時無法咱們無法控制,博客園在壓力正常的情況下,提交延時大約為90-200ms,所以咱得把這個時間算上。應一些朋友要求,加了些注釋。
使用方式一樣,將下來代碼另存為GrabTheBook.user.js(一定要以”.user.js“為結尾),拖到google瀏覽器,然后進入(搶書地址)就可以了,也可以直接點擊文章最下方的下載鏈接,有些網友反映google瀏覽器無法安裝,大致是由於安全性導致,網友 @sati 提供了解決方法,見網址:http://www.itopdog.cn/software-tech/solution-to-chrome-blocking.html
版本
v1.1 秒級別定時搶書(剛開始還沒預計到搶書大潮會如此這般洶涌)上一篇
v2.1 時間精確到了毫秒(剛需呀)(圖1)
v2.2 修改了上一版本一些小BUG (圖2)
v3.0 第三次改進效果(加入了任務管理機制,更方便更直觀,可以很輕松實現網友 @刺蝟的溫馴 說的連環炮)(圖3)
(圖1) (圖2) (圖3)
第三版源碼

// ==UserScript== // @name Grab The Book // @author Xian Hong // @namespace http://www.cnblogs.com/xianhong/ // @description 搶湯姆大叔的書咯 // @include http://www.cnblogs.com/TomXu/archive/2012/10/22/2733027.html // ==/UserScript== function withjQuery(callback, safe) { if (typeof (jQuery) == "undefined") { var script = document.createElement("script"); script.type = "text/javascript"; script.src = "https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"; if (safe) { var cb = document.createElement("script"); cb.type = "text/javascript"; cb.textContent = "jQuery.noConflict();(" + callback.toString() + ")(jQuery);"; script.addEventListener('load', function () { document.head.appendChild(cb); }); } else { var dollar = undefined; if (typeof ($) != "undefined") dollar = $; script.addEventListener('load', function () { jQuery.noConflict(); $ = dollar; callback(jQuery); }); } document.head.appendChild(script); } else { callback(jQuery); } }; withjQuery(function ($) { Array.prototype.remove = function () { var newArr = new Array(); var a = arguments[0]; for (var i = 0; i < this.length; i++) { if (typeof (a) == "function") { if (!a(this[i])) newArr.push(this[i]); } else if (this[i] != a) { newArr.push(this[i]); } } return newArr; }; Array.prototype.find = function () { var args = arguments[0]; for (var i = 0; i < this.length; i++) { if (typeof (args) == "function") { if (args(this[i])) { return this[i]; } } } return false; }; var div = $("<div>", { html: '.', style: 'text-align:left;position: fixed;top: 10px;right: 10px;display: block;-webkit-text-size-adjust: none;font-size: 15px;width: 200px;background-color:white;' }).appendTo($(document.body)); $("<div>", { html: '<div style="background-color:white;">小時:<input type="text" style="width:50px;" id="txtHour" value="12"/>' + '當前時<input type="checkbox" id="chkCurrentHour" checked="checked" /><br />' + '分數:<input type="text" style="width:50px;" id="txtMinutes" value="0"/>' + '下一分<input type="checkbox" id="chkNextMinutes" checked="checked" /><br />' + '秒數:<input type="text" style="width:50px;" id="txtSecond" value="4"/><br />' + '毫秒:<input type="text" style="width:50px;" id="txtMilliseconds" value="150"/><br />' + '間隔:<input type="text" style="width:50px;" id="txtInterval" value="5"/>(ms)<br />' + '內容:<textarea id="txtComment" style="height:30px;width:100px;"></textarea><br />' + '<input type="button" id="btnExecSettings" value="執行設定" />' + '<input type="button" id="btnExec" value="添加任務" />' + '<br /> <a id="btnRemoveAll" href="javascript:;">[X]</a> 任務:</div><div id="taskContainer" style="background-color:white;"></div>', style: 'text-align:left;position: fixed;top: 40px;right: 10px;display: block;-webkit-text-size-adjust: none;font-size: 15px;width: 200px;height: 50px;background-color:white;' }).appendTo($(document.body)); var settings = { minutes: 0, //初始化搶書的分數 second: 4, //初始化本地時間的搶書秒數 milliseconds: 150, //初始化本地時間的搶書毫秒數 interval: 5 }; //獲取當前時間 var getCurTime = function () { var curTime = new Date(); return { hour: curTime.getHours(), minutes: curTime.getMinutes(), second: curTime.getSeconds(), milliseconds: curTime.getMilliseconds() }; }; var strContent = ""; var grabTheBook = function () { var curTime = getCurTime(); var content = $("#txtComment").val() + " 本地時間:------------" + curTime.minutes + ":" + curTime.second + ":" + curTime.milliseconds; var comment = {}; comment.postId = cb_entryId; comment.Body = content; comment.ParentCommentID = 0; var startDate = new Date(); $.ajax({ url: '/mvc/PostComment/New.aspx', data: JSON.stringify(comment), type: "post", dataType: "json", contentType: "application/json; charset=utf8", success: function (data) { if (data) { var dt = (new Date()).getTime() - startDate; strContent += "提交耗時:" + dt + " 提交內容:" + content + "<br />"; ShowCommentMsg(strContent); } else { var errorMsg = "抱歉!評論提交失敗!"; ShowCommentMsg(errorMsg); } }, error: function (xhr) { ShowCommentMsg("error:" + xhr.responseText); } }); }; var taskArray = []; var renderHtml = function () { $("#taskContainer").empty(); $(taskArray).each(function (i) { var task = this; if (typeof (this.h) != "function") { var removeE = $("<a>", { html: ' [X] ', href: 'javascript:;' }); var span = $('<span>', { html: '(' + (i + 1) + ')<<' + task.h + ":" + task.m + ":" + task.s + ":" + task.ms }); span.appendTo($("#taskContainer")); removeE.click(function () { task.breakFlag = true; taskArray = taskArray.remove(function (t) { return t.id == task.id; }); renderHtml(); }).appendTo(span); span.append("<br />"); } }); }; var id = 0; var templateFun = function (h, m, s, ms) { if (h && typeof (h) != "number") return; id++; m = m || settings.minutes; s = s || settings.second; ms = ms || settings.milliseconds; var task = { id: id, h: h, m: m, s: s, ms: ms, breakFlag: false }; taskArray.push(task); renderHtml(); var f = function () { if (task.breakFlag) return; var curTime = getCurTime(); div.html(curTime.hour + ':' + curTime.minutes + ":" + curTime.second + ":" + curTime.milliseconds); if (curTime.hour == h && curTime.minutes == m && curTime.second == s && curTime.milliseconds >= ms) { task.breakFlag = true; grabTheBook(); taskArray = taskArray.remove(function (t) { return t.id == task.id; }); renderHtml(); } else { setTimeout(f, settings.interval); //每間隔?毫秒執行一次 } }; return f; }; var settingFun = function () { var curTime = getCurTime(); settings.minutes = parseInt($("#txtMinutes").val()); settings.second = parseInt($("#txtSecond").val()); settings.milliseconds = parseInt($("#txtMilliseconds").val()); settings.interval = parseInt($("#txtInterval").val()); }; var removeAll = function () { $(taskArray).each(function () { var task = this; task.breakFlag = true; taskArray = taskArray.remove(function (t) { return t.id == task.id; }); renderHtml(); }); }; $("#btnRemoveAll").click(removeAll); $("#btnExecSettings").click(function () { settingFun(); removeAll(); templateFun(10)(); templateFun(12)(); templateFun(14)(); templateFun(16)(); templateFun(18)(); templateFun(20)(); }); $("#btnExec").click(function () { //點擊按鈕,重新為搶書秒數和搶書毫秒數賦值 settingFun(); var curTime = getCurTime(); var minite = $("#chkNextMinutes").attr("checked") ? curTime.minutes + 1 : parseInt($("#txtMinutes").val()); var hour = $("#chkCurrentHour").attr("checked") ? curTime.hour : parseInt($("#txtHour").val()); templateFun(hour, minite, parseInt($("#txtSecond").val()), parseInt($("#txtMilliseconds").val()))(); }); }, true);