| /** |
| * Copyright Marc J. Schmidt. See the LICENSE file at the top-level |
| * directory of this distribution and at |
| * https://github.com/marcj/css-element-queries/blob/master/LICENSE. |
| */ |
| ; |
| (function() { |
| |
| /** |
| * Class for dimension change detection. |
| * |
| * @param {Element|Element[]|Elements|jQuery} element |
| * @param {Function} callback |
| * |
| * @constructor |
| */ |
| this.ResizeSensor = function(element, callback) { |
| /** |
| * |
| * @constructor |
| */ |
| function EventQueue() { |
| this.q = []; |
| this.add = function(ev) { |
| this.q.push(ev); |
| }; |
| |
| var i, j; |
| this.call = function() { |
| for (i = 0, j = this.q.length; i < j; i++) { |
| this.q[i].call(); |
| } |
| }; |
| } |
| |
| /** |
| * @param {HTMLElement} element |
| * @param {String} prop |
| * @returns {String|Number} |
| */ |
| function getComputedStyle(element, prop) { |
| if (element.currentStyle) { |
| return element.currentStyle[prop]; |
| } else if (window.getComputedStyle) { |
| return window.getComputedStyle(element, null).getPropertyValue(prop); |
| } else { |
| return element.style[prop]; |
| } |
| } |
| |
| /** |
| * |
| * @param {HTMLElement} element |
| * @param {Function} resized |
| */ |
| function attachResizeEvent(element, resized) { |
| if (!element.resizedAttached) { |
| element.resizedAttached = new EventQueue(); |
| element.resizedAttached.add(resized); |
| } else if (element.resizedAttached) { |
| element.resizedAttached.add(resized); |
| return; |
| } |
| |
| element.resizeSensor = document.createElement('div'); |
| element.resizeSensor.className = 'resize-sensor'; |
| var style = 'position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; z-index: -1; visibility: hidden;'; |
| var styleChild = 'position: absolute; left: 0; top: 0;'; |
| |
| element.resizeSensor.style.cssText = style; |
| element.resizeSensor.innerHTML = |
| '<div class="resize-sensor-expand" style="' + style + '">' + |
| '<div style="' + styleChild + '"></div>' + |
| '</div>' + |
| '<div class="resize-sensor-shrink" style="' + style + '">' + |
| '<div style="' + styleChild + ' width: 200%; height: 200%"></div>' + |
| '</div>'; |
| element.appendChild(element.resizeSensor); |
| |
| if (!{fixed: 1, absolute: 1}[getComputedStyle(element, 'position')]) { |
| element.style.position = 'relative'; |
| } |
| |
| var expand = element.resizeSensor.childNodes[0]; |
| var expandChild = expand.childNodes[0]; |
| var shrink = element.resizeSensor.childNodes[1]; |
| var shrinkChild = shrink.childNodes[0]; |
| |
| var lastWidth, lastHeight; |
| |
| var reset = function() { |
| expandChild.style.width = expand.offsetWidth + 10 + 'px'; |
| expandChild.style.height = expand.offsetHeight + 10 + 'px'; |
| expand.scrollLeft = expand.scrollWidth; |
| expand.scrollTop = expand.scrollHeight; |
| shrink.scrollLeft = shrink.scrollWidth; |
| shrink.scrollTop = shrink.scrollHeight; |
| lastWidth = element.offsetWidth; |
| lastHeight = element.offsetHeight; |
| }; |
| |
| reset(); |
| |
| var changed = function() { |
| if (element.resizedAttached) { |
| element.resizedAttached.call(); |
| } |
| }; |
| |
| var addEvent = function(el, name, cb) { |
| if (el.attachEvent) { |
| el.attachEvent('on' + name, cb); |
| } else { |
| el.addEventListener(name, cb); |
| } |
| }; |
| |
| addEvent(expand, 'scroll', function() { |
| if (element.offsetWidth > lastWidth || element.offsetHeight > lastHeight) { |
| changed(); |
| } |
| reset(); |
| }); |
| |
| addEvent(shrink, 'scroll',function() { |
| if (element.offsetWidth < lastWidth || element.offsetHeight < lastHeight) { |
| changed(); |
| } |
| reset(); |
| }); |
| } |
| |
| if ("[object Array]" === Object.prototype.toString.call(element) |
| || ('undefined' !== typeof jQuery && element instanceof jQuery) //jquery |
| || ('undefined' !== typeof Elements && element instanceof Elements) //mootools |
| ) { |
| var i = 0, j = element.length; |
| for (; i < j; i++) { |
| attachResizeEvent(element[i], callback); |
| } |
| } else { |
| attachResizeEvent(element, callback); |
| } |
| |
| this.detach = function() { |
| ResizeSensor.detach(element); |
| }; |
| }; |
| |
| this.ResizeSensor.detach = function(element) { |
| if (element.resizeSensor) { |
| element.removeChild(element.resizeSensor); |
| delete element.resizeSensor; |
| delete element.resizedAttached; |
| } |
| }; |
| |
| })(); |