Salami Adewale Let's see if we can clarify some of this for you.
In regards to putting the script right before the closing body tag, i read its a bad practice as we might sometimes require some script to run before the DOM finish loading which might cause some inconsistency.
I'd be interested in knowing where you heard that, as that's the opposite of every bit of good advice I've heard on the topic. In fact the idea of wanting something run before the markup DOM is complete runs contrary to pretty much anything and everything people do -- or even should be doing -- with JavaScript. I can conceive of nothing I would want to do with JS before the markup DOM is complete. Nothing, nada, zip, zilch. I loads faster, it solves so many problems, I don't see how or why anyone would put scripting into the HEAD anymore other than twenty year out of date practices.
But what do I know, IMHO class="text-large box-shadow col-4-s" is two decades out of date in mentality.
I would suspect someone who thinks they know what they are doing -- but doesn't -- told you that.
however, i got confused at the last part when you passed document into the ()
That construct is called a SIF (self instancing function) or IIFE (Immediately invoking function expression). It's basically an anonymous function that calls itself. Pay attention to the extra () here.
( function(test) { console.log(test) } )('snafu tarfu fubar');
When you ()(); in JavaScript the first () becomes an instance of whatever is inside it, so if you pass it a function -- which is also an object -- it becomes that object. As the function has no name it is anonymous, not dirtying up our global namespace. As the first () is now that function as a callable instance, we can ()(parameters) to pass anything we like to that function.
So basically:
(function(d, w) {
// we can use d for document and w for window here
})(document,window);
is the same as declaring:
function whatever(d, w) {
// we can use d for document and w for window here
}
whatever(document, window);
... except we don't pollute the global namespace with a function name.
It's a pretty common construct. As I mentioned in the code comments even Google uses it on their analytics and adsense scripts.
Also, where you intercepted the submit on the form instead of the button looks confusing to me. I really didn't see where the button was made to respond on the code but somehow, it worked.
That's because it's not intercepting the button. It's intercepting the form's submit event.
There are many different ways to submit an HTML form, many of which have nothing to do with your submit buttons or inputs. In fact a form can have multiple different submits!
A cute trick for testing forms is to set the method to "get" and the href to "#" as then you can see in the address bar what is being returned. Try out this code:
<form action="#" method="get">
<input type="text" name="text">
<button name="first" value="1">First</button>
<button name="second" value="1">Second</button>
<button name="third" value="1">Third</button>
</form>
When you click the first one you get just "?first=1#" as the URI. The second one gives just "?second=1#", and the third one just "?third=1#". The other values are not submit. Now go to the input and hit CTRL+Enter. On some browsers it will trigger the first button to submit -- but on some other browsers it won't trigger ANY of the buttons leaving the URI as just "#"!
ALL of them are submitted through the same FORM element, which is what you in most cases would want to intercept so you always grab all submit attempts regardless of what element the submit came from. This dodges the bullet of some alternative navigation skipping right past your submit button, catches all possible submit methods, etc, etc.
Basically there's a chain of events that happen in a well formed HTML form -- one of those is that when you hit the submit BUTTON (or INPUT type="submit") it is supposed to cascade upwards to submit the FORM tag. As such good practice is to intercept it at the FORM, not the button/submit/keyboard/mouse/mouth stick/pedals/tapper/however else the user is doing it. There are dozens of possible devices and possibilities by which a form can be submit -- intercepting FORM.onsubmit nabs all of them in one place.
Hence why having a FORM around it is important even if not sending server-side... though really in most cases you should be attempting to make a working page client and server side before you start trying to throw scripting at things. This is someplace a lot of developers these days are screwing up, and it's telling a lot of potential users to sod off in the process!
There's a saying that's gone around the past twenty years or so that I heartily endorse:
Good scripting should enhance an already working page. If you cannot make a fully functional semantic accessible page without client-side JavaScript first, you likely have zero business adding scripting to it.
Sadly right now a lot of people spew out endless lame excuses not to do so these days. Screws over a lot of people just starting out with bad advice and worse practices.