I have following page:
<body>
foo
</body>
</html>
<script type="text/javascript">
function func(k){
alert(k);
$('#key').click(function() {func(++k)});
}
</script>
My expectations of this code execution following:
I click on link and see 0, then click one more time and see 1, then click one more time and see 2....then 3....4...5....6
But actual result:
I click on link and see 0,
I click on link and see 0 and then 1 twice,
I click on link one more time and see 0 2 2 2 2 and 1.
Please help to understand what does happen and and how to rewrite it?
Update
Key of the question is invocation of old function with new argument on onclick action!
you can set a global variable and increase in each function call
var globalCounter = 0;
$('#key').click(function() {
alert(globalCounter);
globalCounter++;
});
you dont need
onclick="func(0)"
in html tag because you already set click event handler with
$('#key').click(function(){});
You can simply modify your function as follows:
function func() {
if (!window.count)
window.count = 0;
alert(count++);
}
foo
Side notes:
You should add the <script> block inside your <html> document, preferably just before closing <body>
You are missing quotes around the id attribute
I rewrote function like this:
function func(k){
alert(k);
$("#key").removeAttr('onclick');
$("#key").unbind('click')
$('#key').click(function() {func(++k)});
}
and I see expected result
Currently, the inline click handler is setting k to 0 and adding a new jQuery click listener on every click. Each jQuery handler will increase the value of k on every click, and this creates a mess you can see in the alerted values.
At first, remove the inline onclick from #key. You can do it without breaking anything, just set it to null within $(document).ready():
$('#key').prop('onclick', null);
Then for the click counter, create a variable and a new click handler:
var clickCounter = 0;
$('#key').click(function () {
clickCounter += 1;
});
A live demo at jsFiddle.
You are adding a new func on each click. That is why you are seeing the new number many times, as well as the old ones.
Add these lines to remove previous handlers:
$("a").prop("onclick", null); //remove default "onclick" handler - otherwise the 0 will always continue coming
$("#key").off("click"); //remove old jQuery assigned handlers
Then send ++k to new handler.
Related
I'm attempting to do a project in which I need to change attributes on a button. I have no code for you, but I still need help. Is there any way I can change a button that's already there so that the onclick attribute runs a different function from before? Thanks in advance.
I feel like all the answers so far miss the main point. Since you don't have any code examples, I'm guessing you'll find it hard to extrapolate out what everyone is saying.
So, one button, which when clicked, changes to another method, and when clicked again, changes back. I'm using the onclick attribute for simplicity, but as others have shown, using JavaScript .onclick or addEventListener is a better choice.
function function1(e) {
// Show where we're at
alert("function1 is running");
// Get which button was clicked from the event that is passed in, and set its onclick event
e.currentTarget.setAttribute("onclick", "function2(event)");
}
function function2(e) {
// Show where we're at
alert("function2 is running");
// Get which button was clicked from the event that is passed in, and set its onclick event
e.currentTarget.setAttribute("onclick", "function1(event)");
}
<button onclick="function1(event)">Click Me!</button>
You can of course change what function1 and function2 do, and add more changes (e.g. function 3 and 4), add logic for when to change, and so on.
use .onclick = function_name;
Demo :
document.getElementById('myButton').onclick = fun2;
function fun1() {
alert('I am from Function 1');
}
function fun2() {
alert('I am from Function 2');
}
<button id='myButton' onclick='fun1()'>Click me</button>
Yes, you can. There's only one thing to keep in mind:
An event on which you want the change to happen
Once you have identified that event, just bind it with JQuery's .attr() function to change any attribute.
Read more: http://api.jquery.com/attr/
Javascript Events: https://developer.mozilla.org/en-US/docs/Web/API/Event
Use jQuery like:
$("mybtn").click(function(){
$("#mybtn").attr({
"onclick" : "anotherFunction()",
});
});
Yes, it's possible. Check this fiddle: https://jsfiddle.net/gerardofurtado/ga3k7ssp/1/
I set a variable to 0 and this function for button 1:
bt1.onclick = function(){
i++;
myPar.innerHTML = i;
};
It increases the variable and displays the number.
But, clicking on button 2, it changes button 1 function:
bt1.onclick = function(){
i--;
myPar.innerHTML = i;
};
Now button 1 decreases the variable.
This other fiddle is similar, but using radio buttons, to show that you can set the original function of button 1 back: https://jsfiddle.net/gerardofurtado/8gbLq355/1/
I'm total beginner in JavaScript. The problem is that the code works only when I click on the text two times. I need same, but with one click. The code is on the link:
http://jsbin.com/uTizoKe/1/edit?html,output
I'd really appreciate any help. Thank in advance
Move your script tag to the end of the body of the HTML, and remove the onclick handler from the table tag. This works (here's the jsbin):
<script>
document.getElementsByTagName('table')[0].onclick = setTDOnclickEvents();
function setTDOnclickEvents() {
var allTDs = document.getElementsByTagName("TD");
for (var i in allTDs) {
allTDs[i].onclick = function () {
txtCellData.value = this.innerHTML;
}
}
}
</script>
Another option (rather than calling your function based on a table click) is to simply do this:
<script>
var allTDs = document.getElementsByTagName("TD");
for (var i in allTDs) {
allTDs[i].onclick = function () {
txtCellData.value = this.innerHTML;
}
}
</script>
Another option is (if you want to use the script in the head of the document), put everything as a function inside of window.onload.
Additionally, it generally a good practice to try to avoid relying on putting event handlers inside HTML elements themselves, and rather handle all that stuff inside your JavaScript.
Remove the onclick from the table and add it as onload to the body
DEMO
Alternatively, you can use window.onload instead of putting it directly in the body
DEMO
The problem is that you have an onclick attached to the table which calls setTDOnclickEvents. So, only when the user clicks the table will that onclick occur.
What you really want is to bind your elements within the table when the page loads. Using jQuery you could do...
$(function() {
setTDOnclickEvents();
});
Replace
<body>
by
<body onload="setTDOnclickEvents()">
There are other ways to do that, like you could just write :
document.onload = setTDOnclickEvents;
Inside your JavaScript
You need to bind your function to an event for it to be fired at all, if it's inside head.
I'd expect your code not to work at all, strange that it does. Perhaps some default behavior somewhere, not worth investigating...
PS: I just saw that you're biding the click event for table to the function, so that would explain the strange behavior. Yeah, remove that.
The problem is that you're calling setTDOnclickEvents() on click of the table element. So you're not attaching the click events until after you've clicked the first time.
Instead, you can move this into the body onload attribute.
There are some other improvements you could make to this code to, to make it simpler and more up-to-date. If interested, please let me know, I'd be happy to help.
I want to toggle open and hide words when I toggle the panel.
Here is the code I used. it works only for hide but when I click next time it doesnt show open.
$(document).ready(function(){
$(".flip1").click(function(){
$(".panel1").slideToggle("slow");
var val= 0;
if(val==0){
$('#word').html("hide").show();
val=1;
}else{
$('#word').html("open").show();
val=0;
}
// $(".info").hide();
});
});
help me to correct this.
Move this line:
var val= 0;
Out of the click() callback.
Where you have it it is a local variable within your click handler, and it gets set to 0 every time the handler is called. Move it outside the handler and it will get initialised to 0 once, and then updated within the click handler.
Alternatively, get rid of that variable altogether and do something like this:
$(document).ready(function(){
$(".flip1").click(function(){
$(".panel1").slideToggle("slow");
$("#word").html(function(i,oldHtml) {
return oldHtml==="hide"?"show":"hide";
}).show();
});
});
Demo: http://jsfiddle.net/9S5eq/
EDIT: If you pass a callback to the .html() method, jQuery calls it for each element in the jQuery object, passing the index of the current element within the object and that element's current html. It sets the html to whatever value you return. So in this case where there is only one element the index parameter isn't actually needed at all, but you can't leave it out because the current value is passed in the second parameter (so i is just a sort of placeholder).
you can use this code
$(document).ready(function(){
var val= 0;
$(".flip1").click(function(){
$(".panel1").slideToggle("slow");
if(val==0){
$('#Word').html("hide").show();
val=1;
}else{
$('#Word').html("open").show();
val=0;
}
// $(".info").hide();
});
});
you must use var val=0 before the click event of the .flip1
in my html page, i have an image, and on clicking a button, i'm calling the function TestLoad() where it is changing the src of the image and when the image is loaded i'm doing something...
take an example:
javascript:
function TestLoad() {
alert('before');
$('#ImgTest').attr('src', 'Images/Image1.jpg');
$('#ImgTest').load(function () {
alert('after');
});
}
html:
<img id = "ImgTest" alt="" src="" style="width:100px; height:100px"/>
<input type="button" onclick ="TestLoad();" value="TestLoad"/>
my problem is:
when i click the button for the first time, i'm getting the alert "after" one time and if i click another time, the alert will be displayed two time and the third, 3 times...
Kindly advice
Thanks
Each time your handler executes, it adds another new load handler. You only need to assign the handler a single time. If you really need to do it this way, you can either remove the existing handlers first or check the events to see if it's already being handled:
var $imgTest = $('#ImgTest');
$imgTest.attr('src','Images/Image1.jpg');
$imgTest.unbind('load');
$imgTest.load(function(){
alert('after');
});
Or:
var events;
var $imgTest = $('#ImgTest');
$imgTest.attr('src', 'Images/Image1.jpg');
events = $imgTest.data('events');
if(events !== null && typeof events.load === undefined){
$imgTest.load(function(){
alert('after');
});
}
Your onclick event is probably binding another load event.
You don't need to keep adding the event to it. It already exists. If you need to bind another one, you'll want to unbind the previous event first.
.on("load", function() { ... });
.off("load");
You are binding multiple functions in your event handler
//bind this outside of your test load method
$('#ImgTest').load(function () {
alert('after');
});
function TestLoad() {
alert('before');
$('#ImgTest').attr('src', 'Images/Image1.jpg');
}
I have a link that looks like this:
<a id="mylink" onclick="deleteHike( 3 );" href="javascript:void(0);">Yes</a>
It is able to call this JavaScript:
window.onload = function()
{
//Get a reference to the link on the page
// with an id of "mylink"
var a = document.getElementById("mylink");
//Set code to run when the link is clicked
// by assigning a function to "onclick"
a.onclick = function( hike_id )
{
// Somecode her
// But when I try to use the hike_id it displays as [object MouseEvent]
}
}
But the value that comes in is [object MouseEvent], not the number that I was expecting. Any idea why this happens and how to fix this? :)
Thanks!
You are trying to assign the function to your link in two different and conflicting ways.
Using the eval-ed function string, onclick = "function(value)", works but is deprecated.
The other way of binding the click handler in the onload event works too, but if you want a particular value to be passed, you'll have to change your script a bit because the value as given in the initial onclick is completely lost when you set the onclick to a new function.
To make your current method work, you don't need an onload handler at all. You just need this:
function deleteHike(hike_id) {
// Some code here
}
To do it the second way, which I recommend, it would look like this:
<a id="mylink" href="javascript:void(0);">Yes</a>
with this script:
function deleteHike(e, hike_id) {
// Some code here
// e refers to the event object which you can do nifty things with like
// - learn the actual clicked element if it was a parent or child of the `this` element
// - stop the event from bubbling up to parent items
// - stop the event from being captured by child items
// (I may have these last two switched)
}
function getCall(fn, param) {
return function(e) {
e = e || window.event;
e.preventDefault(); // this might let you use real URLs instead of void(0)
fn(e, param);
};
}
window.onload = function() {
var a = document.getElementById("mylink");
a.onclick = getCall(deleteHike, 3);
};
The parameter of a DOM event function is the event object (in Firefox and other standards-compliant browsers). It is nothing in IE (thus the need to also grab window.event). I added a little helper function for you that creates a closure around your parameter value. You could do that each time yourself but it would be a pain. The important part is that getCall is a function that returns a function, and it is this returned function that gets called when you click on the element.
Finally, I recommend strongly that instead of all this, you use a library such as jQuery because it solves all sorts of problems for you and you don't have to know crazy JavaScript that takes much expertise to get just right, problems such as:
Having multiple handlers for a single event
Running JavaScript as soon as possible before the onload event fires with the simulated event ready. For example, maybe an image is still downloading but you want to put the focus on a control before the user tries to use the page, you can't do that with onload and it is a really hard problem to solve cross-browser.
Dealing with how the event object is being passed
Figuring out all the different ways that browsers handle things like event propagation and getting the clicked item and so on.
Note: in your click handler you can just use the this event which will have the clicked element in it. This could be really powerful for you, because instead of having to encode which item it was in the JavaScript for each element's onclick event, you can simply bind the same handler to all your items and get its value from the element. This is better because it lets you encode the information about the element only in the element, rather than in the element and the JavaScript.
You should just be able to declare the function like this (no need to assign on window.onload):
function deleteHike(hike_id)
{
// Somecode her
// But when I try to use the hike_id it displays as [object MouseEvent]
}
The first parameter in javascript event is the event itself. If you need a reference back to the "a" tag you could use the this variable because the scope is now the "a" tag.
Here's my new favorite way to solve this problem. I like this approach for its clarity and brevity.
Use this HTML:
<a onclick="deleteHike(event);" hike_id=1>Yes 1</a><br/>
<a onclick="deleteHike(event);" hike_id=2>Yes 2</a><br/>
<a onclick="deleteHike(event);" hike_id=3>Yes 3</a><br/>
With this JavaScript:
function deleteHike(event) {
var element = event.target;
var hike_id = element.getAttribute("hike_id");
// do what you will with hike_id
if (confirm("Delete hike " + hike_id + "?")) {
// do the delete
console.log("item " + hike_id + " deleted");
} else {
// don't do the delete
console.log("user canceled");
}
return;
}
This code works because event is defined in the JavaScript environment when the onclick handler is called.
For a more complete discussion (including why you might want to use "data-hike_id" instead of "hike_id" as the element attribute), see: How to store arbitrary data for some HTML tags.
These are alternate forms of the HTML which have the same effect:
<a onclick="deleteHike(event);" hike_id=4 href="javascript:void(0);">Yes 4</a><br/>
<button onclick="deleteHike(event);" hike_id=5>Yes 5</button><br/>
<span onclick="deleteHike(event);" hike_id=6>Yes 6</span><br/>
When you assign a function to an event on a DOM element like this, the browser will automatically pass the event object (in this case MouseEvent as it's an onclick event) as the first argument.
Try it like this,
a.onclick = function(e, hike_id) { }