1 | /*!
|
---|
2 | * Trend 0.2.0
|
---|
3 | *
|
---|
4 | * Fail-safe TransitionEnd event for jQuery.
|
---|
5 | *
|
---|
6 | * Adds a new "trend" event that can be used in browsers that don't
|
---|
7 | * support "transitionend".
|
---|
8 | *
|
---|
9 | * NOTE: Only supports being bound with "jQuery.one".
|
---|
10 | *
|
---|
11 | * Copyright 2014, Pixel Union - http://pixelunion.net
|
---|
12 | * Released under the MIT license
|
---|
13 | */
|
---|
14 | ;(function($){
|
---|
15 |
|
---|
16 | // Prefixed transitionend event names
|
---|
17 | var transitionEndEvents =
|
---|
18 | "webkitTransitionEnd " +
|
---|
19 | "otransitionend " +
|
---|
20 | "oTransitionEnd " +
|
---|
21 | "msTransitionEnd " +
|
---|
22 | "transitionend";
|
---|
23 |
|
---|
24 | // Prefixed transition duration property names
|
---|
25 | var transitionDurationProperties = [
|
---|
26 | "transition-duration",
|
---|
27 | "-moz-transition-duration",
|
---|
28 | "-webkit-transition-duration",
|
---|
29 | "-ms-transition-duration",
|
---|
30 | "-o-transition-duration",
|
---|
31 | "-khtml-transition-duration"
|
---|
32 | ];
|
---|
33 |
|
---|
34 | // Prefixed transition delay property names
|
---|
35 | var transitionDelayProperties = [
|
---|
36 | "transition-delay",
|
---|
37 | "-moz-transition-delay",
|
---|
38 | "-webkit-transition-delay",
|
---|
39 | "-ms-transition-delay",
|
---|
40 | "-o-transition-delay",
|
---|
41 | "-khtml-transition-delay"
|
---|
42 | ];
|
---|
43 |
|
---|
44 | // Parses a CSS time value into milliseconds.
|
---|
45 | var parseTime = function(s) {
|
---|
46 | s = s.replace(/\s/, "");
|
---|
47 | var v = window.parseFloat(s);
|
---|
48 |
|
---|
49 | return s.match(/[^m]s$/i)
|
---|
50 | ? v * 1000
|
---|
51 | : v;
|
---|
52 | };
|
---|
53 |
|
---|
54 | // Parses the longest time unit found in a series of CSS properties.
|
---|
55 | // Returns a value in milliseconds.
|
---|
56 | var parseProperties = function(el, properties) {
|
---|
57 | var duration = 0;
|
---|
58 |
|
---|
59 | for (var i = 0; i < properties.length; i++) {
|
---|
60 | // Get raw CSS value
|
---|
61 | var value = el.css(properties[i]);
|
---|
62 | if (!value) continue;
|
---|
63 |
|
---|
64 | // Multiple transitions--pick the longest
|
---|
65 | if (value.indexOf(",") !== -1) {
|
---|
66 | var values = value.split(",");
|
---|
67 | var durations = (function(){
|
---|
68 | var results = [];
|
---|
69 | for (var i = 0; i < values.length; i++) {
|
---|
70 | var duration = parseTime(values[i]);
|
---|
71 | results.push(duration);
|
---|
72 | }
|
---|
73 | return results;
|
---|
74 | })();
|
---|
75 |
|
---|
76 | duration = Math.max.apply(Math, durations);
|
---|
77 | }
|
---|
78 |
|
---|
79 | // Single transition
|
---|
80 | else {
|
---|
81 | duration = parseTime(value);
|
---|
82 | }
|
---|
83 |
|
---|
84 | // Accept first vaue
|
---|
85 | break;
|
---|
86 | }
|
---|
87 |
|
---|
88 | return duration;
|
---|
89 | };
|
---|
90 |
|
---|
91 | $.event.special.trend = {
|
---|
92 | // Triggers an event handler when an element is done transitioning.
|
---|
93 | //
|
---|
94 | // Handles browsers that don't support transitionend by adding a
|
---|
95 | // timeout with the transition duration.
|
---|
96 | add: function(handleObj) {
|
---|
97 | var el = $(this);
|
---|
98 | var fired = false;
|
---|
99 |
|
---|
100 | // Mark element as being in transition
|
---|
101 | el.data("trend", true);
|
---|
102 |
|
---|
103 | // Calculate a fallback duration. + 20 because some browsers fire
|
---|
104 | // timeouts faster than transitionend.
|
---|
105 | var time =
|
---|
106 | parseProperties(el, transitionDurationProperties) +
|
---|
107 | parseProperties(el, transitionDelayProperties) +
|
---|
108 | 20;
|
---|
109 |
|
---|
110 | var cb = function(e) {
|
---|
111 | // transitionend events can be sent for each property. Let's just
|
---|
112 | // skip all but the first. Also handles the timeout callback.
|
---|
113 | if (fired) return;
|
---|
114 |
|
---|
115 | // Child elements that also have transitions can be fired before we
|
---|
116 | // complete. This will catch and ignore those. Unfortunately, we'll
|
---|
117 | // have to rely on the timeout in these cases.
|
---|
118 | if (e && e.srcElement !== el[0]) return;
|
---|
119 |
|
---|
120 | // Mark element has not being in transition
|
---|
121 | el.data("trend", false);
|
---|
122 |
|
---|
123 | // Callback
|
---|
124 | fired = true;
|
---|
125 | if (handleObj.handler) handleObj.handler();
|
---|
126 | };
|
---|
127 |
|
---|
128 | el.one(transitionEndEvents, cb);
|
---|
129 | el.data("trend-timeout", window.setTimeout(cb, time));
|
---|
130 | },
|
---|
131 |
|
---|
132 | remove: function(handleObj) {
|
---|
133 | var el = $(this);
|
---|
134 | el.off(transitionEndEvents);
|
---|
135 | window.clearTimeout(el.data("trend-timeout"));
|
---|
136 | }
|
---|
137 | };
|
---|
138 |
|
---|
139 | })(jQuery);
|
---|