wnr / element-resize-detector Goto Github PK
View Code? Open in Web Editor NEWOptimized cross-browser resize listener for elements.
License: MIT License
Optimized cross-browser resize listener for elements.
License: MIT License
Hello!
I've tested your plugin and there is one Problem.
Actually the "scroll" strategy is just faster in case of loading performance.
The "object" strategy is much faster in runtime.
I've created a fiddle: https://jsfiddle.net/930mvaux/4/
The first element has the object strategy and the second has the scroll strategy.
If you will start resizing both elements, you will notice how mich faster the object strategy actually is.
Maybe you have some improvements.
Best regards,
Sora
: )
Hey, I notice when some listened component goes hidden, the event is not trigger, I'm using the object approach.
Thank you!
Try this in Chrome, it should add "lt" and "gte" classes to the elements for breakpoints 400 and 800.
It works some of the time, but often it does not. If you set dir="ltr" it works flawlessly.
<!DOCTYPE html>
<html dir="rtl">
<head>
<style>
body {
box-sizing: border-box;
height: 100%;
}
.maincontainer {
width: 70%;
height: 100%;
float: left;
}
.sidebar {
width: 30%;
height: 100%;
float: left;
}
.box.gte800 {
background-color: grey;
}
.box.lt800.gte400 {
background-color: lightgoldenrodyellow;
}
.box.lt400 {
background-color: lightblue;
}
</style>
</head>
<body ng-app="cq">
<h1>Hello Plunker!</h1>
<div class="maincontainer">
<box>Box1 content (70% width)</box>
<box>Box2 content (70% width)</box>
</div>
<div class="sidebar">
<box>Box3 content (30% width)</box>
<box>Box4 content (30% width)</box>
</div>
<script data-require="[email protected]" data-semver="2.1.3" src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
<script src="https://rawgit.com/wnr/element-resize-detector/master/dist/element-resize-detector.js"></script>
<script data-require="[email protected]" data-semver="1.5.3" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>
<script>
angular.module('cq', [])
.service('ElementWidthDetector', function () {
var erd = elementResizeDetectorMaker({
strategy: "scroll" //<- For ultra performance.
});
this.listenTo = erd.listenTo;
this.removeListener = erd.removeListener;
})
.directive('cqBreakpoints', ['ElementWidthDetector', function (ElementWidthDetector) {
return {
restrict: 'A',
scope: {
onResize: '&',
},
link: function (scope, element, attrs) {
var breakpoints = attrs.cqBreakpoints.split(' ');
var listener = function () {
calculateCssClasses(element, breakpoints);
scope.onResize({width: element[0].offsetWidth})
}
ElementWidthDetector.listenTo(element, listener);
element.on('$destroy', function () {
ElementWidthDetector.removeListener(element, listener);
})
}
};
}])
.component('box', {
template: '<div class="box" ng-transclude cq-breakpoints="400 800" on-resize="$ctrl.resized(width)"></div>',
transclude: true,
controller: function () {
this.resized = function(width) {
console.log('Box resized to: ' + width);
};
}
});
// Code goes here
function calculateCssClasses(el, breakpoints) {
var classesToRemove = breakpoints.reduce(function (a, b) { return a + ' lt' + b + ' gte' + b; }, '');
el.removeClass(classesToRemove);
var w = el[0].offsetWidth;
breakpoints.forEach(function (val) {
var b = parseFloat(val);
if (w < b) {
el.addClass("lt" + val);
} else {
el.addClass("gte" + val);
}
});
}
</script>
</body>
</html>
It could be computed by the formula presented in http://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively
Probably doesn't like the async batch updating.
Testing this library in a Cordova HTML5 application running on iOS simulator. Is it supposed to work?
Basically I scroll up and down the application/HTML with the mouse, and have also tried changing CSS properties of the target element via the JavaScript console. It does not fire the resize listener at all.
Hi!
I have an issue with element-resize-detector not working in firefox if it gets applied to an element which has a parent element that has display: 'none';
.
I temporarily solved this by hiding the element using position: absolute
and visibility: hidden
.
It still looks like this is an open issue on resizeSensor:
If dimension changes are done directly after listenTo calls then it might be that those resize events are not fired (since adding the event listener is async). This can probably be fixed by manually checking the dimensions before and after attachment of listener.
This can totally be done in a stylesheet, but how do you feel about adding flex: 0
into the containerContainer
inline styles? https://github.com/wnr/element-resize-detector/blob/master/dist/element-resize-detector.js#L793
Hi, I work on Chrome, and my next task is to create a native resize observer. It'll be similar to element-resize-detector.
I am currently writing a spec, and am looking for usage examples. Do you have any examples of where resize detector was needed?
PS: The scrolling trick you've used is neat. I've thought about how I'd write a polyfill, and did not come up with anything as clever.
Seem to call callback 2 times for each element.
Could be fixed with:
.resize-triggers > div::-webkit-scrollbar {
display: none; /* Fixes the Chrome scrollbar bug */
}
from http://www.backalleycoder.com/2013/03/18/cross-browser-event-based-element-resize-detection/
Calling uninstall too soon after calling listenTo results in an error:
element-resize-detector.js:969 Uncaught TypeError: Failed to execute 'removeChild' on 'Node': parameter 1 is not of type 'Node'.
This seems to happen because the work in listenTo has not completed yet and there doesn't seem to be any way of knowing when it's safe to call uninstall.
Failing test code:
window.onload = function() {
var elementResizeDetector = elementResizeDetectorMaker({
strategy: 'scroll'
});
elementResizeDetector.listenTo(document.querySelector('body'), console.log.bind(console));
elementResizeDetector.uninstall(document.querySelector('body'));
}
I thought MS Edge was supported after seeing this script referenced in the comments on http://www.backalleycoder.com/2013/03/18/cross-browser-event-based-element-resize-detection/, but it appears to be having issues using either strategy. Minimal test cases:
http://s.codepen.io/RwwL/debug/qbNamO (uses default strategy, not working in Edge with provided buttons or on window resize)
http://s.codepen.io/RwwL/debug/GoqNKd (uses scroll strategy, works in Edge on window resize but not after using the font size/padding buttons)
Maybe there's been a regression? Apologies if the mistake is in my usage or assumptions, of course.
Also possibly helpful info: working in CodePen's /pen/editors view, it appeared at first that the script wasn't working with any browser, but after checking the issues I think that may just be another occurrence of #31.
See #31. getComputedStyle
returns "auto"
for width and height of elements that are not block display elements. Therefore the scroll strategy fails the style resolved check. This could perhaps be solved by using the element.getBoundingClientRect
or element.getClientRects
instead.
Does not work with elements that are not yet in the DOM. Would be nice to be able to activate elements so that the resize listener kicks in when the element is added to the DOM.
Hi. We encountered an interesting issue. Where an element was activated, but it was displayed none. This causes the resize detection to not trigger if the element is shown again it looks like. Going to try and recreate in a plunker
See elqteam/elq#56
When calling the uninstall method on a erd the above error is thrown.
var resizeDetectorElements = $("#uid .container").toArray();
var resizeDetector = elementResizeDetectorMaker({
strategy: "scroll" //<- For ultra performance.
});
resizeDetector.listenTo(resizeDetectorElements, function(element) {
// code for resize
});
*** this line throws the error ***
resizeDetector.uninstall(resizeDetectorElements);
Object seem do be broken on IE8 (and down?). Perhaps use the resize event instead of object fix since those legacy browsers support it.
The user orbolanos commented at backalleycoder and stated that:
It looks like the created object is focusable under Firefox.
Adding the following code under addResizeListener fixes the issue.
obj.setAttribute('tabindex', '-1');
As far as I understood you are using backalleycoder's approach. Are you aware of this potential issue?
I might be doing something really stupid here, but I cannot get this to work at all in JSFiddle. I'm actually trying to reproduce another problem I'm having with our prod site so I can submit an issue for that, but I can't get this library to work at all on JSFiddle.
Is it safe to remove element without remove handler ?
In some cases, the element is removed without any chance to remove listeners. will this cause any problem like memory leaking?
Could you please add a bower.json
to support installing with bower?
I suggest creating and appending a new element for each test.. is there some magic going on that takes care of that, or are all the tests using the same DOM/state ? I have limited experience with Jasmine/Karma (I use tape), so I might be missing something. If each test is reusing the same element, I'd be glad to submit a PR to improve this. I think the Jasmine way is to use beforeEach()
, though I personally prefer to skip the magic and manually call functions I need per test. Tell me what you think and I'll see if I can help.
I have an error when quickly adding and removing an element from DOM:
Uncaught TypeError: Cannot read property 'container' of undefined
Happens in Chrome, can't reproduce it in IE 11 or Firefox.
We use React.
Stacktrace
getExpandElement
getExpandChildElement
updateChildSizes
performUpdateChildSizes
process
processBatch
I can se that the the error happens after the element is uninstalled.
Can be solved by having only one function applied to the object, which calls all listeners
Hi!
It seems that latest npm version is very old, could you please update npm packages?
Hi, you have tagged the new release, but the dist code is stil 0.3.2. Could you please update?
During certain manual stress tests, I ended up with the following error.
main.9f41ae4โฆ.js:16 Uncaught TypeError: Cannot read property 'onShrink' of undefined
Unfortunately, it was a production system I was testing, so I just narrowed it down to this library, and the location of the minimized code looks something like this:
O(w,"scroll",function(){c(e).onShrink&&c(e).onShrink()})}
which leads to this line on the scroll detection strategy file: https://github.com/wnr/element-resize-detector/blob/master/src/detection-strategy/scroll.js#L370
So, probably a scroll event executed even the element's state is invalid. I'm unsure on when exactly that happened, due to the nature of my tests. However, I'm certain enough to file this issue (I'm using the resizer at only one point in the whole application, and it properly disposes of its resources, so its not from the app directly, but just likely just sets it up for this bug).
Should not contain elq information. Also, should be able to configure which id to use if element already has one.
Can happen when the ERD enabled element is positioned close to the page boundaries.
Fixed by wrapping .erd_scroll_detection_container
with something like this:
<div style="overflow: hidden; position: absolute; top: 0; right: 0; bottom: 0; left: 0">
...
</div>
Should probably be tested that it doesn't cause new issues.
Right now layouts are being forced by offsetWidth
and getComputedStyle(element)
.
The offsetWidth
can be removed (since callOnAdd
option exists) and getComputedStyle(element)
may be changed to element.style
because only position
is accessed (which does not need to be computed, or does it?).
This makes the .start()
call 10 times faster in bootstrap-elq.
one suggestion was to use "derequire" eg so you'd end up with:
browserify main.js --standalone Foo | derequire > bundle.js
as a note, there is no issue with your minified build (since the "require" function is renamed anyway)
If resize-detection using the 'object' strategy is triggered on an element that is then removed from the page, line 28 in src/detection-strategy/object.js
might throw an error, and it seems this error is thrown from asynchronous code, which makes catching it somewhat difficult.
In our case, it made IE11 throw up a dialog asking the end-user to debug the application :(
If this error needs to be communicated to the consumer, it should be done using a promise rejection, or perhaps a callback.
https://github.com/wnr/element-resize-detector/blob/master/src/detection-strategy/object.js#L28
If an element is not detached, but has width "auto" (as in the case when display:block) it could be feasible to traverse the DOM chain to fetch the first parent element that has an explicit width. This could get messy with different layout options for elements (inline vs block) etc, but could perhaps be done quite easily.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.