Making long story short, I got a chance to jump from DevOps to Software Development (Frontend). Because I'm quite new to JS design patterns, I need some quality advice about the job I've done recently.
The goal is to create a component which checks if there's a particular class on the current page, and if yes, add event listeners for the document (one default & one custom) that will hold the logic for triggering a popup. The popup should appear only once, then the event listener should not perform any anymore actions. For this, I defined the lockPopup
variable (state management). There is also screenEdge
flag available, since the requirements for this project are changing and it basically flips around quite often.
I chose a kind-of revealing module pattern, with init function that will be called on jQuery's $( document ).ready()
method.
var Popup = (function() {
// Component state management
var lockPopup = false;
var screenEdge = 'top';
// Variables for jQuery selectors
var passableClassName = '.passable-class';
var animatedClassName = '.animated-class';
// Cache DOM
var $elementToSelect = $(passableClassName);
var $elementToAnimate = $(animatedClassName);
// Entrypoint for application
function _init() {
_conditionalEventBind();
}
// Conditional event binding
function _conditionalEventBind() {
if (typeof $elementToSelect[0] !== 'undefined') {
$(document).scroll(_notifyEventToBeDispatched);
$(document).on("togglePopup", _togglePopup);
}
}
// Event listener callbacks
//
// Determining the position from selected item in document
function _determineValidPosition() {
var $scrolledDistance = $(window).scrollTop();
var $itemTopOffset = $elementToSelect.offset().top;
if (screenEdge === 'top') {
return $scrolledDistance >= $itemTopOffset;
};
if (screenEdge === 'bottom') {
return ($scrolledDistance + window.screen.availHeight) >= $itemTopOffset;
}
}
function _notifyEventToBeDispatched() {
if (!lockPopup) {
if (_determineValidPosition()) {
$.event.trigger({ type: "togglePopup" });
lockPopup = true;
}
}
}
// Function definition for popup animation
function _togglePopup() {
$($elementToAnimate).fadeIn(500).delay(5000).fadeOut(500);
}
// **************************** Component initialisation *
// Returning main entry point for application, so the rest of
// component features are private & not accessible from outside
return {
init: _init
}
})();
Example how will be called:
$( document ).ready(function() {
Popup.init();
});
I will be extremely grateful for any hints regarding this style/logic that I've applied here.
typeof $elementToSelect[0] !== 'undefined'
is justif($elementToSelect.length)
.. if it doesn't have any elements the length will be zero, which is falsy. \$\endgroup\$init
if you so desperately need to have a function with that name. \$\endgroup\$_notifyEventToBeDispatched
.. combine them,if (!lockPopup && _determineValidPosition())...
or better, inverse them..if(lockPopup || !_determineWhaterver()) return;
and then the rest of the code can follow without being nested. \$\endgroup\$