1) If you want to make a form, make a form. Where's your FORM tag?
2) don't intercept the submit button, intercept the submit on the form.
3) the LABEL's "for" attribute is supposed to point at an ID on the input it is "for". You have no such input.
4) Where's your fieldset to mark the difference between user-changeable fields and your labelless?
5) querySelector should be unnecessary, and you seem to be getting a lot of elements you don't need to.
6) You want to style something, do it from your stylesheet, not the JavaScript.
Proper semantics for such a form would go something like this:
<form id="login" method="post" action="#">
<h1>Login</h1>
<fieldset>
<label for="login_name">Enter Name:</label>
<input type="text" name="name" id="login_name">
<button>Submit</button>
</fieldset>
</form>
That way you have something that will work scripting off. You then enhance it with scripting intercepting the form's submit event.
/*
I put this in a SIF (self instancing function, also known as
a IIFE -- immediately invoked function expression) so that
anything this script does is isolated from other scripting
on the site.
I pass 'document' as 'd' as it runs a hair faster and makes
the code a bit less unweildy. Simple trick I picked up from
Google's various codebases. Good enough for the Goog, good
enough for the rest of us.
*/
(function(d) {
var
loginForm = d.getElementById('login'),
loginName = d.getElementById('login_name'),
output = loginForm.appendChild(d.createElement('p'));
output.id = 'loginOutput';
loginForm.addEventListener('submit', function(e) {
e.preventDefault(); // prevent the scripting off action=""
output.textContent = 'Welcome ' + loginName.value;
});
})(document);
I would load that from an external file (static scripting has no business in your HTML) right before </body> -- by which time the DOM is built so you can skip all the "onload" stuff Aaron Artille outlined. Loading your scripts right before </body> most of the time means you can stop playing with onload, or that ASYNC nonsense, and has the interesting side effect of making the page load faster. Placing the SCRIPT tag into the HEAD is an outdated, outmoded way of working with JS.
I also built the output on the DOM since as a scripting only element it too has no business in the markup.
Live demo here: cutcodedown.com/for_others/SalamiAdewale
Hope that helps.
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.