Programming Question First (from w3 schools)
The programming example way below (from W3 schools) is nice and easy, it works on their website but I'm really confused on something.
onkeypress="return noNumbers(event)"
why is there a return before the function? What does it do? If you know the answer to that - how did you find out that information? My guess would be, that it allows the keypressed function to continue processing the keystroke since my event "interupted" it?
also - I have been trying to see what 'event' is. It doesnt seem to be a keyword. I spent > hour trying to find what it is. It doesnt seem to be assigned anywhere in their code example. Normally in that spot you would see 'this'. If it's a not assigned variable will it always pass the event handler? Confused...
What I want to do with their function
I want to make a password strength checker AS you type. I was looking at their example so I could figure out how to capture keys (cross browser and minimal IE7). My idea was...
<input type="password" name="pword" maxlength="50" size="50" id="field_pword" onkeyup="PasswordStrength(name, 8, 'relaxed')" onblur="CheckField(name, 8, 1)">
note: Yes, I know it's better to assign event handlers outside of the html but I couldn't see a way to pass variables to it unless it was inline. I'm a novice so I may have overlooked something but... thats why I do it IN the HTML.
also, IS IT BAD how I am passing name? it does send pword to the function but am I doing something wrong there? Should I just make it a constant string? It works as is, but sometimes just because something works... doesn't mean it's correct. :)
onkeyup="PasswordStrength('pword', 8, 'relaxed')" onblur="CheckField('pword', 8, 1)">
My checkfield function works (I use it after every field) I recently added in PasswordStrength. My question is... my new function isn't passing the event hander so how can I check what key is pressed? Can I do this?
onkeyup="PasswordStrength(name, 8, 'relaxed', event)"
or should it read...
onkeyup="return PasswordStrength(name, 8, 'relaxed', event)"
If I can't pass whatever 'event' is that way, inside my function can I accurately get what the key pressed was without a big mess of code? Since I'm learning I need examples to be as simple as possible (please).
Using my function I was going to do it this way but I still don't know how to get what key was pressed...
function PasswordStrength(sField, iMinLength, sStrength, e?)
{
var form = document.forms[0];
var gc = form[sField].value;
// once I have the value I can do checking but it would be nice to have WHAT key
// was pressed
// the e? above is where I was thinking of passing the event
W3 example I was pulling some knowledge from...
function noNumbers(e)
{
var keynum;
var keychar;
var numcheck;
if(window.event) // IE
{
keynum = e.keyCode;
}
else if(e.which) // Netscape/Firefox/Opera
{
keynum = e.which;
}
keychar = String.fromCharCode(keynum);
numcheck = /\d/;
return !numcheck.test(keychar);
}
</script>
<form>
Type some text (numbers not allowed):
<input type="text" onkeypress="return noNumbers(event)" />
</form>
</body>
</html>
As someone is typing I was going to change the text using innerHTML beside the password field to say, "Weak", "Ok", "Good", "Perfect" or something along those lines for the password status. I'd love to do it how google does it with a graphic to the left of the field but I don't know how to do that simply. lol.
Is my way fixable? Do you have a better way to do this that I don't know about? Much appreciated. Awaiting an infusion of wisdom...
Just to your first programming questions:
Your suggestion is right, to return a value inside of an event
lets you interrupt the action depending on the values content. Returning false inside onclick
will end in the click not to be done. So <a href="http://test.de"
onclick="return false;">linkname</a> wont link you to anything if
JavaScript is active.
event is simply a variable declared before it runs into the actual event, further explanation below.
You know the elements eventhandler attributes in JavaScript?
They are functions i.e.
document.createElement('div').onclick = function( event ){
//do something...
return true || false;
};
if you assign an onclick attribute to a tag it's simply another adjusted way to create this anonymous function. So
<input onclick="this.value = 'can\'t click me :P Mouse X: ' + event.clientX; return false;" type="text" id="ip" />
will behave as if you created an anonymous function taking the argument event.
window.onload = function(){
document.getElementById('ip').onclick = function( event ){
this.value = 'can\'t click me :P Mouse X: ' + event.clientX; return false;
};
};
This will behave exactly equal except of the delayed assignment.
The this keyword is always the owner object whose property function you're accessing or the object you're passing to an apply/call method. In this case it's obviously the owner - the DOM element. So this.value is the inputs value.
The event passed to the function is just an object containing some useful information about the current browsers state and miscellaneous. It's having slightly different properties filled with different values in different browsers but the main functionality is the same everywhere.
As explained above it makes no difference whether you write what you did or this:
window.onload = function(){
var yourElement = document.getElementsByTagName('pword')[0];
yourElement.onkeyup = function( event ){
PasswordStrength(this.name, 8, 'relaxed')
};
};
No it's not really bad to use just name.. whenever you access a property of the owners object you can omit the this keyword. Thus it's simply the same conflict as the one about writing
<script type="text/javascript">//<![CDATA[
onload = function(){ alert('hello!') };
//]]></script>
instead of window.onload or this.onload or even this.window.onload (which are all theoretically working since the everything containing object has a property named window which refers to itself). You could say it's a matter of convention. But since the convention to always access own properties over the this keyword (except for window which you should access over its property window) is strongly established and supported, you probably should write this.name.
That depends on whether you want to eventually interrupt the event and don't let the user finish his keyup. Explained above.
Why shouldn't you be able to pass the event object? Just treat it like a normal variable.
Combining the information above and the example in your question you should be able to get knowledge about which key was pressed.
1) The "return" word makes it so that if the function returns false, that gets passed back to the event and stops the keystroke from being processed by the browser (and appearing in the input field if that's what the event is on).
2) event is the Event object, which contains information on the event such as what key wa pressed, where the event was fired, etc.
3) Yes, it is bad how you are passing name, because you aren't passing it. Use this.name instead.
4) In this case, you don't need return because you aren't trying to stop a keystroke from being added to the textbox. Similarly, you don't need to pass event because you can pass this.value to get the contents of the textbox.
5) You can just pass this instead of this.name, this.value or whatever other values.Then, in the function, get the properties from the single argument.
6) Once you pass the entire value with this.value, you can run your tests on that. There is absolutely no need to know what key was pressed, especially as things like Ctrl+V would completely screw you over.
7) You can have a <div> and change its width and/or background colour to make a sort of strength bar indicator.
Related
I'm currently following a tutorial about Javascript events. Basically, what the instructor is walking us through is how to listen to user input data from the HTML input tag using the keyup Javascript event and then logging the value on the console.
Here's the code snippet:
document.getElementById("searchInput").addEventListener("keyup", function(event) {
let searchQuery = event.target.value.toLowerCase();
console.log(searchQuery);
});
It's straightforward, however, I'm curious about the significance of adding the event parameter and accessing the target property of such event. I went ahead and removed the event parameter, as well as the target property, and made it so as to log the value, too, and, as far as I am aware, it behaved identically.
document.getElementById("searchInput").addEventListener("keyup", function () {
let searchQuery = document.getElementById("searchInput").value.toLowerCase();
console.log(searchQuery);
});
Is there a unique reason why the instructor chose to do the former or is it simply for brevity reasons?
It’s useful if you want to write a more general function that would work with whatever element you pass into it. Currently you are specifying the id of the element you’d like to access within the function. But at some point you may want to write a function that you can reuse with multiple elements at once, this is where event.target comes in.
I am new to JavaScript/jQuery and I've been learning how to make functions. A lot of functions have cropped up with (e) in brackets. Let me show you what I mean:
$(this).click(function(e) {
// does something
});
It always appears that the function doesn't even use the value of (e), so why is it there so often?
e is the short var reference for event object which will be passed to event handlers.
The event object essentially has lot of interesting methods and properties that can be used in the event handlers.
In the example you have posted is a click handler which is a MouseEvent
$(<element selector>).click(function(e) {
// does something
alert(e.type); //will return you click
}
DEMO - Mouse Events DEMO uses e.which and e.type
Some useful references:
http://api.jquery.com/category/events/
http://www.quirksmode.org/js/events_properties.html
http://www.javascriptkit.com/jsref/event.shtml
http://www.quirksmode.org/dom/events/index.html
http://www.w3.org/TR/DOM-Level-3-Events/#event-types-list
DISCLAIMER: This is a very late response to this particular post but as I've been reading through various responses to this question, it struck me that most of the answers use terminology that can only be understood by experienced coders. This answer is an attempt to address the original question with a novice audience in mind.
Intro
The little '(e)' thing is actually part of broader scope of something in Javascript called an event handling function. Every event handling function receives an event object. For the purpose of this discussion, think of an object as a "thing" that holds a bunch of properties (variables) and methods (functions), much like objects in other languages. The handle, the 'e' inside the little (e) thing, is like a variable that allows you to interact with the object (and I use the term variable VERY loosely).
Consider the following jQuery examples:
$("#someLink").on("click", function(e){ // My preferred method
e.preventDefault();
});
$("#someLink").click(function(e){ // Some use this method too
e.preventDefault();
});
Explanation
"#someLink" is your element selector (which HTML tag will trigger this).
"click" is an event (when the selected element is clicked).
"function(e)" is the event handling function (on event, object is created).
"e" is the object handler (object is made accessible).
"preventDefault()" is a method (function) provided by the object.
What's happening?
When a user clicks on the element with the id "#someLink" (probably an anchor tag), call an anonymous function, "function(e)", and assign the resulting object to a handler, "e". Now take that handler and call one of its methods, "e.preventDefault()", which should prevent the browser from performing the default action for that element.
Note: The handle can pretty much be named anything you want (i.e. 'function(billybob)'). The 'e' stands for 'event', which seems to be pretty standard for this type of function.
Although 'e.preventDefault()' is probably the most common use of the event handler, the object itself contains many properties and methods that can be accessed via the event handler.
Some really good information on this topic can be found at jQuery's learning site, http://learn.jquery.com. Pay special attention to the Using jQuery Core and Events sections.
e doesn't have any special meaning. It's just a convention to use e as function parameter name when the parameter is event.
It can be
$(this).click(function(loremipsumdolorsitamet) {
// does something
}
as well.
In that example, e is just a parameter for that function, but it's the event object that gets passed in through it.
The e argument is short for the event object. For example, you might want to create code for anchors that cancels the default action. To do this you would write something like:
$('a').click(function(e) {
e.preventDefault();
}
This means when an <a> tag is clicked, prevent the default action of the click event.
While you may see it often, it's not something you have to use within the function even though you have specified it as an argument.
In jQuery e short for event, the current event object. It's usually passed as a parameter for the event function to be fired.
Demo: jQuery Events
In the demo I used e
$("img").on("click dblclick mouseover mouseout",function(e){
$("h1").html("Event: " + e.type);
});
I may as well have used event
$("img").on("click dblclick mouseover mouseout",function(event){
$("h1").html("Event: " + event.type);
});
Same thing!
Programmers are lazy we use a lot of shorthand, partly it decreases our work, partly is helps with readability. Understanding that will help you understand the mentality of writing code.
Today I just wrote a post about "Why do we use the letters like “e” in e.preventDefault()?" and I think my answer will make some sense...
At first,let us see the syntax of addEventListener
Normally it will be:
target.addEventListener(type, listener[, useCapture]);
And the definition of the parameters of addEventlistener are:
type :A string representing the event type to listen out for.
listener :The object which receives a notification (an object that implements the Event interface) when an event of the specified type
occurs. This must be an object implementing the EventListener
interface, or a JavaScript function.
(From MDN)
But I think there is one thing should be remarked:
When you use Javascript function as the listener, the object that implements the Event interface(object event) will be automatically assigned to the "first parameter" of the function.So,if you use function(e) ,the object will be assigned to "e" because "e" is the only parameter of the function(definitly the first one !),then you can use e.preventDefault to prevent something....
let us try the example as below:
<p>Please click on the checkbox control.</p>
<form>
<label for="id-checkbox">Checkbox</label>
<input type="checkbox" id="id-checkbox"/>
</div>
</form>
<script>
document.querySelector("#id-checkbox").addEventListener("click", function(e,v){
//var e=3;
var v=5;
var t=e+v;
console.log(t);
e.preventDefault();
}, false);
</script>
the result will be : [object MouseEvent]5 and you will prevent the click event.
but if you remove the comment sign like :
<script>
document.querySelector("#id-checkbox").addEventListener("click", function(e,v){
var e=3;
var v=5;
var t=e+v;
console.log(t);
e.preventDefault();
}, false);
</script>
you will get : 8 and an error:"Uncaught TypeError: e.preventDefault is not a function
at HTMLInputElement. (VM409:69)".
Certainly,the click event will not be prevented this time.Because the "e" was defined again in the function.
However,if you change the code to:
<script>
document.querySelector("#id-checkbox").addEventListener("click", function(e,v){
var e=3;
var v=5;
var t=e+v;
console.log(t);
event.preventDefault();
}, false);
</script>
every thing will work propertly again...you will get 8 and the click event be prevented...
Therefore, "e" is just a parameter of your function and you need an "e" in you function() to receive the "event object" then perform e.preventDefault(). This is also the reason why you can change the "e" to any words that is not reserved by js.
It's a reference to the current event object
this will be my first stackoverflow help but I am confident that my answer will help anyone reading this.
Basically, e is just an object containing information about the EVENT which has just occured.
if it is 'click', then the object will contain about the click,
if it is 'submit', then the object will contain about the submit,
and they are typically found in addEventListener.
clickMe.addEventListener('click', e => {
console.log(e)
}
meaning, whenever I 'click' the button, it will console.log the INFOMRATION about the event that happened which is I did is to 'click' it, this will print information about the click event.
e is very useful because you can access and use the event to your very own project such as printing the location of x value... like
clickMe.addEventListener('click', e => {
console.log(e.clientX)
}
then it will print the location where you 'click' that event.. mine it returns 32
if you prefer video, please watch this
https://www.youtube.com/watch?v=_BVkOvpyRI0
video is not mine
upvoting me will truly help me since I am a student and looking for opportunity to help here. Love lots!
$(this).click(function(e) {
// does something
});
In reference to the above code
$(this) is the element which as some variable.
click is the event that needs to be performed.
the parameter e is automatically passed from js to your function which holds the value of $(this) value and can be used further in your code to do some operation.
I am attempting to call a javascript function on a webpage that contains the 'this' keyword which is referring to the <input> textbox on the webpage. The function looks like this:
functiondostuff('hdnAttribute',this,'Key')
Using
js = "functiondostuff('hdnAttribute',this,'Key')"
Call IE.Document.parentWindow.execScript(js)
doesn't throw an error but does not produce the results of the function since this cannot be identified.
Stepping through the website this = [object DispHTMLInputElement] instead of the element name while the function is running. Anyone have any ideas?
Good Morning,
Adding more to this issue. There seems to be two problems, 1st is setting the window.event, functiondostuff begins with: if (window.event && window.event.keyCode == 13), when the function is called it exits out immediately due to the event being null. Is there a way to pass the event as 13 to the website? The second issue is submitting the "this" HTMLInputObject.
Does anyone know a method to fire the 'onkeypress' event? I am at the point of trying sendkeys to avoid calling the function but have not been able to get them to work with IE. Thanks for any suggestions!
Key point is context. If you have this HTML
<input onclick="functiondostuff('hdnAttribute',this,'Key')">
then the browser can infer context from the user interaction and set this for you correctly.
From within VBA that's a slightly different matter and you have to define context manually.
How about this:
Dim js As Variant
js = Array( _
"var input = document.getElementById('yourElementsId');", _
"functiondostuff('hdnAttribute',input,'Key');" _
)
Call IE.Document.parentWindow.execScript(Join(js, vbNewLine))
This way you get to define context yourself.
document.getElementById was just for the sake of the example. If your element has no ID, use any other method (like DOM traversal, document.querySelectorAll, document.getElementsByTagName + a loop, ...) to get a reference to the desired element.
Is there a way to run a JavaScript function when a key is pressed and released?
For example, how would I run a function example() when the T key is pressed? I've seen examples of these before, but they were long and messy, and I couldn't get them to work. Would something like this just go in a <script> in the <head>?
Part 1: Where to put the scriptblock?
To capture over the entire page, like as a page-help-function (maybe you want to capture F1?) then you would put your script block in the <head> tag, inside a script. But if you want to capture a DOM element, then you have to execute the code after the DOM element occurs (because the script is interpreted as it's found, if the DOM element doesn't exist yet, the selector engine can't find it. If this doesn't make sense say something, and an article shall be found).
But here's something for you to consider: Good javascript programmer mentors today recommend all javascript be loaded at the end of the page. The only things you might want to load at the head of the document are libraries like jQuery, because those are widely cached, especially if you're using a CDN version of jQuery, as that generally tends to not impact load times.
So that answers the question of "where do I put the codeblock, in the <head>?": No. At the end.
Now, as to how to actually capture the keystroke, let's do it in three parts:
Part 2: Capturing all keyboard events on the window:
<html>
<head>
<title>blah blah</title>
<meta "woot, yay StackOverflow!">
</head>
<body>
<h1>all the headers</h1>
<div>all the divs</div>
<footer>All the ... ... footers?</footer>
<script>
/* the last example replaces this one */
function keyListener(event){
//whatever we want to do goes in this block
event = event || window.event; //capture the event, and ensure we have an event
var key = event.key || event.which || event.keyCode; //find the key that was pressed
//MDN is better at this: https://developer.mozilla.org/en-US/docs/DOM/event.which
if(key===84){ //this is for 'T'
doThing();
}
}
/* the last example replace this one */
var el = window; //we identify the element we want to target a listener on
//remember IE can't capture on the window before IE9 on keypress.
var eventName = 'keypress'; //know which one you want, this page helps you figure that out: http://www.quirksmode.org/dom/events/keys.html
//and here's another good reference page: http://unixpapa.com/js/key.html
//because you are looking to capture for things that produce a character
//you want the keypress event.
//we are looking to bind for IE or non-IE,
//so we have to test if .addEventListener is supported,
//and if not, assume we are on IE.
//If neither exists, you're screwed, but we didn't cover that in the else case.
if (el.addEventListener) {
el.addEventListener('click', keyListener, false);
} else if (el.attachEvent) {
el.attachEvent('on'+eventName, keyListener);
}
//and at this point you're done with registering the function, happy monitoring
</script>
</body>
</html>
Part 3: Capturing all keyboard events on a specific element
This line: var el = window; //we identify the element we want to target a listener on might also be var el = document.getElementByTagName('input'); or some other document selector. The example still works the same that way.
Part 4: An 'elegant' solution
var KeypressFunctions = [];
KeypressFunctions['T'.charCodeAt(0)] = function _keypressT() {
//do something specific for T
}
KeypressFunctions['t'.charCodeAt(0)] = function _keypresst() {
//do something specific for t
}
//you get the idea here
function keyListener(event){
//whatever we want to do goes in this block
event = event || window.event; //capture the event, and ensure we have an event
var key = event.key || event.which || event.keyCode; //find the key that was pressed
//MDN is better at this: https://developer.mozilla.org/en-US/docs/DOM/event.which
KeypressFunctions[key].call(); //if there's a defined function, run it, otherwise don't
//I also used .call() so you could supply some parameters if you wanted, or bind it to a specific element, but that's up to you.
}
What does all this do?
The KeypressFunctions is an array, that we can populate with various values but have them be somewhat human readable. Each index into the array is done as 'T'.charCodeAt(0) which gives the character code (event.which || event.keyCode look familiar?) for the index position into the array that we're adding a function for. So in this case our array only has two defined index-values, 84 (T) and 116 (t). We could've written that as KeypressFunctions[84] = function ... but that's less human-readable, at the expense of the human-readable is longer. Always write code for yourself first, the machine is often smarter than you give it credit for. Don't try and beat it with logic, but don't code excessive if-else blocks when you can be slightly elegant.
gah! I forgot to explain something else!
The reason for the _keypressT and _keypresst is so that when this gets called as an anonymous function, or as part of a callstack (it will, one day) then you can identify the function. This is a really handy practice to get into the habit of, making sure that all potentially anonymous functions still get "named" even though they have a proper name elsewhere. Once again, good javascript mentors suggest things that help folks ;-).
gah! I forgot to explain something else!
Notice you could just as easily do:
function doThing() //some pre-defined function before our code
var KeypressFunctions = [];
KeypressFunctions['T'.charCodeAt(0)] = doThing
KeypressFunctions['t'.charCodeAt(0)] = doThing
and then for either T or t, the doThing function is run. Notice that we just passed the name of the function and we didn't try to run the function by doThing() (this is a HUGE difference and a big hint if you're going to do this sort of thing)
I can't believe I forgot this one!
Part 5: jQuery:
Because the emphasis today is on jQuery, here's a block you can put anywhere in your app after the jQuery library has loaded (head, body, footer, whatever):
<script>
function doTheThingsOnKeypress(event){
//do things here! We've covered this before, but this time it's simplified
KeypressFunctions[event.which].call();
}
$(document).on('keypress','selector',doTheThingsOnKeypress);
// you could even pass arbitrary data to the keypress handler, if you wanted:
$(document).on('keypress','selector',{/* arbitrary object here! */},doTheThingsOnKeypress);
//this object is accessible through the event as data: event.data
</script>
If you're going to use the KeypressFunctions as from before, ensure they are actually defined before this.
Use the onkeydown event and the keyCode property (where T code is 84):
document.onkeydown = function(e){
e = e || window.event;
var key = e.which || e.keyCode;
if(key===84){
example();
}
}
I just suggest you to use addEventListener/attachEvent methods instead of the onkeydown property
EDIT:
As T.J. Crowder requested, here's the addEventListener/attachEvent usage, with a compatibility check:
var addEvent = document.addEventListener ? function(target,type,action){
if(target){
target.addEventListener(type,action,false);
}
} : function(target,type,action){
if(target){
target.attachEvent('on' + type,action,false);
}
}
addEvent(document,'keydown',function(e){
e = e || window.event;
var key = e.which || e.keyCode;
if(key===84){
example();
}
});
And for a list of the key codes, check this page
Bind a keyup/down/press event handler to the document object.
Check which key was pressed (by looking at key or keyCode on the event object
Call the function if it matches the key want you want
It doesn't matter where the script runs, the document object is (effectively) always available.
I am trying to change the value of the onblur attribute of a text input after the page has finished loading.
When I do the following, it simply fires the function:
ip.onblur = stopCalcUpInt(this,10);
When I do the following, I have success:
ip.onblur = function onblur(event){stopCalcUpInt(this,10);}
Unfortunately, the whole point of this is to be able to dynamically set the second parameter for stopCalcUpInt(). If I hard code a value for it... it works fine... but any attempts to pass varibles to this fails... instead of putting the value of the variable as the second param it just puts the plain text of the variable name itself. Here is ideally what I am TRYING to do:
ip.onblur = function onblur(event){stopCalcUpInt(this,this.value);}
In this example, when I alert the ip.onblur I get:
It depends what this is intended to refer to. In an event handler this refers to the element on which the event is being handled. If that's what you want then your code looks good as written; this will point to ip.
If you intend this to refer to the this from outside the event handler and not ip then try this:
var self = this;
ip.onblur = function(event) { stopCalcUpInt(self, self.value); };
The answer to getting this to work was super easy, yet not overly obvious. Instead of:
ip.onblur = function onblur(event){stopCalcUpInt(this,this.value);}
I did this:
ip.setAttribute('onblur','stopCalcUpInt(this,\'' + ip.value + '\');');
Works perfectly... no more banging my head against the wall! Yay!
ip.onblur = function() {stopCalcUpInt(this,this.value);}
ip.onblur is an event handler... i.e. it's a function
Now, when you alert a function, FF will show you the source code for that function (if it's user defined).
That is why you're seeing the plain text of the variable name.
For an event handler, this is the element that is currently handling the event. So, if you're setting the onblur handler of an input box, you will have access to the contents of that input box.
The code sample that you provided:
ip.onblur = function onblur(event){stopCalcUpInt(this,this.value);}
should work correctly. Try
ip.onblur = function onblur(event){alert(this.value); stopCalcUpInt(this,this.value);}
if you want to be sure
Is stopCalcUpInt expecting a number in the second parameter? The value attribute will return a String, while in your hardcoded example you're passing a number type. Try this:
ip.onblur = function onblur(event){stopCalcUpInt(this,this.value * 1);}
As explained in QuirksMode:
Since multiplying assumes numbers,
JavaScript makes the string a number,
if possible.