您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
try to take over the world!
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.cn-greasyfork.org/scripts/404470/811202/Timing_JQuery.js
// ==UserScript== // @name Timing_JQuery // @namespace http://tampermonkey.net/ // @version 0.1 // @description try to take over the world! // @author You // @match http://*/* // @grant none // ==/UserScript== /** * code from http://creativecouple.github.io/jquery-timing/jquery-timing.js * timing.jquery.js * * JavaScript functions for waiting / repeating / stopping jQuery actions. * * This code is published under the MIT License (MIT). * http://www.opensource.org/licenses/mit-license.php * * For examples, reference, and other information see * http://creativecouple.github.com/jquery-timing/ * * @author CreativeCouple * @author Peter Liske * @copyright (c) 2011 by CreativeCouple * @see http://creativecouple.github.com/jquery-timing/ */ (function(jQuery, window){ /** * object to store statically invoked threads */ var THREAD_GROUPS = {}, /** * unique timing identifier for different purposes */ tuid = 1, /** * remember original core function $.each() */ originalEach = jQuery.fn.each, /** * remember original core function $.on() (or $.bind()) */ originalOn = jQuery.fn.on || jQuery.fn.bind, /** * remember original core function $.off() (or $.unbind()) */ originalOff = jQuery.fn.off || jQuery.fn.unbind, /** * .until() and .all() have special meanings */ loopEndMethods = {}; function sameOrNextJQuery(before, after) { after = jQuery(after); after.prevObject = before; var i = before.length; if (i !== after.length) { return after; } while (i--) { if (before[i] !== after[i]) { return after; } } return before; } function loopCounts(loops) { var ret = [], i = loops.length; while (i--) { ret[i] = loops[i]._count; } return ret; } /** * Initialize a new timed invocation chain. * * @author CreativeCouple * @author Peter Liske * * @param context initial context * @param methodStack linked list of methods that has been or will be filled by someone else * @param ongoingLoops optional arguments for callback parameters * @param onStepCallback function to call on each step * @returns the timed invocation chain method */ function createTimedInvocationChain(context, methodStack, ongoingLoops, onStepCallback) { ongoingLoops = ongoingLoops || []; var executionState = { _context: context, _method: methodStack }, preventRecursion = false, method, otherExecutionState, deferred; function hookupToProxy(state, mockup){ state._canContinue = false; function fire(){ state._next = sameOrNextJQuery(state._context, state._next); state._canContinue = true; timedInvocationChain(); } return typeof mockup.promise == "function" ? mockup.promise().then(fire) : mockup.then(fire, true); } /** * Invoke all the methods currently in the timed invocation chain. * * @author CreativeCouple * @author Peter Liske */ function timedInvocationChain(deferredReturnValue) { while (!preventRecursion) try { // keep recursive calls away preventRecursion = !preventRecursion; // save current context state if (typeof onStepCallback == "function") { onStepCallback(jQuery.makeArray(executionState._next || executionState._context)); } // leave the chain when waiting for a trigger if (executionState._canContinue == false) { break; } // check end of chain if (!executionState._method._name) { if (deferred && (!ongoingLoops.length || ongoingLoops[0]._allowPromise)) { // resolve any waiting promise if (executionState._context && typeof executionState._context.promise == "function") { executionState._context.promise().then(deferred.resolve); } else { deferred.resolveWith(executionState._context); } deferred = null; } if (!ongoingLoops.length) { /* * We've reached the end of our TIC * and there is nothing left to wait for. * So we can safely return the original jQuery object * hence enabling instant invocation. */ return executionState._context; } /* * Now we have ongoing loops but reached the chain's end. */ otherExecutionState = ongoingLoops[0]._openEndAction && ongoingLoops[0]._openEndAction(timedInvocationChain, executionState, ongoingLoops); if (!otherExecutionState) { // if innermost loop can't help us, just leave the chain break; } executionState = otherExecutionState; continue; } // check if user tries to use a non-existing function call method = executionState._context && executionState._context[executionState._method._name] || loopEndMethods[executionState._method._name]; if (!method) { throw 'no such method "'+executionState._method._name+'" on object ('+executionState._context+')'; } // check whether we came here triggered or not if (method.timing && !executionState._canContinue) { // prevent automatic re-trigger in case of loops executionState._canContinue = false; // handle timing method executionState = method.timing(timedInvocationChain, executionState, ongoingLoops, onStepCallback) || executionState; } else { if (!method.timing && !executionState._canContinue) { // prevent automatic re-trigger in case of loops executionState._next = executionState._context[executionState._method._name].apply(executionState._context, executionState._method._arguments); if (ongoingLoops.length && executionState._next && executionState._next instanceof PredictingProxy) { hookupToProxy(executionState, executionState._next); continue; } } // go to next step otherExecutionState = { _context: executionState._next, _method: executionState._method._next }; // prevent automatic re-trigger in case of loops executionState._canContinue = false; // invoke callback method with given arguments if (typeof executionState._callback == "function") { executionState._callback.apply(executionState._context, loopCounts(ongoingLoops)); } executionState = otherExecutionState; } } catch(e) { /* * We had a runtime exception. * In plain JavaScript live the chain would break now. * So we do, too. */ preventRecursion = !preventRecursion; throw e; } finally { preventRecursion = !preventRecursion; } return deferredReturnValue; }; if (jQuery.Deferred) { // add .promise() method to tic timedInvocationChain.promise = function(type, target){ var ret = (deferred = deferred || jQuery.Deferred()).promise(target); timedInvocationChain(); return ret; }; } return timedInvocationChain; } /** * Create a placeholder object to collect chained method calls. * * @author CreativeCouple * @author Peter Liske * * @param context initial context * @param methodStack a linked list that this placeholder will fill with call parameters * @return the placeholder object */ function PredictingProxy(context, methodStack, onStepCallback) { this['.methods'] = methodStack; this['.callback'] = onStepCallback; this.length = 0; Array.prototype.push.apply(this, jQuery.makeArray(this._ = context._ = context)); for (var key in context) { if (!(key in PredictingProxy.prototype) && typeof context[key] == "function") { this[key] = extendMockupPrototype(key); } } } // enabling jQuery.when(tic); if (jQuery.Deferred) { PredictingProxy.prototype.promise = function(type, target) { if (typeof type == "object") { target = type; type = null; } return (this['.callback'] && typeof this['.callback'].promise == "function") ? this['.callback'].promise(type, target) : jQuery.Deferred().resolveWith(this).promise(target); }; } /** * Create and return a new placeholder function on the prototype of PredictingProxy. */ function extendMockupPrototype(name){ return PredictingProxy.prototype[name] = function(){ this['.methods']._name = name; this['.methods']._arguments = arguments; this['.methods'] = this['.methods']._next = {}; return this['.callback'] ? this['.callback'](this, name, arguments) : this; }; } /** * Create replacement methods for .bind(), .on(), .one(), .live(), and .delegate() * that support chaining instead of giving a callback function. */ jQuery.each(['bind','on','one','live','delegate'], function(index, name){ if (jQuery.fn[name]) { var original = jQuery.fn[name]; jQuery.fn[name] = function(){ var i, methodStack, placeholder, timedInvocationChain, deferred, context = this; for(i=0; i<arguments.length; i++) { if (typeof arguments[i] == "function" || (arguments[i] && typeof arguments[i] == "object") || arguments[i] === false) { if (arguments[i] !== jQuery) { // fix for jQuery 1.6 .one() + .unbind() if (typeof arguments[i] == "function" && jQuery.guid) { arguments[i].guid = arguments[i].guid || jQuery.guid++; } return original.apply(context, arguments); } break; } } Array.prototype.splice.call(arguments, i, 1, function(){ timedInvocationChain = createTimedInvocationChain(context.$(this), methodStack, [{ _count: jQuery.extend(Array.prototype.shift.apply(arguments), arguments), _allowPromise: true }], function(elements){ placeholder.length = 0; Array.prototype.push.apply(placeholder, elements); }); if (deferred) { timedInvocationChain.promise().then(deferred.resolve); deferred = null; } return timedInvocationChain(); }); function fire(){ return timedInvocationChain ? timedInvocationChain(placeholder) : placeholder; } if (jQuery.Deferred) { fire.promise = function(type, target){ if (typeof type == "object") { target = type; type = null; } return (timedInvocationChain && !type) ? timedInvocationChain.promise(type, target) : (deferred = deferred || jQuery.Deferred()).promise(target); }; } return placeholder = new PredictingProxy(original.apply(context, arguments), methodStack = {}, fire); }; } }); /** * Create replacement method for .animate() and .load() * that support chaining if $ is given as callback function. */ jQuery.each(['animate','load'], function(index, name){ if (jQuery.fn[name]) { var original = jQuery.fn[name]; jQuery.fn[name] = function(){ while (arguments.length && arguments[arguments.length-1] == null) { Array.prototype.pop.apply(arguments); } if (this.length && arguments.length > 1 && arguments[arguments.length-1] === jQuery) { var event = '_timing'+tuid++; arguments[arguments.length-1] = function(){ jQuery(this).trigger(event); }; return this.each().one(event).all(original.apply(this, arguments)); } return original.apply(this, arguments); }; } }); /** * Define new methods .wait(), .repeat(), .join(), .then() * which will always start a new TIC if invoked outside of a TIC. */ jQuery.each(['wait','repeat','join','then'], function(index, name){ jQuery.fn[name] = function(){ var methodStack = {}, placeholder = new PredictingProxy(this, methodStack, createTimedInvocationChain(this, methodStack, [], function(elements){ placeholder.length = 0; Array.prototype.push.apply(placeholder, elements); })); return placeholder[name].apply(placeholder, arguments); }; }); /** * Define to wait for joining all animation queues. * * @param timedInvocationChain * @param executionState */ jQuery.fn.join.timing = function(timedInvocationChain, executionState) { var queueName, promising, waitingElements = executionState._context.length; if (typeof executionState._method._arguments[0] == "string") { queueName = executionState._method._arguments[0]; if (typeof executionState._method._arguments[1] == "function") { executionState._callback = executionState._method._arguments[1]; } else { promising = executionState._method._arguments[1]; executionState._callback = executionState._method._arguments[2]; } } else { if (typeof executionState._method._arguments[0] == "function") { executionState._callback = executionState._method._arguments[0]; } else { promising = executionState._method._arguments[0]; executionState._callback = executionState._method._arguments[1]; } } executionState._next = executionState._context; executionState._canContinue = !waitingElements; // wait for each element to reach the current end of its queue if (promising) { executionState._context.promise(queueName == null ? 'fx' : queueName).then(function(){ executionState._canContinue = true; timedInvocationChain(); }); } else { executionState._context.queue(queueName == null ? 'fx' : queueName, function(next){ executionState._canContinue = !--waitingElements; timedInvocationChain(); next(); }); } }; /** * Define to simply run callback method for .then() * * @param timedInvocationChain * @param executionState */ jQuery.fn.then.timing = function(timedInvocationChain, executionState){ executionState._callback = executionState._method._arguments[0]; executionState._next = executionState._context; executionState._canContinue = true; if (executionState._method._arguments[1]) { Array.prototype.shift.apply(executionState._method._arguments); } }; /** * Define timeout or binding to wait for. * * @param timedInvocationChain * @param executionState */ jQuery.fn.wait.timing = function(timedInvocationChain, executionState, ongoingLoops) { var trigger, event, timeout, context = executionState._context; trigger = executionState._method._arguments[0]; executionState._callback = executionState._method._arguments[1]; function triggerAction() { originalOff.call(event ? originalOff.call(context, event, triggerAction) : context, 'unwait', unwaitAction); executionState._canContinue = true; executionState._next = sameOrNextJQuery(executionState._context, executionState._next); timedInvocationChain(); } function unwaitAction(evt, skipWait){ originalOff.call(event ? originalOff.call(jQuery(this), event, triggerAction) : jQuery(this), 'unwait', unwaitAction); context = context.not(this); if (!skipWait) { executionState._next = executionState._next.not(this); } if (!context.length) { executionState._canContinue = executionState._next.length; executionState._next = sameOrNextJQuery(executionState._context, executionState._next); window.clearTimeout(timeout); executionState = { _context: context }; } // just update the snapshot info timedInvocationChain(); } originalOn.call(context, 'unwait', unwaitAction); executionState._next = context; if (trigger == null || trigger == jQuery) { trigger = context; } if (typeof trigger == "function") { trigger = trigger.apply(context, loopCounts(ongoingLoops)); } if (typeof trigger == "string") { originalOn.call(context, event = trigger, triggerAction); } else if (trigger && typeof trigger.promise == "function") { trigger.promise().then(triggerAction); } else if (trigger && typeof trigger.then == "function") { trigger.then(triggerAction, true); } else { timeout = window.setTimeout(triggerAction, Math.max(0,trigger)); } }; /** * Define to simply run callback method for .then() * * @param timedInvocationChain * @param executionState */ jQuery.fn.each = function(callback){ if (!callback || callback === jQuery) { var methodStack = {}, placeholder = new PredictingProxy(this, methodStack, createTimedInvocationChain(this, methodStack, [], function(elements){ placeholder.length = 0; Array.prototype.push.apply(placeholder, elements); })); return placeholder.each(callback); } return originalEach.apply(this, arguments); }; /** * Define interval or binding to repeat. * * @param timedInvocationChain * @param executionState */ jQuery.fn.each.timing = function(timedInvocationChain, executionState, ongoingLoops, onStepCallback) { if (executionState._method._arguments[0] && executionState._method._arguments[0] !== jQuery) { executionState._canContinue = true; executionState._next = originalEach.apply(executionState._context, executionState._method._arguments); return; } var size = Math.max(executionState._context.length, 1), finished = 0, key, methodToGoOn, openLoopTimeout, innerTICs = [], innerElements = [], proxyPlaceholder = jQuery.extend({}, executionState._context), stepByStep = executionState._method._arguments[0] === jQuery; if (stepByStep) { window.setTimeout(function(){ openLoopTimeout = true; timedInvocationChain(); },0); } function spreadAction(){ if (stepByStep) { if (finished < size) { (innerTICs[finished])(); } } else { for (var i=0; i<size; i++) { (innerTICs[i])(); } } return proxyPlaceholder; } for (key in PredictingProxy.prototype) { proxyPlaceholder[key] = spreadAction; } proxyPlaceholder.length = size; for(key=0; key<size; key++) (function(index){ var innerLoops = ongoingLoops.slice(), context = executionState._context.eq(index); innerElements[index] = context.get(); innerLoops.unshift({ _count: index, _allAction: function(state){ finished++; if (finished == size) { methodToGoOn = state._method._next; } timedInvocationChain(); }, _fixOpenLoop: loopEndMethods.all, _openEndAction: function(tic, state){ if (openLoopTimeout) { finished++; if (finished == size) { methodToGoOn = state._method; } timedInvocationChain(); } } }); innerTICs[index] = createTimedInvocationChain(context, executionState._method._next, innerLoops, function(elements){ innerElements[index] = elements; proxyPlaceholder.length = 0; for (var i=0; i<size; i++) { Array.prototype.push.apply(proxyPlaceholder, innerElements[i]); } if (onStepCallback) onStepCallback(jQuery.makeArray(proxyPlaceholder)); }); })(key); executionState._next = proxyPlaceholder; executionState._canContinue = true; executionState._openEndAction = function(tic, state){ if (finished == size) { ongoingLoops.shift(); return { _context: sameOrNextJQuery(executionState._context, proxyPlaceholder), _method: methodToGoOn }; } var finishedBefore = finished; spreadAction(); if (finished != finishedBefore) { return state; } }; executionState._count = size; ongoingLoops.unshift(executionState); }; loopEndMethods.all = function(executionState){ jQuery.extend(executionState._method, { _next: jQuery.extend({}, executionState._method), _name: 'all', _arguments: [] }); executionState._canContinue = null; }; loopEndMethods.all.timing = function(timedInvocationChain, executionState, ongoingLoops) { if (!ongoingLoops.length || !ongoingLoops[0]._fixOpenLoop) { throw '.all() method must be used after .each() only'; } if (!ongoingLoops[0]._allAction) { ongoingLoops[0]._fixOpenLoop(executionState); return; } ongoingLoops[0]._allAction(executionState); }; /** * Define interval or binding to repeat. * * @param timedInvocationChain * @param executionState */ jQuery.fn.repeat.timing = function(timedInvocationChain, executionState, ongoingLoops) { var trigger, firstRunNow, openLoopTimeout, event, interval; if (typeof executionState._method._arguments[0] == "function") { executionState._callback = executionState._method._arguments[0]; } else if (typeof executionState._method._arguments[1] == "function") { trigger = executionState._method._arguments[0]; executionState._callback = executionState._method._arguments[1]; } else { trigger = executionState._method._arguments[0]; firstRunNow = executionState._method._arguments[1]; executionState._callback = executionState._method._arguments[2]; } function triggerAction() { executionState._next = executionState._next || executionState._context; executionState._canContinue = true; timedInvocationChain(); } function unrepeatAction(){ originalOff.call(event ? originalOff.call(jQuery(this), event, triggerAction) : jQuery(this), 'unrepeat', unrepeatAction); var context = executionState._context.not(this); executionState._next = (executionState._next == executionState._context) ? context : executionState._next; executionState._context = context; executionState._canContinue = executionState._context.length && executionState._canContinue; trigger = executionState._context.length && trigger; window.clearInterval(!executionState._context.length && interval); // just update the snapshot info timedInvocationChain(); } executionState._openEndAction = function(tic, state){ if (executionState._canContinue || openLoopTimeout) { executionState._count++; executionState._next = executionState._next || executionState._context; executionState._canContinue = executionState._canContinue || (trigger && state._context && state._context.length); return executionState; } }; if (trigger == null) { firstRunNow = trigger = true; window.setTimeout(function(){ openLoopTimeout = true; timedInvocationChain(); },0); } else { if (typeof trigger == "string") { originalOn.call(executionState._context, event = trigger, triggerAction); } else { interval = window.setInterval(triggerAction, Math.max(0, trigger)); } trigger = false; } originalOn.call(executionState._context, 'unrepeat', unrepeatAction); executionState._next = executionState._context; executionState._count = 0; executionState._untilAction = function(end){ if (end) { unrepeatAction.apply(executionState._context); } if (trigger) { triggerAction(); } }; executionState._fixOpenLoop = loopEndMethods.until; if (firstRunNow) { triggerAction(); } ongoingLoops.unshift(executionState); }; /** * Defined to evaluate condition when calling .until() */ loopEndMethods.until = function(executionState){ jQuery.extend(executionState._method, { _next: jQuery.extend({}, executionState._method), _name: 'until', _arguments: [] }); executionState._canContinue = null; }; loopEndMethods.until.timing = function(timedInvocationChain, executionState, ongoingLoops) { if (!ongoingLoops.length || !ongoingLoops[0]._fixOpenLoop) { throw '.until() method must be used after .repeat() only'; } if (!ongoingLoops[0]._untilAction) { ongoingLoops[0]._fixOpenLoop(executionState); return; } var condition = executionState._method._arguments[0], loopContext = executionState._method._arguments[1]; if (condition === jQuery) { condition = null; loopContext = executionState._method._arguments.length <= 1 || loopContext; } if (typeof condition == "function") { condition = condition.apply(executionState._context, loopCounts(ongoingLoops)); } if (condition == null) { condition = !executionState._context.size(); } if (typeof condition == "object") { condition = condition.toString(); } if (typeof condition == "number") { condition = ongoingLoops[0]._count >= condition-1; } if (condition) { executionState._canContinue = true; executionState._next = executionState._context; ongoingLoops.shift()._untilAction(condition); } else { if (loopContext) { ongoingLoops[0]._next = executionState._context; } executionState = ongoingLoops[0]; executionState._count++; executionState._untilAction(condition); return executionState; } }; // support .until() and .all() new PredictingProxy(loopEndMethods); /** * Define unwait and unrepeat methods. */ jQuery.each(['unwait','unrepeat'], function(index, name){ jQuery.fn[name] = function(){ return this.trigger(name, arguments); }; }); /** * define all static timing methods: * $.wait, $.repeat ,$.join, $.then, $.unwait, $.unrepeat */ jQuery.each(['wait','repeat','join','then','unwait','unrepeat'], function(index, name){ jQuery[name] = function(){ var group = typeof arguments[0] == "string" ? Array.prototype.shift.apply(arguments) : ''; return jQuery.fn[name].apply(THREAD_GROUPS[group] = (THREAD_GROUPS[group] || jQuery('<div>').text(group)), arguments); }; }); /** * X defines deferred variables that can be used in timed invocation chains * * @author CreativeCouple * @author Peter Liske */ function X(compute, Var, calculation){ if (typeof compute == "string") { calculation = new Function('x','return ['+compute+'\n,x]'); compute = function(x, result){ result = calculation(x); callbackVariable.x = result[1]; return result[0]; }; } var hasRelatedVariable = typeof Var == "function", hasComputation = typeof compute == "function", callbackVariable = function(value) { if (arguments.length == 1) { callbackVariable.x = value; if (hasRelatedVariable) { Var(value); } } else { return evaluate(); } }; function evaluate(value){ value = hasRelatedVariable ? Var() : callbackVariable.x; return hasComputation ? compute(value) : value; } callbackVariable.x = 0; callbackVariable._ = { toString: callbackVariable.$ = callbackVariable.toString = evaluate.toString = evaluate }; callbackVariable.mod = function(val){ return X(function(x){ return x % val; }, callbackVariable); }; callbackVariable.add = function(val){ return X(function(x){ return x + val; }, callbackVariable); }; callbackVariable.neg = function(){ return X('-x', callbackVariable); }; // $$ only for backward compatibility callbackVariable.$$ = callbackVariable.X = function(compute){ return X(compute, callbackVariable); }; jQuery.each(['a','b','c','d','e','f','g','h','i','j'], function(index, character){ callbackVariable[index] = callbackVariable[character] = function(){ callbackVariable(arguments[index]); }; }); return callbackVariable; }; // $$ only for backward compatibility window.$$ = jQuery.$$ = jQuery.X = X; /** * Define chained version of $(). * This allows to use .end() to come back to previous jQuery selection. */ jQuery.fn.$ = function(){ var ret = jQuery.apply(window, arguments); ret.prevObject = this; return ret; }; })(jQuery, window);