From 62905e30f7dc21603cec859cd4009351a2a94337 Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Sat, 7 Mar 2015 02:38:37 +0100 Subject: [PATCH] Trigger event on dom object when activated --- dist/wow.js | 213 +++++++++++++++++------------ dist/wow.min.js | 4 +- spec/coffeescripts/wow-spec.coffee | 24 ++++ spec/javascripts/wow-spec.js | 18 ++- src/wow.coffee | 22 +++ 5 files changed, 189 insertions(+), 92 deletions(-) diff --git a/dist/wow.js b/dist/wow.js index a309205..17231cf 100644 --- a/dist/wow.js +++ b/dist/wow.js @@ -1,7 +1,7 @@ (function() { var MutationObserver, Util, WeakMap, getComputedStyle, getComputedStyleRX, - __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; + bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; Util = (function() { function Util() {} @@ -21,6 +21,39 @@ return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(agent); }; + Util.prototype.createEvent = function(event, bubble, cancel, detail) { + var customEvent; + if (bubble == null) { + bubble = false; + } + if (cancel == null) { + cancel = false; + } + if (detail == null) { + detail = null; + } + if (document.createEvent != null) { + customEvent = document.createEvent('CustomEvent'); + customEvent.initCustomEvent(event, bubble, cancel, detail); + } else if (document.createEventObject != null) { + customEvent = document.createEventObject(); + customEvent.eventType = event; + } else { + customEvent.eventName = event; + } + return customEvent; + }; + + Util.prototype.emitEvent = function(elem, event) { + if (elem.dispatchEvent != null) { + return elem.dispatchEvent(event); + } else if (elem[event] != null) { + return elem[event](); + } else if (elem['on' + event] != null) { + return elem['on' + event](); + } + }; + Util.prototype.addEvent = function(elem, event, fn) { if (elem.addEventListener != null) { return elem.addEventListener(event, fn, false); @@ -60,10 +93,10 @@ } WeakMap.prototype.get = function(key) { - var i, item, _i, _len, _ref; - _ref = this.keys; - for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) { - item = _ref[i]; + var i, item, j, len, ref; + ref = this.keys; + for (i = j = 0, len = ref.length; j < len; i = ++j) { + item = ref[i]; if (item === key) { return this.values[i]; } @@ -71,10 +104,10 @@ }; WeakMap.prototype.set = function(key, value) { - var i, item, _i, _len, _ref; - _ref = this.keys; - for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) { - item = _ref[i]; + var i, item, j, len, ref; + ref = this.keys; + for (i = j = 0, len = ref.length; j < len; i = ++j) { + item = ref[i]; if (item === key) { this.values[i] = value; return; @@ -108,7 +141,7 @@ getComputedStyle = this.getComputedStyle || function(el, pseudo) { this.getPropertyValue = function(prop) { - var _ref; + var ref; if (prop === 'float') { prop = 'styleFloat'; } @@ -117,7 +150,7 @@ return _char.toUpperCase(); }); } - return ((_ref = el.currentStyle) != null ? _ref[prop] : void 0) || null; + return ((ref = el.currentStyle) != null ? ref[prop] : void 0) || null; }; return this; }; @@ -138,18 +171,19 @@ if (options == null) { options = {}; } - this.scrollCallback = __bind(this.scrollCallback, this); - this.scrollHandler = __bind(this.scrollHandler, this); - this.start = __bind(this.start, this); + this.scrollCallback = bind(this.scrollCallback, this); + this.scrollHandler = bind(this.scrollHandler, this); + this.start = bind(this.start, this); this.scrolled = true; this.config = this.util().extend(options, this.defaults); this.animationNameCache = new WeakMap(); + this.wowEvent = this.util().createEvent(this.config.boxClass); } WOW.prototype.init = function() { - var _ref; + var ref; this.element = window.document.documentElement; - if ((_ref = document.readyState) === "interactive" || _ref === "complete") { + if ((ref = document.readyState) === "interactive" || ref === "complete") { this.start(); } else { this.util().addEvent(document, 'DOMContentLoaded', this.start); @@ -158,35 +192,35 @@ }; WOW.prototype.start = function() { - var box, _i, _len, _ref; + var box, j, len, ref; this.stopped = false; this.boxes = (function() { - var _i, _len, _ref, _results; - _ref = this.element.querySelectorAll("." + this.config.boxClass); - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - box = _ref[_i]; - _results.push(box); + var j, len, ref, results; + ref = this.element.querySelectorAll("." + this.config.boxClass); + results = []; + for (j = 0, len = ref.length; j < len; j++) { + box = ref[j]; + results.push(box); } - return _results; + return results; }).call(this); this.all = (function() { - var _i, _len, _ref, _results; - _ref = this.boxes; - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - box = _ref[_i]; - _results.push(box); + var j, len, ref, results; + ref = this.boxes; + results = []; + for (j = 0, len = ref.length; j < len; j++) { + box = ref[j]; + results.push(box); } - return _results; + return results; }).call(this); if (this.boxes.length) { if (this.disabled()) { this.resetStyle(); } else { - _ref = this.boxes; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - box = _ref[_i]; + ref = this.boxes; + for (j = 0, len = ref.length; j < len; j++) { + box = ref[j]; this.applyStyle(box, true); } } @@ -199,22 +233,22 @@ if (this.config.live) { return new MutationObserver((function(_this) { return function(records) { - var node, record, _j, _len1, _results; - _results = []; - for (_j = 0, _len1 = records.length; _j < _len1; _j++) { - record = records[_j]; - _results.push((function() { - var _k, _len2, _ref1, _results1; - _ref1 = record.addedNodes || []; - _results1 = []; - for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { - node = _ref1[_k]; - _results1.push(this.doSync(node)); + var k, len1, node, record, results; + results = []; + for (k = 0, len1 = records.length; k < len1; k++) { + record = records[k]; + results.push((function() { + var l, len2, ref1, results1; + ref1 = record.addedNodes || []; + results1 = []; + for (l = 0, len2 = ref1.length; l < len2; l++) { + node = ref1[l]; + results1.push(this.doSync(node)); } - return _results1; + return results1; }).call(_this)); } - return _results; + return results; }; })(this)).observe(document.body, { childList: true, @@ -239,7 +273,7 @@ }; WOW.prototype.doSync = function(element) { - var box, _i, _len, _ref, _results; + var box, j, len, ref, results; if (element == null) { element = this.element; } @@ -247,11 +281,11 @@ return; } element = element.parentNode || element; - _ref = element.querySelectorAll("." + this.config.boxClass); - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - box = _ref[_i]; - if (__indexOf.call(this.all, box) < 0) { + ref = element.querySelectorAll("." + this.config.boxClass); + results = []; + for (j = 0, len = ref.length; j < len; j++) { + box = ref[j]; + if (indexOf.call(this.all, box) < 0) { this.boxes.push(box); this.all.push(box); if (this.stopped || this.disabled()) { @@ -259,20 +293,21 @@ } else { this.applyStyle(box, true); } - _results.push(this.scrolled = true); + results.push(this.scrolled = true); } else { - _results.push(void 0); + results.push(void 0); } } - return _results; + return results; }; WOW.prototype.show = function(box) { this.applyStyle(box); - box.className = "" + box.className + " " + this.config.animateClass; + box.className = box.className + " " + this.config.animateClass; if (this.config.callback != null) { - return this.config.callback(box); + this.config.callback(box); } + return this.util().emitEvent(box, this.wowEvent); }; WOW.prototype.applyStyle = function(box, hidden) { @@ -300,14 +335,14 @@ })(); WOW.prototype.resetStyle = function() { - var box, _i, _len, _ref, _results; - _ref = this.boxes; - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - box = _ref[_i]; - _results.push(box.style.visibility = 'visible'); - } - return _results; + var box, j, len, ref, results; + ref = this.boxes; + results = []; + for (j = 0, len = ref.length; j < len; j++) { + box = ref[j]; + results.push(box.style.visibility = 'visible'); + } + return results; }; WOW.prototype.customStyle = function(box, hidden, duration, delay, iteration) { @@ -339,32 +374,32 @@ WOW.prototype.vendors = ["moz", "webkit"]; WOW.prototype.vendorSet = function(elem, properties) { - var name, value, vendor, _results; - _results = []; + var name, results, value, vendor; + results = []; for (name in properties) { value = properties[name]; elem["" + name] = value; - _results.push((function() { - var _i, _len, _ref, _results1; - _ref = this.vendors; - _results1 = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - vendor = _ref[_i]; - _results1.push(elem["" + vendor + (name.charAt(0).toUpperCase()) + (name.substr(1))] = value); + results.push((function() { + var j, len, ref, results1; + ref = this.vendors; + results1 = []; + for (j = 0, len = ref.length; j < len; j++) { + vendor = ref[j]; + results1.push(elem["" + vendor + (name.charAt(0).toUpperCase()) + (name.substr(1))] = value); } - return _results1; + return results1; }).call(this)); } - return _results; + return results; }; WOW.prototype.vendorCSS = function(elem, property) { - var result, style, vendor, _i, _len, _ref; + var j, len, ref, result, style, vendor; style = getComputedStyle(elem); result = style.getPropertyCSSValue(property); - _ref = this.vendors; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - vendor = _ref[_i]; + ref = this.vendors; + for (j = 0, len = ref.length; j < len; j++) { + vendor = ref[j]; result = result || style.getPropertyCSSValue("-" + vendor + "-" + property); } return result; @@ -401,11 +436,11 @@ if (this.scrolled) { this.scrolled = false; this.boxes = (function() { - var _i, _len, _ref, _results; - _ref = this.boxes; - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - box = _ref[_i]; + var j, len, ref, results; + ref = this.boxes; + results = []; + for (j = 0, len = ref.length; j < len; j++) { + box = ref[j]; if (!(box)) { continue; } @@ -413,9 +448,9 @@ this.show(box); continue; } - _results.push(box); + results.push(box); } - return _results; + return results; }).call(this); if (!(this.boxes.length || this.config.live)) { return this.stop(); diff --git a/dist/wow.min.js b/dist/wow.min.js index 81cfa93..8527210 100644 --- a/dist/wow.min.js +++ b/dist/wow.min.js @@ -1,2 +1,2 @@ -/*! WOW - v1.0.3 - 2015-01-14 -* Copyright (c) 2015 Matthieu Aussaguel; Licensed MIT */(function(){var a,b,c,d,e,f=function(a,b){return function(){return a.apply(b,arguments)}},g=[].indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(b in this&&this[b]===a)return b;return-1};b=function(){function a(){}return a.prototype.extend=function(a,b){var c,d;for(c in b)d=b[c],null==a[c]&&(a[c]=d);return a},a.prototype.isMobile=function(a){return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(a)},a.prototype.addEvent=function(a,b,c){return null!=a.addEventListener?a.addEventListener(b,c,!1):null!=a.attachEvent?a.attachEvent("on"+b,c):a[b]=c},a.prototype.removeEvent=function(a,b,c){return null!=a.removeEventListener?a.removeEventListener(b,c,!1):null!=a.detachEvent?a.detachEvent("on"+b,c):delete a[b]},a.prototype.innerHeight=function(){return"innerHeight"in window?window.innerHeight:document.documentElement.clientHeight},a}(),c=this.WeakMap||this.MozWeakMap||(c=function(){function a(){this.keys=[],this.values=[]}return a.prototype.get=function(a){var b,c,d,e,f;for(f=this.keys,b=d=0,e=f.length;e>d;b=++d)if(c=f[b],c===a)return this.values[b]},a.prototype.set=function(a,b){var c,d,e,f,g;for(g=this.keys,c=e=0,f=g.length;f>e;c=++e)if(d=g[c],d===a)return void(this.values[c]=b);return this.keys.push(a),this.values.push(b)},a}()),a=this.MutationObserver||this.WebkitMutationObserver||this.MozMutationObserver||(a=function(){function a(){"undefined"!=typeof console&&null!==console&&console.warn("MutationObserver is not supported by your browser."),"undefined"!=typeof console&&null!==console&&console.warn("WOW.js cannot detect dom mutations, please call .sync() after loading new content.")}return a.notSupported=!0,a.prototype.observe=function(){},a}()),d=this.getComputedStyle||function(a){return this.getPropertyValue=function(b){var c;return"float"===b&&(b="styleFloat"),e.test(b)&&b.replace(e,function(a,b){return b.toUpperCase()}),(null!=(c=a.currentStyle)?c[b]:void 0)||null},this},e=/(\-([a-z]){1})/g,this.WOW=function(){function e(a){null==a&&(a={}),this.scrollCallback=f(this.scrollCallback,this),this.scrollHandler=f(this.scrollHandler,this),this.start=f(this.start,this),this.scrolled=!0,this.config=this.util().extend(a,this.defaults),this.animationNameCache=new c}return e.prototype.defaults={boxClass:"wow",animateClass:"animated",offset:0,mobile:!0,live:!0,callback:null},e.prototype.init=function(){var a;return this.element=window.document.documentElement,"interactive"===(a=document.readyState)||"complete"===a?this.start():this.util().addEvent(document,"DOMContentLoaded",this.start),this.finished=[]},e.prototype.start=function(){var b,c,d,e;if(this.stopped=!1,this.boxes=function(){var a,c,d,e;for(d=this.element.querySelectorAll("."+this.config.boxClass),e=[],a=0,c=d.length;c>a;a++)b=d[a],e.push(b);return e}.call(this),this.all=function(){var a,c,d,e;for(d=this.boxes,e=[],a=0,c=d.length;c>a;a++)b=d[a],e.push(b);return e}.call(this),this.boxes.length)if(this.disabled())this.resetStyle();else for(e=this.boxes,c=0,d=e.length;d>c;c++)b=e[c],this.applyStyle(b,!0);return this.disabled()||(this.util().addEvent(window,"scroll",this.scrollHandler),this.util().addEvent(window,"resize",this.scrollHandler),this.interval=setInterval(this.scrollCallback,50)),this.config.live?new a(function(a){return function(b){var c,d,e,f,g;for(g=[],e=0,f=b.length;f>e;e++)d=b[e],g.push(function(){var a,b,e,f;for(e=d.addedNodes||[],f=[],a=0,b=e.length;b>a;a++)c=e[a],f.push(this.doSync(c));return f}.call(a));return g}}(this)).observe(document.body,{childList:!0,subtree:!0}):void 0},e.prototype.stop=function(){return this.stopped=!0,this.util().removeEvent(window,"scroll",this.scrollHandler),this.util().removeEvent(window,"resize",this.scrollHandler),null!=this.interval?clearInterval(this.interval):void 0},e.prototype.sync=function(){return a.notSupported?this.doSync(this.element):void 0},e.prototype.doSync=function(a){var b,c,d,e,f;if(null==a&&(a=this.element),1===a.nodeType){for(a=a.parentNode||a,e=a.querySelectorAll("."+this.config.boxClass),f=[],c=0,d=e.length;d>c;c++)b=e[c],g.call(this.all,b)<0?(this.boxes.push(b),this.all.push(b),this.stopped||this.disabled()?this.resetStyle():this.applyStyle(b,!0),f.push(this.scrolled=!0)):f.push(void 0);return f}},e.prototype.show=function(a){return this.applyStyle(a),a.className=""+a.className+" "+this.config.animateClass,null!=this.config.callback?this.config.callback(a):void 0},e.prototype.applyStyle=function(a,b){var c,d,e;return d=a.getAttribute("data-wow-duration"),c=a.getAttribute("data-wow-delay"),e=a.getAttribute("data-wow-iteration"),this.animate(function(f){return function(){return f.customStyle(a,b,d,c,e)}}(this))},e.prototype.animate=function(){return"requestAnimationFrame"in window?function(a){return window.requestAnimationFrame(a)}:function(a){return a()}}(),e.prototype.resetStyle=function(){var a,b,c,d,e;for(d=this.boxes,e=[],b=0,c=d.length;c>b;b++)a=d[b],e.push(a.style.visibility="visible");return e},e.prototype.customStyle=function(a,b,c,d,e){return b&&this.cacheAnimationName(a),a.style.visibility=b?"hidden":"visible",c&&this.vendorSet(a.style,{animationDuration:c}),d&&this.vendorSet(a.style,{animationDelay:d}),e&&this.vendorSet(a.style,{animationIterationCount:e}),this.vendorSet(a.style,{animationName:b?"none":this.cachedAnimationName(a)}),a},e.prototype.vendors=["moz","webkit"],e.prototype.vendorSet=function(a,b){var c,d,e,f;f=[];for(c in b)d=b[c],a[""+c]=d,f.push(function(){var b,f,g,h;for(g=this.vendors,h=[],b=0,f=g.length;f>b;b++)e=g[b],h.push(a[""+e+c.charAt(0).toUpperCase()+c.substr(1)]=d);return h}.call(this));return f},e.prototype.vendorCSS=function(a,b){var c,e,f,g,h,i;for(e=d(a),c=e.getPropertyCSSValue(b),i=this.vendors,g=0,h=i.length;h>g;g++)f=i[g],c=c||e.getPropertyCSSValue("-"+f+"-"+b);return c},e.prototype.animationName=function(a){var b;try{b=this.vendorCSS(a,"animation-name").cssText}catch(c){b=d(a).getPropertyValue("animation-name")}return"none"===b?"":b},e.prototype.cacheAnimationName=function(a){return this.animationNameCache.set(a,this.animationName(a))},e.prototype.cachedAnimationName=function(a){return this.animationNameCache.get(a)},e.prototype.scrollHandler=function(){return this.scrolled=!0},e.prototype.scrollCallback=function(){var a;return!this.scrolled||(this.scrolled=!1,this.boxes=function(){var b,c,d,e;for(d=this.boxes,e=[],b=0,c=d.length;c>b;b++)a=d[b],a&&(this.isVisible(a)?this.show(a):e.push(a));return e}.call(this),this.boxes.length||this.config.live)?void 0:this.stop()},e.prototype.offsetTop=function(a){for(var b;void 0===a.offsetTop;)a=a.parentNode;for(b=a.offsetTop;a=a.offsetParent;)b+=a.offsetTop;return b},e.prototype.isVisible=function(a){var b,c,d,e,f;return c=a.getAttribute("data-wow-offset")||this.config.offset,f=window.pageYOffset,e=f+Math.min(this.element.clientHeight,this.util().innerHeight())-c,d=this.offsetTop(a),b=d+a.clientHeight,e>=d&&b>=f},e.prototype.util=function(){return null!=this._util?this._util:this._util=new b},e.prototype.disabled=function(){return!this.config.mobile&&this.util().isMobile(navigator.userAgent)},e}()}).call(this); \ No newline at end of file +/*! WOW - v1.0.3 - 2015-03-07 +* Copyright (c) 2015 Matthieu Aussaguel; Licensed MIT */(function(){var a,b,c,d,e,f=function(a,b){return function(){return a.apply(b,arguments)}},g=[].indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(b in this&&this[b]===a)return b;return-1};b=function(){function a(){}return a.prototype.extend=function(a,b){var c,d;for(c in b)d=b[c],null==a[c]&&(a[c]=d);return a},a.prototype.isMobile=function(a){return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(a)},a.prototype.createEvent=function(a,b,c,d){var e;return null==b&&(b=!1),null==c&&(c=!1),null==d&&(d=null),null!=document.createEvent?(e=document.createEvent("CustomEvent"),e.initCustomEvent(a,b,c,d)):null!=document.createEventObject?(e=document.createEventObject(),e.eventType=a):e.eventName=a,e},a.prototype.emitEvent=function(a,b){return null!=a.dispatchEvent?a.dispatchEvent(b):null!=a[b]?a[b]():null!=a["on"+b]?a["on"+b]():void 0},a.prototype.addEvent=function(a,b,c){return null!=a.addEventListener?a.addEventListener(b,c,!1):null!=a.attachEvent?a.attachEvent("on"+b,c):a[b]=c},a.prototype.removeEvent=function(a,b,c){return null!=a.removeEventListener?a.removeEventListener(b,c,!1):null!=a.detachEvent?a.detachEvent("on"+b,c):delete a[b]},a.prototype.innerHeight=function(){return"innerHeight"in window?window.innerHeight:document.documentElement.clientHeight},a}(),c=this.WeakMap||this.MozWeakMap||(c=function(){function a(){this.keys=[],this.values=[]}return a.prototype.get=function(a){var b,c,d,e,f;for(f=this.keys,b=d=0,e=f.length;e>d;b=++d)if(c=f[b],c===a)return this.values[b]},a.prototype.set=function(a,b){var c,d,e,f,g;for(g=this.keys,c=e=0,f=g.length;f>e;c=++e)if(d=g[c],d===a)return void(this.values[c]=b);return this.keys.push(a),this.values.push(b)},a}()),a=this.MutationObserver||this.WebkitMutationObserver||this.MozMutationObserver||(a=function(){function a(){"undefined"!=typeof console&&null!==console&&console.warn("MutationObserver is not supported by your browser."),"undefined"!=typeof console&&null!==console&&console.warn("WOW.js cannot detect dom mutations, please call .sync() after loading new content.")}return a.notSupported=!0,a.prototype.observe=function(){},a}()),d=this.getComputedStyle||function(a){return this.getPropertyValue=function(b){var c;return"float"===b&&(b="styleFloat"),e.test(b)&&b.replace(e,function(a,b){return b.toUpperCase()}),(null!=(c=a.currentStyle)?c[b]:void 0)||null},this},e=/(\-([a-z]){1})/g,this.WOW=function(){function e(a){null==a&&(a={}),this.scrollCallback=f(this.scrollCallback,this),this.scrollHandler=f(this.scrollHandler,this),this.start=f(this.start,this),this.scrolled=!0,this.config=this.util().extend(a,this.defaults),this.animationNameCache=new c,this.wowEvent=this.util().createEvent(this.config.boxClass)}return e.prototype.defaults={boxClass:"wow",animateClass:"animated",offset:0,mobile:!0,live:!0,callback:null},e.prototype.init=function(){var a;return this.element=window.document.documentElement,"interactive"===(a=document.readyState)||"complete"===a?this.start():this.util().addEvent(document,"DOMContentLoaded",this.start),this.finished=[]},e.prototype.start=function(){var b,c,d,e;if(this.stopped=!1,this.boxes=function(){var a,c,d,e;for(d=this.element.querySelectorAll("."+this.config.boxClass),e=[],a=0,c=d.length;c>a;a++)b=d[a],e.push(b);return e}.call(this),this.all=function(){var a,c,d,e;for(d=this.boxes,e=[],a=0,c=d.length;c>a;a++)b=d[a],e.push(b);return e}.call(this),this.boxes.length)if(this.disabled())this.resetStyle();else for(e=this.boxes,c=0,d=e.length;d>c;c++)b=e[c],this.applyStyle(b,!0);return this.disabled()||(this.util().addEvent(window,"scroll",this.scrollHandler),this.util().addEvent(window,"resize",this.scrollHandler),this.interval=setInterval(this.scrollCallback,50)),this.config.live?new a(function(a){return function(b){var c,d,e,f,g;for(g=[],c=0,d=b.length;d>c;c++)f=b[c],g.push(function(){var a,b,c,d;for(c=f.addedNodes||[],d=[],a=0,b=c.length;b>a;a++)e=c[a],d.push(this.doSync(e));return d}.call(a));return g}}(this)).observe(document.body,{childList:!0,subtree:!0}):void 0},e.prototype.stop=function(){return this.stopped=!0,this.util().removeEvent(window,"scroll",this.scrollHandler),this.util().removeEvent(window,"resize",this.scrollHandler),null!=this.interval?clearInterval(this.interval):void 0},e.prototype.sync=function(){return a.notSupported?this.doSync(this.element):void 0},e.prototype.doSync=function(a){var b,c,d,e,f;if(null==a&&(a=this.element),1===a.nodeType){for(a=a.parentNode||a,e=a.querySelectorAll("."+this.config.boxClass),f=[],c=0,d=e.length;d>c;c++)b=e[c],g.call(this.all,b)<0?(this.boxes.push(b),this.all.push(b),this.stopped||this.disabled()?this.resetStyle():this.applyStyle(b,!0),f.push(this.scrolled=!0)):f.push(void 0);return f}},e.prototype.show=function(a){return this.applyStyle(a),a.className=a.className+" "+this.config.animateClass,null!=this.config.callback&&this.config.callback(a),this.util().emitEvent(a,this.wowEvent)},e.prototype.applyStyle=function(a,b){var c,d,e;return d=a.getAttribute("data-wow-duration"),c=a.getAttribute("data-wow-delay"),e=a.getAttribute("data-wow-iteration"),this.animate(function(f){return function(){return f.customStyle(a,b,d,c,e)}}(this))},e.prototype.animate=function(){return"requestAnimationFrame"in window?function(a){return window.requestAnimationFrame(a)}:function(a){return a()}}(),e.prototype.resetStyle=function(){var a,b,c,d,e;for(d=this.boxes,e=[],b=0,c=d.length;c>b;b++)a=d[b],e.push(a.style.visibility="visible");return e},e.prototype.customStyle=function(a,b,c,d,e){return b&&this.cacheAnimationName(a),a.style.visibility=b?"hidden":"visible",c&&this.vendorSet(a.style,{animationDuration:c}),d&&this.vendorSet(a.style,{animationDelay:d}),e&&this.vendorSet(a.style,{animationIterationCount:e}),this.vendorSet(a.style,{animationName:b?"none":this.cachedAnimationName(a)}),a},e.prototype.vendors=["moz","webkit"],e.prototype.vendorSet=function(a,b){var c,d,e,f;d=[];for(c in b)e=b[c],a[""+c]=e,d.push(function(){var b,d,g,h;for(g=this.vendors,h=[],b=0,d=g.length;d>b;b++)f=g[b],h.push(a[""+f+c.charAt(0).toUpperCase()+c.substr(1)]=e);return h}.call(this));return d},e.prototype.vendorCSS=function(a,b){var c,e,f,g,h,i;for(h=d(a),g=h.getPropertyCSSValue(b),f=this.vendors,c=0,e=f.length;e>c;c++)i=f[c],g=g||h.getPropertyCSSValue("-"+i+"-"+b);return g},e.prototype.animationName=function(a){var b;try{b=this.vendorCSS(a,"animation-name").cssText}catch(c){b=d(a).getPropertyValue("animation-name")}return"none"===b?"":b},e.prototype.cacheAnimationName=function(a){return this.animationNameCache.set(a,this.animationName(a))},e.prototype.cachedAnimationName=function(a){return this.animationNameCache.get(a)},e.prototype.scrollHandler=function(){return this.scrolled=!0},e.prototype.scrollCallback=function(){var a;return!this.scrolled||(this.scrolled=!1,this.boxes=function(){var b,c,d,e;for(d=this.boxes,e=[],b=0,c=d.length;c>b;b++)a=d[b],a&&(this.isVisible(a)?this.show(a):e.push(a));return e}.call(this),this.boxes.length||this.config.live)?void 0:this.stop()},e.prototype.offsetTop=function(a){for(var b;void 0===a.offsetTop;)a=a.parentNode;for(b=a.offsetTop;a=a.offsetParent;)b+=a.offsetTop;return b},e.prototype.isVisible=function(a){var b,c,d,e,f;return c=a.getAttribute("data-wow-offset")||this.config.offset,f=window.pageYOffset,e=f+Math.min(this.element.clientHeight,this.util().innerHeight())-c,d=this.offsetTop(a),b=d+a.clientHeight,e>=d&&b>=f},e.prototype.util=function(){return null!=this._util?this._util:this._util=new b},e.prototype.disabled=function(){return!this.config.mobile&&this.util().isMobile(navigator.userAgent)},e}()}).call(this); \ No newline at end of file diff --git a/spec/coffeescripts/wow-spec.coffee b/spec/coffeescripts/wow-spec.coffee index b308ef5..ab4183e 100644 --- a/spec/coffeescripts/wow-spec.coffee +++ b/spec/coffeescripts/wow-spec.coffee @@ -217,6 +217,11 @@ describe 'WOW', -> callback: -> called = true .init() + + # Trigger custom event on dom object, event name is boxClass value + $('.block').on 'block', -> + $(this).addClass('triggered') + setTimeout -> done() , timeout @@ -308,3 +313,22 @@ describe 'WOW', -> .toBe true done() , timeout + + it 'fires the callback on the visible element', (done) -> + # Scroll down so that 150px of #custom-3 becomes visible. + window.scrollTo 0, $('#custom-3').offset().top - winHeight + 150 + setTimeout -> + expect $ '#custom-3' + .toHaveClass 'triggered' + expect $ '#custom-4' + .not.toHaveClass 'triggered' + # Scroll down so that 150px of #custom-4 becomes visible. + window.scrollTo 0, $('#custom-4').offset().top - winHeight + 150 + setTimeout -> + expect $ '#custom-3' + .toHaveClass 'triggered' + expect $ '#custom-4' + .toHaveClass 'triggered' + done() + , timeout + , timeout diff --git a/spec/javascripts/wow-spec.js b/spec/javascripts/wow-spec.js index dde5279..7ec66c3 100644 --- a/spec/javascripts/wow-spec.js +++ b/spec/javascripts/wow-spec.js @@ -153,6 +153,9 @@ return called = true; } }).init(); + $('.block').on('block', function() { + return $(this).addClass('triggered'); + }); return setTimeout(function() { return done(); }, timeout); @@ -214,7 +217,7 @@ }, timeout); }, timeout); }); - return it("fires the callback", function(done) { + it("fires the callback", function(done) { called = false; window.scrollTo(0, $('#custom-3').offset().top - winHeight + 150); return setTimeout(function() { @@ -222,6 +225,19 @@ return done(); }, timeout); }); + return it('fires the callback on the visible element', function(done) { + window.scrollTo(0, $('#custom-3').offset().top - winHeight + 150); + return setTimeout(function() { + expect($('#custom-3')).toHaveClass('triggered'); + expect($('#custom-4')).not.toHaveClass('triggered'); + window.scrollTo(0, $('#custom-4').offset().top - winHeight + 150); + return setTimeout(function() { + expect($('#custom-3')).toHaveClass('triggered'); + expect($('#custom-4')).toHaveClass('triggered'); + return done(); + }, timeout); + }, timeout); + }); }); }); diff --git a/src/wow.coffee b/src/wow.coffee index 6d9a595..4368437 100644 --- a/src/wow.coffee +++ b/src/wow.coffee @@ -15,6 +15,26 @@ class Util isMobile: (agent) -> /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(agent) + createEvent: (event, bubble = false, cancel = false, detail = null) -> + if document.createEvent? # W3C DOM + customEvent = document.createEvent('CustomEvent') + customEvent.initCustomEvent(event, bubble, cancel, detail) + else if document.createEventObject? # IE DOM < 9 + customEvent = document.createEventObject() + customEvent.eventType = event + else + customEvent.eventName = event + + customEvent + + emitEvent: (elem, event) -> + if elem.dispatchEvent? # W3C DOM + elem.dispatchEvent(event) + else if elem[event]? + elem[event](); + else if elem['on'+event]? + elem['on'+event](); + addEvent: (elem, event, fn) -> if elem.addEventListener? # W3C DOM elem.addEventListener event, fn, false @@ -93,6 +113,7 @@ class @WOW @config = @util().extend(options, @defaults) # Map of elements to animation names: @animationNameCache = new WeakMap() + @wowEvent = @util().createEvent(@config.boxClass) init: -> @element = window.document.documentElement @@ -152,6 +173,7 @@ class @WOW @applyStyle(box) box.className = "#{box.className} #{@config.animateClass}" @config.callback(box) if @config.callback? + @util().emitEvent(box, @wowEvent) applyStyle: (box, hidden) -> duration = box.getAttribute('data-wow-duration')