I'm new to OOP in Javascript and I'm having some difficulties.
I wanted to manage objects that do something when they are in viewport.
The code I used
Here is the code that I've implemented. Please note that the problem is especially on the row window.addEventListener( 'scroll', this.i_am_watching.bind(this), false );
that does not work as expected.
<html><head>
<style>
.content { background: #f8f8f8; padding: 20px; height: 1000px; }
.person { padding: 20px; font-size: 20px; line-height: 20px; }
.person.mark { background: pink; }
.person.peter { background: lightblue; }
.person.albert { background: lightgreen; }
div + div { margin-top: 20px; }
div { border: 1px solid black; }
#console { position: fixed; top: 10px; right: 10px; width: 50%; height: 300px; overflow: auto; border: 3px solid black; background: white; }
</style>
</head><body>
<div id="console"></div>
<div class="content">...some content...</div>
<div id="mark_div" class="person mark">MARK</div>
<div class="content">...some content...</div>
<div id="peter_div" class="person peter">PETER</div>
<div class="content">...some content...</div>
<div id="albert_div" class="person albert">ALBERT</div>
<div class="content">...some content...</div>
<script>
function Person( name, div_id )
{
// properties
this.label = name;
this.div = document.getElementById( div_id );
// auxiliary function
this.is_in_viewport = function( el )
{
var rect = el.getBoundingClientRect();
return (
rect.top+el.offsetHeight >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
);
}
// i_am_watching
this.i_am_watching = function()
{
if( this.is_in_viewport( this.div ) ) document.getElementById('console').innerHTML += "I'm watching <b>"+name+"<br>" ;
}
// listener
window.addEventListener( 'scroll', this.i_am_watching, false );
}
Person( "mark", "mark_div" );
Person( "peter", "peter_div" );
Person( "albert", "albert_div" );
</script>
</body></html>
Fiddle: https://jsfiddle.net/bd3182zw/2/
The problem
The problem is that the listener fires only and always when Albert is on the viewport. And when it fires, all objects execute the i_am_watching
method.
bind
doesn't work
As suggested in the MDN reference for EventTarget.addEventListener() (section "The value of this within the handler"), I've tried to add .bind(this)
after the function called by the listener, in order to ensure that this
applies to the right object; but as you can see,m it doesn't work.
What I'm doing wrong?