watch element height in directive

9,690 views
Skip to first unread message

Efflam Daniel

unread,
Aug 8, 2012, 9:21:25 AM8/8/12
to ang...@googlegroups.com
Hi !
I've done a directive to add iScroll to an element.
Now i'm trying to find a way to refresh iScroll if the element height change.
I've tried something like this, but it doesn't work :
scope.$watch(function(){return $(element).height(); }, function(newValue, oldValue) {
if(newValue != oldValue) refreshScroll();
});

How can i watch the element height in a directive ?
Thx !

Efflam Daniel

unread,
Aug 8, 2012, 9:28:34 AM8/8/12
to ang...@googlegroups.com
Oh, i was watching the wrapper height and not the content height.
with something like this, it works :

scope.$watch(function(){return $(content).height(); }, function(newValue, oldValue) {
   if(newValue != oldValue) refreshScroll();
});

Efflam Daniel

unread,
Aug 11, 2012, 8:42:38 AM8/11/12
to ang...@googlegroups.com
In fact it works when the content height is updated from inside of angular but it doesn't when the change come from outside like when an image appears after loading and change the content height.
Any suggestions ?
Thx !

Erik Petersen

unread,
Aug 11, 2012, 2:17:40 PM8/11/12
to ang...@googlegroups.com
The image load isn't forcing a dirty check.  You could bind to the load event of the content (I think the image load bubbles?  I dunno, maybe not!) and then call a dirty check with `scope.$digest()`.

I've never done this and am new so no guarantees :)

Efflam Daniel

unread,
Aug 11, 2012, 6:29:02 PM8/11/12
to ang...@googlegroups.com
Thx Erik
I'm new to angular too ;)
Yes, that was this dirty checking i was thinking when i said from inside / outside angular

But unfortunately,
from w3 site :
If the download was successful :
Set the img element to the completely available state, update the presentation of the image appropriately, and fire a simple event named load at the img element.

"fire a simple event" means (again from w3 site):
Firing a simple event named e means that an event with the name e, which does not bubble (except where otherwise stated) and is not cancelable (except where otherwise stated), and which uses the Event interface, must be created and dispatched at the given target.

So it seems that image load event doesn't bubbles. 
Maybe i can try to bind to the load event of each images.
But when the directive compile, img tags may not be present yet so i'll need to watch when new elements are added. Is there a way to do that ?  

Efflam Daniel

unread,
Aug 11, 2012, 7:00:08 PM8/11/12
to ang...@googlegroups.com
In the link function of the directive, 
element.bind('DOMNodeInserted', function(event){
var imgElements = angular.element(event.target).find('img');
angular.forEach(imgElements, function(imgElement){
angular.element(imgElement).bind('load', function(event){
scope.$digest();
});
});
});
seems to do the trick. I'm not really confident with this script. Is it an acceptable solution ?

Efflam Daniel

unread,
Aug 11, 2012, 7:30:29 PM8/11/12
to ang...@googlegroups.com
Call $digest on each image load was not a great idea for performance. So i changed the code to this :

function refreshScroll(){
    iscroll.refresh();
}

element.bind('DOMNodeInserted', function(event){
var imgElements = angular.element(event.target).find('img');
angular.forEach(imgElements, function(imgElement){
angular.element(imgElement).bind('load', function(event){
if(/* content height as changed */){
                             refreshScroll();
                        }
});
});
});

Perry Mcgee

unread,
Aug 14, 2012, 7:24:05 PM8/14/12
to ang...@googlegroups.com
I'd be careful when using DOMNodeInserted event.

it is deprecated and not supported in IE:

See about deprecation: http://www.w3.org/TR/DOM-Level-3-Events/#event-type-DOMNodeInserted

sh...@badassembly.com

unread,
Aug 21, 2012, 5:20:54 PM8/21/12
to ang...@googlegroups.com
I'd be interested in seeing your iScroll directive. Please share it if you wish.

drew...@gmail.com

unread,
Feb 6, 2013, 7:48:41 AM2/6/13
to ang...@googlegroups.com
Any updated on this?  Do you have the code on github?

Peter Bacon Darwin

unread,
Feb 6, 2013, 8:16:09 AM2/6/13
to ang...@googlegroups.com
This is not an issue with AngularJS but more a problem with browsers.
How would AngularJS know that the element's height has changed?
If you look around, there are various jQuery plugins that deal with this sort of thing but they all do something nasty like poll the height of the element every 100ms looking for changes.


--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular?hl=en-US.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Vladimir Varbanov

unread,
Jul 4, 2014, 2:27:54 AM7/4/14
to ang...@googlegroups.com
Is there any other solution not using the DOMNodeInserted as this is deprecated  from some browsers. I'm trying scope.$watch on a directive, but the event is firing only once - after the render? 

This is otherwise works actually, but not sure what compatibility have.
Vlad. 
Reply all
Reply to author
Forward
0 new messages