您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
arrive.js provides events to watch for DOM elements creation and removal. It makes use of Mutation Observers internally.
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/21927/139586/arrivejs.js
- /*
- * arrive.js
- * v2.3.1
- * https://github.com/uzairfarooq/arrive
- * MIT licensed
- *
- * Copyright (c) 2014-2016 Uzair Farooq
- */
- var Arrive = (function(window, $, undefined) {
- "use strict";
- if(!window.MutationObserver || typeof HTMLElement === 'undefined'){
- return; //for unsupported browsers
- }
- var arriveUniqueId = 0;
- var utils = (function() {
- var matches = HTMLElement.prototype.matches || HTMLElement.prototype.webkitMatchesSelector || HTMLElement.prototype.mozMatchesSelector
- || HTMLElement.prototype.msMatchesSelector;
- return {
- matchesSelector: function(elem, selector) {
- return elem instanceof HTMLElement && matches.call(elem, selector);
- },
- // to enable function overloading - By John Resig (MIT Licensed)
- addMethod: function (object, name, fn) {
- var old = object[ name ];
- object[ name ] = function(){
- if ( fn.length == arguments.length )
- return fn.apply( this, arguments );
- else if ( typeof old == 'function' )
- return old.apply( this, arguments );
- };
- },
- callCallbacks: function(callbacksToBeCalled) {
- for (var i = 0, cb; cb = callbacksToBeCalled[i]; i++) {
- cb.callback.call(cb.elem);
- }
- },
- // traverse through all descendants of a node to check if event should be fired for any descendant
- checkChildNodesRecursively: function(nodes, registrationData, matchFunc, callbacksToBeCalled) {
- // check each new node if it matches the selector
- for (var i=0, node; node = nodes[i]; i++) {
- if (matchFunc(node, registrationData, callbacksToBeCalled)) {
- callbacksToBeCalled.push({ callback: registrationData.callback, elem: node });
- }
- if (node.childNodes.length > 0) {
- utils.checkChildNodesRecursively(node.childNodes, registrationData, matchFunc, callbacksToBeCalled);
- }
- }
- },
- mergeArrays: function(firstArr, secondArr){
- // Overwrites default options with user-defined options.
- var options = {},
- attrName;
- for (attrName in firstArr) {
- options[attrName] = firstArr[attrName];
- }
- for (attrName in secondArr) {
- options[attrName] = secondArr[attrName];
- }
- return options;
- },
- toElementsArray: function (elements) {
- // check if object is an array (or array like object)
- // Note: window object has .length property but it's not array of elements so don't consider it an array
- if (typeof elements !== "undefined" && (typeof elements.length !== "number" || elements === window)) {
- elements = [elements];
- }
- return elements;
- }
- };
- })();
- // Class to maintain state of all registered events of a single type
- var EventsBucket = (function() {
- var EventsBucket = function() {
- // holds all the events
- this._eventsBucket = [];
- // function to be called while adding an event, the function should do the event initialization/registration
- this._beforeAdding = null;
- // function to be called while removing an event, the function should do the event destruction
- this._beforeRemoving = null;
- };
- EventsBucket.prototype.addEvent = function(target, selector, options, callback) {
- var newEvent = {
- target: target,
- selector: selector,
- options: options,
- callback: callback,
- firedElems: []
- };
- if (this._beforeAdding) {
- this._beforeAdding(newEvent);
- }
- this._eventsBucket.push(newEvent);
- return newEvent;
- };
- EventsBucket.prototype.removeEvent = function(compareFunction) {
- for (var i=this._eventsBucket.length - 1, registeredEvent; registeredEvent = this._eventsBucket[i]; i--) {
- if (compareFunction(registeredEvent)) {
- if (this._beforeRemoving) {
- this._beforeRemoving(registeredEvent);
- }
- this._eventsBucket.splice(i, 1);
- }
- }
- };
- EventsBucket.prototype.beforeAdding = function(beforeAdding) {
- this._beforeAdding = beforeAdding;
- };
- EventsBucket.prototype.beforeRemoving = function(beforeRemoving) {
- this._beforeRemoving = beforeRemoving;
- };
- return EventsBucket;
- })();
- /**
- * @constructor
- * General class for binding/unbinding arrive and leave events
- */
- var MutationEvents = function(getObserverConfig, onMutation) {
- var eventsBucket = new EventsBucket(),
- me = this;
- var defaultOptions = {
- fireOnAttributesModification: false
- };
- // actual event registration before adding it to bucket
- eventsBucket.beforeAdding(function(registrationData) {
- var
- target = registrationData.target,
- selector = registrationData.selector,
- callback = registrationData.callback,
- observer;
- // mutation observer does not work on window or document
- if (target === window.document || target === window)
- target = document.getElementsByTagName("html")[0];
- // Create an observer instance
- observer = new MutationObserver(function(e) {
- onMutation.call(this, e, registrationData);
- });
- var config = getObserverConfig(registrationData.options);
- observer.observe(target, config);
- registrationData.observer = observer;
- registrationData.me = me;
- });
- // cleanup/unregister before removing an event
- eventsBucket.beforeRemoving(function (eventData) {
- eventData.observer.disconnect();
- });
- this.bindEvent = function(selector, options, callback) {
- options = utils.mergeArrays(defaultOptions, options);
- var elements = utils.toElementsArray(this);
- for (var i = 0; i < elements.length; i++) {
- eventsBucket.addEvent(elements[i], selector, options, callback);
- }
- };
- this.unbindEvent = function() {
- var elements = utils.toElementsArray(this);
- eventsBucket.removeEvent(function(eventObj) {
- for (var i = 0; i < elements.length; i++) {
- if (this === undefined || eventObj.target === elements[i]) {
- return true;
- }
- }
- return false;
- });
- };
- this.unbindEventWithSelectorOrCallback = function(selector) {
- var elements = utils.toElementsArray(this),
- callback = selector,
- compareFunction;
- if (typeof selector === "function") {
- compareFunction = function(eventObj) {
- for (var i = 0; i < elements.length; i++) {
- if ((this === undefined || eventObj.target === elements[i]) && eventObj.callback === callback) {
- return true;
- }
- }
- return false;
- };
- }
- else {
- compareFunction = function(eventObj) {
- for (var i = 0; i < elements.length; i++) {
- if ((this === undefined || eventObj.target === elements[i]) && eventObj.selector === selector) {
- return true;
- }
- }
- return false;
- };
- }
- eventsBucket.removeEvent(compareFunction);
- };
- this.unbindEventWithSelectorAndCallback = function(selector, callback) {
- var elements = utils.toElementsArray(this);
- eventsBucket.removeEvent(function(eventObj) {
- for (var i = 0; i < elements.length; i++) {
- if ((this === undefined || eventObj.target === elements[i]) && eventObj.selector === selector && eventObj.callback === callback) {
- return true;
- }
- }
- return false;
- });
- };
- return this;
- };
- /**
- * @constructor
- * Processes 'arrive' events
- */
- var ArriveEvents = function() {
- var mutationEvents,
- me = this;
- // Default options for 'arrive' event
- var arriveDefaultOptions = {
- fireOnAttributesModification: false,
- onceOnly: false,
- existing: false
- };
- function getArriveObserverConfig(options) {
- var config = {
- attributes: false,
- childList: true,
- subtree: true
- };
- if (options.fireOnAttributesModification) {
- config.attributes = true;
- }
- return config;
- }
- function onArriveMutation(mutations, registrationData) {
- mutations.forEach(function( mutation ) {
- var newNodes = mutation.addedNodes,
- targetNode = mutation.target,
- callbacksToBeCalled = [];
- // If new nodes are added
- if( newNodes !== null && newNodes.length > 0 ) {
- utils.checkChildNodesRecursively(newNodes, registrationData, nodeMatchFunc, callbacksToBeCalled);
- }
- else if (mutation.type === "attributes") {
- if (nodeMatchFunc(targetNode, registrationData, callbacksToBeCalled)) {
- callbacksToBeCalled.push({ callback: registrationData.callback, elem: node });
- }
- }
- utils.callCallbacks(callbacksToBeCalled);
- });
- }
- function nodeMatchFunc(node, registrationData, callbacksToBeCalled) {
- // check a single node to see if it matches the selector
- if (utils.matchesSelector(node, registrationData.selector)) {
- if(node._id === undefined) {
- node._id = arriveUniqueId++;
- }
- // make sure the arrive event is not already fired for the element
- if (registrationData.firedElems.indexOf(node._id) == -1) {
- if (registrationData.options.onceOnly) {
- if (registrationData.firedElems.length === 0) {
- // On first callback, unbind event.
- registrationData.me.unbindEventWithSelectorAndCallback.call(
- registrationData.target, registrationData.selector, registrationData.callback);
- } else {
- // Ignore multiple mutations which may have been queued before the event was unbound.
- return;
- }
- }
- registrationData.firedElems.push(node._id);
- callbacksToBeCalled.push({ callback: registrationData.callback, elem: node });
- }
- }
- }
- arriveEvents = new MutationEvents(getArriveObserverConfig, onArriveMutation);
- var mutationBindEvent = arriveEvents.bindEvent;
- // override bindEvent function
- arriveEvents.bindEvent = function(selector, options, callback) {
- if (typeof callback === "undefined") {
- callback = options;
- options = arriveDefaultOptions;
- } else {
- options = utils.mergeArrays(arriveDefaultOptions, options);
- }
- var elements = utils.toElementsArray(this);
- if (options.existing) {
- var existing = [];
- for (var i = 0; i < elements.length; i++) {
- var nodes = elements[i].querySelectorAll(selector);
- for (var j = 0; j < nodes.length; j++) {
- existing.push({ callback: callback, elem: nodes[j] });
- }
- }
- // no need to bind event if the callback has to be fired only once and we have already found the element
- if (options.onceOnly && existing.length) {
- return callback.call(existing[0].elem);
- }
- setTimeout(utils.callCallbacks, 1, existing);
- }
- mutationBindEvent.call(this, selector, options, callback);
- };
- return arriveEvents;
- };
- /**
- * @constructor
- * Processes 'leave' events
- */
- var LeaveEvents = function() {
- var mutationEvents,
- me = this;
- // Default options for 'leave' event
- var leaveDefaultOptions = {};
- function getLeaveObserverConfig(options) {
- var config = {
- childList: true,
- subtree: true
- };
- return config;
- }
- function onLeaveMutation(mutations, registrationData) {
- mutations.forEach(function( mutation ) {
- var removedNodes = mutation.removedNodes,
- targetNode = mutation.target,
- callbacksToBeCalled = [];
- if( removedNodes !== null && removedNodes.length > 0 ) {
- utils.checkChildNodesRecursively(removedNodes, registrationData, nodeMatchFunc, callbacksToBeCalled);
- }
- utils.callCallbacks(callbacksToBeCalled);
- });
- }
- function nodeMatchFunc(node, registrationData) {
- return utils.matchesSelector(node, registrationData.selector);
- }
- leaveEvents = new MutationEvents(getLeaveObserverConfig, onLeaveMutation);
- var mutationBindEvent = leaveEvents.bindEvent;
- // override bindEvent function
- leaveEvents.bindEvent = function(selector, options, callback) {
- if (typeof callback === "undefined") {
- callback = options;
- options = leaveDefaultOptions;
- } else {
- options = utils.mergeArrays(leaveDefaultOptions, options);
- }
- mutationBindEvent.call(this, selector, options, callback);
- };
- return leaveEvents;
- };
- var arriveEvents = new ArriveEvents(),
- leaveEvents = new LeaveEvents();
- function exposeUnbindApi(eventObj, exposeTo, funcName) {
- // expose unbind function with function overriding
- utils.addMethod(exposeTo, funcName, eventObj.unbindEvent);
- utils.addMethod(exposeTo, funcName, eventObj.unbindEventWithSelectorOrCallback);
- utils.addMethod(exposeTo, funcName, eventObj.unbindEventWithSelectorAndCallback);
- }
- /*** expose APIs ***/
- function exposeApi(exposeTo) {
- exposeTo.arrive = arriveEvents.bindEvent;
- exposeUnbindApi(arriveEvents, exposeTo, "unbindArrive");
- exposeTo.leave = leaveEvents.bindEvent;
- exposeUnbindApi(leaveEvents, exposeTo, "unbindLeave");
- }
- if ($) {
- exposeApi($.fn);
- }
- exposeApi(HTMLElement.prototype);
- exposeApi(NodeList.prototype);
- exposeApi(HTMLCollection.prototype);
- exposeApi(HTMLDocument.prototype);
- exposeApi(Window.prototype);
- var Arrive = {};
- // expose functions to unbind all arrive/leave events
- exposeUnbindApi(arriveEvents, Arrive, "unbindAllArrive");
- exposeUnbindApi(leaveEvents, Arrive, "unbindAllLeave");
- return Arrive;
- })(window, typeof jQuery === 'undefined' ? null : jQuery, undefined);
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址