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.
Related
This is my function and it should change the onClick attribute of the HTML input, but if I use
document.getElementById('buttonLED'+id).onclick = "writeLED(1,1)";
it does not work at all, but if I use
document.getElementById('buttonLED'+id).onclick = writeLED(1,1);
the function executes by itself!
Any ideas what code do I have to use to change the onCLick attribute WITHOUT executing the function, before the button is clicked?
Here is the full function, if it matters:
function showLED(id){
if(color == 0){
document.getElementById('buttonLED'+id).onclick = "writeLED(1,1)";
document.getElementById('buttonLED'+id).value="light is on";
//document.getElementById('buttonLED'+id).disabled = false;
}else{
document.getElementById('buttonLED'+id).onclick = "writeLED(1,0)";
document.getElementById('buttonLED'+id).value="light is off";
//document.getElementById('buttonLED'+id).disabled = false;
}
}
Well, just do this and your problem is solved :
document.getElementById('buttonLED'+id).setAttribute('onclick','writeLED(1,1)')
Have a nice day XD
You want to do this - set a function that will be executed to respond to the onclick event:
document.getElementById('buttonLED'+id).onclick = function(){ writeLED(1,1); } ;
The things you are doing don't work because:
The onclick event handler expects to have a function, here you are assigning a string
document.getElementById('buttonLED'+id).onclick = "writeLED(1,1)";
In this, you are assigning as the onclick event handler the result of executing the writeLED(1,1) function:
document.getElementById('buttonLED'+id).onclick = writeLED(1,1);
The line onclick = writeLED(1,1) means that you want to immediately execute the function writeLED(arg1, arg2) with arguments 1, 1 and assign the return value; you need to instead create a function that will execute with those arguments and assign that. The topmost answer gave one example - another is to use the bind() function like so:
var writeLEDWithSpecifiedArguments = writeLED.bind(this, 1,1);
document.getElementById('buttonLED'+id).onclick = writeLEDWithSpecifiedArguments;
Using Jquery instead of Javascript,
use 'attr' property instead of 'setAttribute'
like
$('buttonLED'+id).attr('onclick','writeLED(1,1)')
You are not actually changing the function.
onClick is assigned to a function (Which is a reference to something, a function pointer in this case). The values passed to it don't matter and cannot be utilised in any manner.
Another problem is your variable color seems out of nowhere.
Ideally, inside the function you should put this logic and let it figure out what to write. (on/off etc etc)
Another solution is to set the 'onclick' attribute to a function that returns your writeLED function.
document.getElementById('buttonLED'+id).onclick = function(){ return writeLED(1,1)};
This can also be useful for other cases when you create an element in JavaScript while it has not yet been drawn in the browser.
First we'll select the required button using query selector and for all the selected buttons we'll set the onclick attribute with a function that needs to be called by clicking on the buttons.
You can write the code for required work you want to do by clicking the button in the function defined.
Well "One of the" generalized solution to your to your problem can be achieved by the following code:
var a=document.querySelectorAll('button');
for(b=0;b<a.length;b++)
{
a[b].setAttribute("onclick","check("+b+")");
}
function check(e)
{
var sa=a[e].innerHTML;
console.log('working onclick',sa);
}
When dynamically creating an element of type select, there are two problems when setting the onclick method:
It is impossible to simply set the onclick with element.onclick="updateInput(this.articleIndex)";
This results in a final HTML tag where no onclick is shown at all.
When set by e.setAttribute("onclick","updateInput(this.articleIndex)");, it does appear in the final HTML. And the updateInput method does get called.
However the functionality seems to be broken, as the argument always evaluates to undefined
Here a simple example of my problems:
var selectElem = document.createElement("select");
selElem.id="articleSelector_"+this.articleIndex;
console.log("the index of the article is " + this.articleIndex);
selElem.setAttribute("onclick","updateInput(this.articleIndex);");
//selElem.onclick="updateInput(this.articleIndex)"; //this does not work
The log shows the correct number. Inside the updateInput method, the argument is of value undefined instead of the number previously shown in the log.
Try attaching handlers with pure Javascript, and not with HTML, without onclick = "... (which is as bad as eval).
The this in your script refers to the calling context of the function - what is it?
You might want:
element.addEventListener('click', () => {
updateInput(this.articleIndex);
});
(arrow functions retain the this of their surrounding scope)
it is impossible to simply set the onclick with element.onclick="updateInput(this.articleIndex)";
What that code does is it assigns the string "updateInput(this.articleIndex)" to the onclick which makes no sense and certainly not what you want.
Even if you remove the quotes:
element.onclick = updateInput(this.articleIndex);
It is still incorrect because it assigns the result of the updateInput() function to the onclick which is again not what you want.
You need to assign a function name to the onclick like this:
element.onclick = updateInput;
However, this doesn't allow you to pass a parameter as you wish. To do so, you need to use an anonymous function:
element.onclick = function() {
updateInput(this.articleIndex)
};
When set by e.setAttribute("onclick","updateInput(this.articleIndex)");, it does appear in the final HTML. And the updateInput method does get called.
This works because it sets the attribute onclick and it is a string type, so everything is correct. It is equivalent to using the anonymous function above. The only difference is this, which in this case refers to the element itself, while in the above code it depends on the context that the code appears in. That's why in this case the argument always evaluates to undefined because the select element doesn't have an articleIndex property.
The problem is the value of the context this when that element is clicked, the context this is not available anymore at that moment.
You have two ways to solve this problem:
You can use the function addEventListener to bind the event click, and bind the function/handler with the desired context this:
The function bind binds a specific context to a function.
selElem.addEventListener('click', updateInput.bind(this));
function updateInput() {
console.log(this.articleIndex);
}
As you need a specific value, you can use data attributes. That way, you don't need to worry about the context this.
selElem.dataset.articleIndex = this.articleIndex;
selElem.addEventListener('click', function() {
updateInput(this.dataset.articleIndex); // Here you can get that value.
});
So I am trying to remove my addEventListener function using the removeEventListener function. I've read alot about it needing to include an handler function, which I have done.
One of the issues is that I am running into is that I would like to remove the eventlistener when I change an input using google's searchbox. Don't mind google but really all what is happening is it is identifying when the input value has changed and providing new results. So a bit of code
var input = document.getElementById('search-input');
var searchBox = new google.maps.places.SearchBox(input);
google.maps.event.addListener(searchBox, 'places_changed', locationChange);
function previousButtonFunction(){
//Does something here and does not return anything. Lets just say it places markers all over the map
}
function locationChange() {
var previousButton = document.getElementById('previous');
previousButton.removeEventListener('click', previousButtonFunction());
previousButton.addEventListener('click', function () { previousButtonFunction()})
};
So this code looks like it doesn't make any sense to you probably, but what I am trying to get is that on the first input it would run the add event listener, and not run the removeEventListener function. Once the value of input has changed, I would like to remove the current listener and re-identify the previousButton with a new addeventlistener.
At the first go, I realize that the function of previousButtonFunction() is run, which I thought that it would only run if there was an identified listener. So the first question is the removeEventListener function supposed to run if the eventlistener wasn't added? Second how can I remove the addEventListener without running the function? Would I need to pass in a tracking identifier such as true => run it/false => don't run?
Thanks any help is greatly appreciated
Don't use ()after the function name. You want to pass only a reference to the function. Putting() after the name calls the function and passed the return value. This is a very common mistake.
Change this:
previousButton.removeEventListener('click', previousButtonFunction());
to this:
previousButton.removeEventListener('click', previousButtonFunction);
The same goes for .addEventListener(). Don't put () after the function name unless the function returns another function that you want to be the listener.
FYI, it's a little unclear why you're attempting to remove and then add back the same exactly same listener function. Unless there are multiple listeners on that object and you're trying to change the order of listeners, this is essentially a noop.
I'm new to both javascript and jquery, and I'm having a small problem. It is happening with both the latest versions of Chrome and Firefox, so I don't think it's a browser issue.
Relevant code is here (this is a self-invoking function inside script tags on the HTML page).
(function () {
"use strict";
var submitbutton = $('#submitcommand'),
textinput = $('#textinput'),
userinput = textinput.val();
submitbutton.on('click', function() {
alert("textinput is " + textinput.val()); // => works
alert("userinput is " + userinput); // => undefined
});
}());
The first call to alert() works just fine, using 'textinput.val()'. The second call to alert() doesn't return any visible text, because 'userinput' is evaluating to 'undefined'.
I've tried going into the Firebug Console and pasting the four statements (the two assignments and the two calls to alert()) in, one after the other. That works, and gets me the result I expect.
So the question is: what changes about the 'userinput' variable inside the on('click') function? What am I not seeing here?
Thanks in advance!
As the function is self invoking, the variable will be set at page load. It is not reassessed every time the button is clicked. During page load you will probably find that:
The input is emtpy
The input is lower down the page than the script (More probable I think)
So at the time of setting there is no value. You probably want to make the variable scoped to the button click:
(function () {
"use strict";
var submitbutton = $('#submitcommand'),
textinput = $('#textinput')
submitbutton.on('click', function() {
var userinput = textinput.val();
alert("textinput is " + textinput.val()); // => works
alert("userinput is " + userinput); // => undefined
});
}());
Also, you will want to make sure the script block is at the bottom of the page, as then all the UI elements will be loaded in the browser when the function is invoked.
Your value is undefined inside the handler.
You should perhaps use it this way:
(function() {
"use strict";
var submitbutton = $('#submitcommand'),
textinput = $('#textinput')
userinput = textinput.val();
submitbutton.on('click', function() {
userinput = textinput.val();// sets the value in the handler
alert("textinput is " + textinput.val());
alert("userinput is " + userinput);
});
}());
working example:http://jsfiddle.net/avCay/
Note that this works this way due to the scope of the variable and the "reset" of the values inside the event handler. The first pass parses the script, the second executes it, and the subsequent event handler fires on the click event of the submitbutton element, setting the value at that point during that event.
EDIT: NOTE: regarding the jQuery read/load wrap (as in my example fiddle) if you wish to NOT have that, you can do:
$('#submitcommand').on('click', function() {
instead of the variable and jQuery will properly hook the event handler to the element.
EDIT2: or perhaps this will provide more insight here. If you do:
You will still need to re-access the variable however if you wish to have the "current" value of the input, not that in the "undefined" state during the initial execution due to the parse/execute cycle of the Javascript. The "re-access" of the .val(); vs the value during the initial script execution is the key to that "undefined" value. and setting it "inside" the handler gets the current value.
When
var userinput = textinput.val()
is evaluated:
textinput may not exist yet - you must be either in a document.ready() handler or the <script> block must be after #textinput in the DOM.
if it does exist, userinput gets its current value, not any future value it may happen to have.
This is because the value of #textinput is empty on page load (unless you set the value to something when the page loads). So the stored value in userinput is empty. When you read the value from textinput inside the event handler, it looks up the value of the input-field.
Makes sense? :)
I'm having a weird problem with some JavaScript/DOM code I've been playing with. I'm trying to assign the .onKeyUp and .onChange events/methods to a text input like so:
form.elements["article"].onkeyup = "alert('test');";
Oddly, assigning using that method is doing nothing, and I'm forced to do this manually using:
form.elements["article"].setAttribute("onkeyup", "alert('test');");
Am I missing something here? I've used the first method I mentioned before and it has worked fine.
Try this:
form.elements["article"].onkeyup = function() { alert("test"); };
Steve
You need to assign a function, not a string. For example:
form.elements["article"].onkeyup = function(){alert('test');};
The only things I know that will take a string and eval it (other than eval) are setTimeout and setInterval.