As a very novice developer, I'm reading more about OOP and structuring JavaScript in a sensible way and have been using the following format for a little while now. It's difficult to know the best way to do things because most examples I see online are for much larger websites than I currently build. More like applications than websites, spanning multiple files and thousands of lines of code, where as mine is just in a single JS file spanning around 1k lines at most. I'm also using jQuery on each project and most things don't use a library like this, or they're based around Angular, etc.
jQuery(document).ready(function($){
Site.init();
});
var Site = (function($) {
// ================ !CACHING COMMON VARS
// Aliased Variables
var cfg, throttle, helper, loader;
// DOM caching
var $win = $(window),
$doc = $(document);
// Globals
var w = {
width: $win.width(),
height: $win.height(),
scroll: $doc.scrollTop()
}
return {
// ================ !SCOPE SETTINGS
settings: {
speed_fast: 300,
speed_slow: 600,
easing: [0.55, 0, 0.1, 1] // SwiftOut (Google Material Design)
},
// ================ !SITE
init: function() {
// Aliases
cfg = this.settings;
throttle = this.handlers.throttle;
helper = this.helpers;
loader = this.handlers.loader;
// ================ !SITEWIDE FUNCTIONS
// Form validation & ajax
this.formProcess();
// ================ !SPECIFIC FUNCTIONS
// Share Popups
helper.check('.js-social-share', this.sharePopup);
},
// ================ !EVENT-HANDLERS
handlers: {
// Throttle resize and scroll events
throttle: function(handler, func) {
var eventHappend = false,
throttleOps = {};
throttleOps[handler] = function(){
eventHappend = true;
}
$win.on(throttleOps);
setInterval(function() {
if ( eventHappend ) {
eventHappend = false;
if (handler === 'resize') {
window_width = $win.width();
window_height = $win.height();
}
if (handler === 'scroll') {
scroll_top = $doc.scrollTop();
}
func();
}
}, 250);
},
loader: function(func) {
$win.on('load', func);
}
}, // End Handlers
// ================ !HELPER/UTILITY FUNCTIONS
helpers: {
// Get a random Num between min and max
getRandom: function(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
},
// Check if element exists and run function
check: function(el, func) {
if ($(el).length) {
func();
}
}
}, // End Helpers
// ================ !SITEWIDE FUNCTIONS
// Open Share popups in new window
sharePopup: function() {
$('.js-social-share a').on('click', function(){
if ($(this).attr('href').indexOf('http') === 0) {
var newwindow = window.open($(this).attr('href'), '', 'height=450, width=700');
if (window.focus) {
newwindow.focus();
}
return false;
}
});
}, // End sharePopup()
// ================ !SPECIFIC FUNCTIONS
// Process Forms.
formProcess: function() {
var $forms = $('.js-process-form');
// Make sure forms are valid (using jQuery Validate)
$forms.each(function(){
$(this).validate({
ignore: '',
rules: {
upload: {
required: true
}
},
onfocusout: function(element) {
this.element(element);
},
onkeyup: false
});
});
// On submit do Ajax post
$forms.on('submit', function(e){
e.preventDefault();
var $this = $(this);
if ($this.valid()) {
// Uses site object from Worpress
$.ajax({
url: WP.base_dir+"/wp-admin/admin-ajax.php",
type:'POST',
data: $.extend({
action: 'contact_email'
}, $this.serializeObject()),
dataType: 'json',
success: function(data){
//Access the returned JSON
$this.html('<h1>' + data.message + '</h1>');
}
});
}
});
}, // End formProcess()
}; // End return Site
})(jQuery);
Main things that are bothering me are:
- Are things enclosed correctly? (so as to not conflict with anything another dev might add in to the domready)
- Are the event handlers/checkers even efficient?
- Am I doing anything glaringly wrong?
There are a few things that are included elsewhere, so don't worry about something that is referenced but not in the script. I've included a couple of example functions in there as I would normally use them.