UNPKG

@tower1229/flow-ui

Version:

Highly customizable UI framework based Seajs/jQuery

466 lines (456 loc) 12.5 kB
/* * name: img-loaded.js * version: v0.0.1 * update: build * date: 2015-09-28 */ (function() { function EventEmitter() {} var proto = EventEmitter.prototype; var exports = this; var originalGlobalValue = exports.EventEmitter; function indexOfListener(listeners, listener) { var i = listeners.length; while (i--) { if (listeners[i].listener === listener) { return i } } return -1 } function alias(name) { return function aliasClosure() { return this[name].apply(this, arguments) } } proto.getListeners = function getListeners(evt) { var events = this._getEvents(); var response; var key; if (typeof evt === 'object') { response = {}; for (key in events) { if (events.hasOwnProperty(key) && evt.test(key)) { response[key] = events[key] } } } else { response = events[evt] || (events[evt] = []) } return response }; proto.flattenListeners = function flattenListeners(listeners) { var flatListeners = []; var i; for (i = 0; i < listeners.length; i += 1) { flatListeners.push(listeners[i].listener) } return flatListeners }; proto.getListenersAsObject = function getListenersAsObject(evt) { var listeners = this.getListeners(evt); var response; if (listeners instanceof Array) { response = {}; response[evt] = listeners } return response || listeners }; proto.addListener = function addListener(evt, listener) { var listeners = this.getListenersAsObject(evt); var listenerIsWrapped = typeof listener === 'object'; var key; for (key in listeners) { if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) { listeners[key].push(listenerIsWrapped ? listener : { listener: listener, once: false }) } } return this }; proto.on = alias('addListener'); proto.addOnceListener = function addOnceListener(evt, listener) { return this.addListener(evt, { listener: listener, once: true }) }; proto.once = alias('addOnceListener'); proto.defineEvent = function defineEvent(evt) { this.getListeners(evt); return this }; proto.defineEvents = function defineEvents(evts) { for (var i = 0; i < evts.length; i += 1) { this.defineEvent(evts[i]) } return this }; proto.removeListener = function removeListener(evt, listener) { var listeners = this.getListenersAsObject(evt); var index; var key; for (key in listeners) { if (listeners.hasOwnProperty(key)) { index = indexOfListener(listeners[key], listener); if (index !== -1) { listeners[key].splice(index, 1) } } } return this }; proto.off = alias('removeListener'); proto.addListeners = function addListeners(evt, listeners) { return this.manipulateListeners(false, evt, listeners) }; proto.removeListeners = function removeListeners(evt, listeners) { return this.manipulateListeners(true, evt, listeners) }; proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) { var i; var value; var single = remove ? this.removeListener : this.addListener; var multiple = remove ? this.removeListeners : this.addListeners; if (typeof evt === 'object' && !(evt instanceof RegExp)) { for (i in evt) { if (evt.hasOwnProperty(i) && (value = evt[i])) { if (typeof value === 'function') { single.call(this, i, value) } else { multiple.call(this, i, value) } } } } else { i = listeners.length; while (i--) { single.call(this, evt, listeners[i]) } } return this }; proto.removeEvent = function removeEvent(evt) { var type = typeof evt; var events = this._getEvents(); var key; if (type === 'string') { delete events[evt] } else if (type === 'object') { for (key in events) { if (events.hasOwnProperty(key) && evt.test(key)) { delete events[key] } } } else { delete this._events } return this }; proto.removeAllListeners = alias('removeEvent'); proto.emitEvent = function emitEvent(evt, args) { var listeners = this.getListenersAsObject(evt); var listener; var i; var key; var response; for (key in listeners) { if (listeners.hasOwnProperty(key)) { i = listeners[key].length; while (i--) { listener = listeners[key][i]; if (listener.once === true) { this.removeListener(evt, listener.listener) } response = listener.listener.apply(this, args || []); if (response === this._getOnceReturnValue()) { this.removeListener(evt, listener.listener) } } } } return this }; proto.trigger = alias('emitEvent'); proto.emit = function emit(evt) { var args = Array.prototype.slice.call(arguments, 1); return this.emitEvent(evt, args) }; proto.setOnceReturnValue = function setOnceReturnValue(value) { this._onceReturnValue = value; return this }; proto._getOnceReturnValue = function _getOnceReturnValue() { if (this.hasOwnProperty('_onceReturnValue')) { return this._onceReturnValue } else { return true } }; proto._getEvents = function _getEvents() { return this._events || (this._events = {}) }; EventEmitter.noConflict = function noConflict() { exports.EventEmitter = originalGlobalValue; return EventEmitter }; if (typeof define === 'function' && define.amd) { define('eventEmitter/EventEmitter', [], function() { return EventEmitter }) } else if (typeof module === 'object' && module.exports) { module.exports = EventEmitter } else { this.EventEmitter = EventEmitter } }.call(this)); (function(window) { var docElem = document.documentElement; var bind = function() {}; function getIEEvent(obj) { var event = window.event; event.target = event.target || event.srcElement || obj; return event } if (docElem.addEventListener) { bind = function(obj, type, fn) { obj.addEventListener(type, fn, false) } } else if (docElem.attachEvent) { bind = function(obj, type, fn) { obj[type + fn] = fn.handleEvent ? function() { var event = getIEEvent(obj); fn.handleEvent.call(fn, event) } : function() { var event = getIEEvent(obj); fn.call(obj, event) }; obj.attachEvent("on" + type, obj[type + fn]) } } var unbind = function() {}; if (docElem.removeEventListener) { unbind = function(obj, type, fn) { obj.removeEventListener(type, fn, false) } } else if (docElem.detachEvent) { unbind = function(obj, type, fn) { obj.detachEvent("on" + type, obj[type + fn]); try { delete obj[type + fn] } catch (err) { obj[type + fn] = undefined } } } var eventie = { bind: bind, unbind: unbind }; if (typeof define === 'function' && define.amd) { define('eventie/eventie', eventie) } else { window.eventie = eventie } })(this); define('img-loaded', function(require, exports, module) { var $ = window.$ || require('jquery'); var console = window.console; var hasConsole = typeof console !== 'undefined'; function extend(a, b) { for (var prop in b) { a[prop] = b[prop] } return a } var objToString = Object.prototype.toString; function isArray(obj) { return objToString.call(obj) === '[object Array]' } function makeArray(obj) { var ary = []; if (isArray(obj)) { ary = obj } else if (typeof obj.length === 'number') { for (var i = 0, len = obj.length; i < len; i++) { ary.push(obj[i]) } } else { ary.push(obj) } return ary } function ImagesLoaded(elem, options, onAlways) { if (!(this instanceof ImagesLoaded)) { return new ImagesLoaded(elem, options) } if (typeof elem === 'string') { elem = $(elem) } this.elements = makeArray(elem); this.options = extend({}, this.options); if (typeof options === 'function') { onAlways = options } else { extend(this.options, options) } if (onAlways) { this.on('always', onAlways) } this.getImages(); if ($) { this.jqDeferred = new $.Deferred() } var _this = this; setTimeout(function() { _this.check() }) } ImagesLoaded.prototype = new EventEmitter(); ImagesLoaded.prototype.options = {}; ImagesLoaded.prototype.getImages = function() { this.images = []; for (var i = 0, len = this.elements.length; i < len; i++) { var elem = this.elements[i]; if (elem.nodeName === 'IMG') { this.addImage(elem) } var nodeType = elem.nodeType; if (!nodeType || !(nodeType === 1 || nodeType === 9 || nodeType === 11)) { continue } var childElems = $(elem).find('img'); for (var j = 0, jLen = childElems.length; j < jLen; j++) { var img = childElems[j]; this.addImage(img) } } }; ImagesLoaded.prototype.addImage = function(img) { var loadingImage = new LoadingImage(img); this.images.push(loadingImage) }; ImagesLoaded.prototype.check = function() { var _this = this; var checkedCount = 0; var length = this.images.length; this.hasAnyBroken = false; if (!length) { this.complete(); return } function onConfirm(image, message) { if (_this.options.debug && hasConsole) { console.log('confirm', image, message) } _this.progress(image); checkedCount++; if (checkedCount === length) { _this.complete() } return true } for (var i = 0; i < length; i++) { var loadingImage = this.images[i]; loadingImage.on('confirm', onConfirm); loadingImage.check() } }; ImagesLoaded.prototype.progress = function(image) { this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded; var _this = this; setTimeout(function() { _this.emit('progress', _this, image); if (_this.jqDeferred && _this.jqDeferred.notify) { _this.jqDeferred.notify(_this, image) } }) }; ImagesLoaded.prototype.complete = function() { var eventName = this.hasAnyBroken ? 'fail' : 'done'; this.isComplete = true; var _this = this; setTimeout(function() { _this.emit(eventName, _this); _this.emit('always', _this); if (_this.jqDeferred) { var jqMethod = _this.hasAnyBroken ? 'reject' : 'resolve'; _this.jqDeferred[jqMethod](_this) } }) }; if ($) { $.fn.imagesLoaded = function(options, callback) { var instance = new ImagesLoaded(this, options, callback); return instance.jqDeferred.promise($(this)) } } function LoadingImage(img) { this.img = img } LoadingImage.prototype = new EventEmitter(); LoadingImage.prototype.check = function() { var resource = cache[this.img.src] || new Resource(this.img.src); if (resource.isConfirmed) { this.confirm(resource.isLoaded, 'cached was confirmed'); return } if (this.img.complete && this.img.naturalWidth !== undefined) { this.confirm(this.img.naturalWidth !== 0, 'naturalWidth'); return } var _this = this; resource.on('confirm', function(resrc, message) { _this.confirm(resrc.isLoaded, message); return true }); resource.check() }; LoadingImage.prototype.confirm = function(isLoaded, message) { this.isLoaded = isLoaded; this.emit('confirm', this, message) }; var cache = {}; function Resource(src) { this.src = src; cache[src] = this } Resource.prototype = new EventEmitter(); Resource.prototype.check = function() { if (this.isChecked) { return } var proxyImage = new Image(); eventie.bind(proxyImage, 'load', this); eventie.bind(proxyImage, 'error', this); proxyImage.src = this.src; this.isChecked = true }; Resource.prototype.handleEvent = function(event) { var method = 'on' + event.type; if (this[method]) { this[method](event) } }; Resource.prototype.onload = function(event) { this.confirm(true, 'onload'); this.unbindProxyEvents(event) }; Resource.prototype.onerror = function(event) { this.confirm(false, 'onerror'); this.unbindProxyEvents(event) }; Resource.prototype.confirm = function(isLoaded, message) { this.isConfirmed = true; this.isLoaded = isLoaded; this.emit('confirm', this, message) }; Resource.prototype.unbindProxyEvents = function(event) { eventie.unbind(event.target, 'load', this); eventie.unbind(event.target, 'error', this) }; return ImagesLoaded });