Detect if an element comes to the viewport

822 views
Skip to first unread message

Alexander Keil

unread,
Feb 25, 2015, 10:01:44 AM2/25/15
to ang...@googlegroups.com
Hi experts,

I'm new in angularJS and I try to create my first Android App.

I have a list of DIVs, created with ngRepeat:


<ion-scroll zooming="true" direction="y" class="historyTableScroll" has-bouncing="true">

 
<div id="item_{{playlist.id}}" class="singleItem repeat-animation"
 
ng-repeat="playlist in playlists track by playlist.id"
 
ng-class="{'new': playlist.status == 'new'}">
 
<h1>({{$index}}) {{playlist.id}}. {{playlist.title}}</h1>
 
</div>

</ion-scroll>

The class-attribute depends on the status from the playlist-array.

If I push an new element to the array, it will get the class='new'. Now, if the users scrolls down the list, I want to know when a <DIV class='new' ...> comes to the viewport. If the DIV is visible in the viewport, I want to change the class to 'open': <DIV class='open' ...>

I think this should be easily possible with directives, but I have no clue how! :-(

It would be great, if somebody could assist me!!!

Thanks in advance!
Alex

Alexander Keil

unread,
Feb 26, 2015, 9:24:58 AM2/26/15
to ang...@googlegroups.com
Hi again,

I found the solution by my self! ;-)

Here ist my HTML:


<ion-scroll zooming="true" direction="y" class="historyTableScroll" has-bouncing="true">

 
<div id="item_{{playlist.id}}" class="singleItem repeat-animation"
 
ng-repeat="playlist in playlists track by playlist.id"
 
ng-class="{'new': playlist.status == 'new' }"
 comes-to-view array-item="playlist" item-seen="itemSeen(playlist)">

 
<h1>({{$index}}) {{playlist.id}}. {{playlist.title}}</h1>
 
</div>
</ion-scroll>


My super Directive:

app
.directive('comesToView', function () {
 
return{
 restrict
: 'A',
 scope
:{
 arrayItem
: "=",
 itemSeen
: '&'
 
},
 link
: function (scope, element,$rootScope) {

 
var $page = angular.element(document.querySelector('ion-scroll'));
 
var $el = element[0];
 
var offset = $el.clientHeight;
 
var fired = false;

 
if (scope.arrayItem.status == 'new') {

 $page
.bind('scroll', function () {

 
var windowScrollTop = $page[0].getBoundingClientRect().top ;
 
var windowScrollBottom = $page[0].getBoundingClientRect().bottom ;
 
var elScrollTop = $el.getBoundingClientRect().top + offset;

 
if (elScrollTop < windowScrollBottom && elScrollTop > windowScrollTop && !fired) {
 
//Element visible

 fired
= true; //fire this only one time!
 console
.log('VISIBLE');
 scope
.itemSeen();   //call function in controller!
 
}
 
else {
 
//console.log('INVISIBLE');
 
}
 
})
 
} // IF Ende
 
} //link ENDE
 
} //return ENDE
});



Function in controller:

$scope
.itemSeen = function(challenge){
 console
.log('YEAAAAH! ' + challenge.status);
 
// do what ever you want to do!
}








Reply all
Reply to author
Forward
0 new messages