Reputation: 246
I am trying to get more object-oriented when writing Javascript for (simple) websites. I want to create a new object, vidyo
, for each video element on the page while looping through them. Here's what I have right now. This achieves my goals for the function but I know there has to be a better way to organize this code.
I want to be able to call vidyo
on $('video')
after the loop. I also want to make it more plugin like, so I could possibly add in options.
I tried making vidyo
a legitimate object and tried making new instances of it inside the loop but that didn't work.
Any pointers on how to turn these lines into something more robust? Thanks.
var $win = $(window),
top = $win.scrollTop(),
$videos = $('video');
var vidyo = {
play: function(video) {
video[0].play();
},
pause: function(video) {
video[0].pause();
},
check: function(vid) {
var top = $win.scrollTop();
var videoHeight = $(vid).outerHeight(true),
videoHitTop = $(vid).offset().top,
videoOffTheTop = videoHeight + videoHitTop;
if ( top >= videoHitTop && top <= videoOffTheTop ) {
vidyo.play($(vid));
} else {
vidyo.pause($(vid));
}
}
}
var checkVideoPosition = function() {
$videos.each( function( index, el ) {
vidyo.check(el);
})
}
$win.on('scroll', checkVideoPosition);
Upvotes: 2
Views: 154
Reputation: 338406
Remove all global variables and keep it simple. You don't really need a plugin or a fancy object oriented approach.
$(window).on('scroll', function () {
var top = $(this).scrollTop(),
$videos = $('video'),
$inView = $videos.filter(function () {
var height = $(this).outerHeight(true),
hitTop = $(this).offset().top,
offTheTop = height + hitTop;
return top >= hitTop && top <= offTheTop;
});
$inView.each(function () {
if (this.paused) this.play();
});
$videos.not($inView).each(function () {
if (!this.paused) this.pause();
});
});
Edit: you can make this a bit nicer by defining the fixed utility functions in a closure. This way the functions are not re-defined every time the scroll event is being triggered.
$(window).on('scroll', (function () {
function isInView() {
var top = $(window).scrollTop(),
height = $(this).outerHeight(true),
hitTop = $(this).offset().top,
offTheTop = height + hitTop;
return top >= hitTop && top <= offTheTop;
}
function playConditionally() {
if (this.paused) this.play();
}
function pauseConditionally() {
if (!this.paused) this.pause();
}
return function () {
var $videos = $('video'),
$inView = $videos.filter(isInView);
$inView.each(playConditionally);
$videos.not($inView).each(pauseConditionally);
};
})());
Upvotes: 1
Reputation: 445
MDN has an extremely well-written guide to Object Oriented Programming in Javascript. The links along the left are also very helpful pages to read too. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript
Here's a template to get you started. I won't re-write all your functions for you, I merely intend to steer you in the right direction.
function Vidyo (el) {
this.element = el && el.tagName === "VIDEO" ? el : document.createElement("video");
}
Vidyo.prototype = {
play: function() {
this.element.play();
},
pause: function () {
this.element.pause();
},
check: function () {
// ...
}
}
var $videos = $("video"),
vidyos = [];
$videos.each(function (i, el) { vidyos.push( new Vidyo(el) ); });
Hope this helps. I don't know if jQuery has an easier way to get this set up -- I've never used the library. Good luck and have fun!
Upvotes: 1