diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..7e45dcf --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: marcj diff --git a/css-element-queries.d.ts b/css-element-queries.d.ts index 97ee144..3fe0706 100644 --- a/css-element-queries.d.ts +++ b/css-element-queries.d.ts @@ -1,2 +1,2 @@ -export { ResizeSensor, ResizeSensorCallback } from "./src/ResizeSensor"; +export { ResizeSensor, ResizeSensorCallback, Size } from "./src/ResizeSensor"; export { ElementQueries } from './src/ElementQueries'; \ No newline at end of file diff --git a/package.json b/package.json index 36a73d7..964230f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "css-element-queries", - "version": "1.2.1", + "version": "1.2.3", "description": "CSS-Element-Queries Polyfill. Proof-of-concept for high-speed element dimension/media queries in valid css.", "main": "index.js", "typings": "css-element-queries.d.ts", diff --git a/src/ResizeSensor.d.ts b/src/ResizeSensor.d.ts index ad6c412..3fba8c6 100644 --- a/src/ResizeSensor.d.ts +++ b/src/ResizeSensor.d.ts @@ -1,4 +1,9 @@ -export declare type ResizeSensorCallback = (size: { width: number; height: number; }) => void; +export declare interface Size { + width: number; + height: number; +} + +export declare type ResizeSensorCallback = (size: Size) => void; export declare class ResizeSensor { /** diff --git a/src/ResizeSensor.js b/src/ResizeSensor.js index ed4ef54..9a25503 100755 --- a/src/ResizeSensor.js +++ b/src/ResizeSensor.js @@ -36,6 +36,13 @@ return globalWindow.setTimeout(fn, 20); }; + var cancelAnimationFrame = globalWindow.cancelAnimationFrame || + globalWindow.mozCancelAnimationFrame || + globalWindow.webkitCancelAnimationFrame || + function (timer) { + globalWindow.clearTimeout(timer); + }; + /** * Iterate over each of the provided element(s). * @@ -102,6 +109,9 @@ * @constructor */ var ResizeSensor = function(element, callback) { + //Is used when checking in reset() only for invisible elements + var lastAnimationFrameForInvisibleCheck = 0; + /** * * @constructor @@ -195,16 +205,19 @@ var computedStyle = window.getComputedStyle(element); var position = computedStyle ? computedStyle.getPropertyValue('position') : null; - if ('absolute' !== position && 'relative' !== position && 'fixed' !== position) { + if ('absolute' !== position && 'relative' !== position && 'fixed' !== position && 'sticky' !== position) { element.style.position = 'relative'; } - var dirty, rafId; + var dirty = false; + + //last request animation frame id used in onscroll event + var rafId = 0; var size = getElementSize(element); var lastWidth = 0; var lastHeight = 0; var initialHiddenCheck = true; - var lastAnimationFrame = 0; + lastAnimationFrameForInvisibleCheck = 0; var resetExpandShrink = function () { var width = element.offsetWidth; @@ -226,10 +239,9 @@ var invisible = element.offsetWidth === 0 && element.offsetHeight === 0; if (invisible) { // Check in next frame - if (!lastAnimationFrame){ - lastAnimationFrame = requestAnimationFrame(function(){ - lastAnimationFrame = 0; - + if (!lastAnimationFrameForInvisibleCheck){ + lastAnimationFrameForInvisibleCheck = requestAnimationFrame(function(){ + lastAnimationFrameForInvisibleCheck = 0; reset(); }); } @@ -280,8 +292,11 @@ addEvent(expand, 'scroll', onScroll); addEvent(shrink, 'scroll', onScroll); - // Fix for custom Elements - requestAnimationFrame(reset); + // Fix for custom Elements and invisible elements + lastAnimationFrameForInvisibleCheck = requestAnimationFrame(function(){ + lastAnimationFrameForInvisibleCheck = 0; + reset(); + }); } forEachElement(element, function(elem){ @@ -289,17 +304,28 @@ }); this.detach = function(ev) { + // clean up the unfinished animation frame to prevent a potential endless requestAnimationFrame of reset + if (lastAnimationFrameForInvisibleCheck) { + cancelAnimationFrame(lastAnimationFrameForInvisibleCheck); + lastAnimationFrameForInvisibleCheck = 0; + } ResizeSensor.detach(element, ev); }; this.reset = function() { - element.resizeSensor.resetSensor(); + //To prevent invoking element.resizeSensor.resetSensor if it's undefined + if (element.resizeSensor.resetSensor) { + element.resizeSensor.resetSensor(); + } }; }; ResizeSensor.reset = function(element) { forEachElement(element, function(elem){ - elem.resizeSensor.resetSensor(); + //To prevent invoking element.resizeSensor.resetSensor if it's undefined + if (element.resizeSensor.resetSensor) { + elem.resizeSensor.resetSensor(); + } }); }; diff --git a/tests/demo.html b/tests/demo.html index d8a75c2..22968f0 100644 --- a/tests/demo.html +++ b/tests/demo.html @@ -97,6 +97,15 @@ .example-2[min-width~="400px"] .example-2-box { background-color: gray; } + + #example-invisible { + display: none; + } + + #example-invisible[min-width~="100px"]{ + color: red; + font-weight: bold; + } + + +

Performance Demo

@@ -393,4 +422,4 @@

Performance Demo

- \ No newline at end of file +