Javascript eventlisteners override other buttons? - javascript

I've run into a problem using eventlisteners and javascript (though onclick seems to have the same effect).
I have this in html
<input id="srch" type="button" value="Zoek gebruikers!" onclick="searchButton()">
Now, this initially worked fine and executes the expected javascript code. But, when I add this in another javascript function
var addbutton = document.createElement("input");
addbutton.setAttribute("id","openAddMenu");
addbutton.type = "button";
addbutton.value = "search";
addbutton.innerHTML = "Zoek";
addbutton.addEventListener('click',searchFriendsAsync(),false);
Now my initial button wil try to execute 'searchFriendAsync()' as well.
I'm quite inexperienced with javascript, so I'm sure it's something basic I'm missing. Yet search results on google find answers regarding adding one event to multiple buttons etc, which is .. about the opposite of what I want. I need multiple buttons with different events - some buttons are generated using javascript. (Note, when I add another eventlistener to a third button, both the first and second button will mess up).

One problem is here:
addbutton.addEventListener( 'click', searchFriendsAsync(), false );
I assume searchFriendsAsync is a function defined in your code that you wish to call when addbutton is clicked, is that right?
That's not what this code does. It calls searchFriendsAsync immediately (because of the parentheses) and passes its return value to addEventListener, which doesn't do any good. Simply remove the parentheses to pass a reference to the function itself instead of calling it:
addbutton.addEventListener( 'click', searchFriendsAsync, false );

In JavaScript, there is a difference between searchFriendsAsync and searchFriendsAsync(). The first one is just giving a reference to the function that has to be executed. The second one is actually invoking the function.
The onclick attribute expects JavaScript code. Thus you want to execute the function. Thus the parentheses are needed.
However when you specify the button in JavaScript, you would just want to tell the name/reference of the function to be executed I.e. without the parentheses. The addEventListener function would make sure that the reference is executed. Thus your code would be like this
addbutton.addEventListener('click', searchFriendsAsync, false);

Related

Assigning JQuery On Click Function in For Loop

I have a function that dynamically creates div elements based upon whatever input is given, and lets them choose certain items by clicking on each div. I have it so that if the div is clicked, a function (named checkToggle) is called that makes it looks like it is selected and adjusts some related variables. There is a checkbox in the div element that is toggled by this function (hence its name). Long story short, I had to jump through some hoops to get it to work, most of which I don't even remember. Please don't ask me about that.
The point of this question is this. I initially used the following JavaScript code to run the function when the checkbox was clicked. It was assigned by the main function, which created these div elements using a for loop.
document.getElementById(`${itemID}-checkbox`).onclick = function() {
checkToggle(`${itemID}-checkbox`);
};
This works, but I wanted to try to convert all of my onClick functions to JQuery. Here is the JQuery alternative I created.
$(`${itemID}-checkbox`).on(`click`, function() {
checkToggle(`${itemID}-checkbox`);
});
While the code itself seems to be fine, it does not work. It seems as if JQuery functions cannot be created like this in a for loop or something. It is applied after the element is created and put in its place, so I don't think it has anything to do with the element not being ready. I am also having the same issue with 2 other similar cases. Any idea as of why this isn't working?
Let me know if more information is needed and if so, what kind of information is needed.
You need to update the selector to Target HTML id using the # character. Simply prepend the character to the query:
$(`#${itemID}-checkbox`).on(`click`, function() { checkToggle(`${itemID}-checkbox`); });
It would also apply to DOM methods querySelector or querySelectorAll as well.
Hopefully that helps!

onclick event not firing javascript

EDIT #2:
Made a JS Fiddle... http://jsfiddle.net/N2p6G/ (I hardcoded some stuff that I'm certain works correctly, but the problem is still there)
Original:
So, I have written tens of thousands of lines of javascript, and used code that look like this a hundreds of times and I don't understand what's going on.
blacklistitembutton.onclick = function() {
console.log("clicked.");
}
The above code does not seem to be working... and I can't figure out why
In fact, I use the same method earlier in the same file... and it works fine!
settings.onclick = function() {
settings_popup.toggle();
}
EDIT:
Might it have something to do with the fact that it's being executed in a for loop?
Here is the code...
var blacklistButton = document.createElement('input');
blacklistButton.type = 'button';
blacklistButton.value = "Add Current Site to Blacklist";
blacklistButton.onclick = function() {
console.log('blacklistButton clicked');
}
for (var i=0;i<blacklist.length;i++) {
var blacklistitembutton = document.createElement('div');
blacklistitembutton.type = 'button';
blacklistitembutton.blacklistValue = blacklist[i];
blacklistitembutton.value = "X";
blacklistitembutton.onclick = function() {
console.log("clicked.");
}
}
Then both blacklistButton and all of the blacklistitembuttons are put into the document through element.appendChild (and they all show up successfully!)
The blacklistButton onclick fires just fine, and the blacklistitembutton onclick does not.
document.addEventListener('click', function(){
console.log('clicked');
}, false);
Edit:
Here is a re-write of your code in a fiddle: http://jsfiddle.net/N2p6G/1/
There are a lot of things in your code that worry me. Hopefully from my re-write you can see there are better ways to handle some things.
1) I'm not sure why you are using document.write() at the beginning. That has very little purpose.
2) You are modifying the DOM way too much. Some of the DOM elements you are creating in code are better-served as just being target locations in html. Only the dynamically-created input button elements need to be done in javascript. Remember, modifying the DOM should be done as little as possible.
3) Don't assign events using the onclick, onsubmit, onhover, etc syntax. Events should only be bound to DOM elements using addEventListener. The other benefit of doing it the proper way is that you can assign multiple events of the same type, if need be, to the same element. Also, with some extra state code that I haven't included, you can selectively remove particular events later if you need to.
4) There was a debate several years ago about whether using innerHTML and string templates was faster/better than using DOM creation methods. For a while, the best solution was to use documentFragments and a combination of the two methods. These days, it doesn't really matter anymore since all browsers are pretty damn fast, so for simplicity's sake is good to just go with innerHTML.
This also goes back to the rule of "don't touch the DOM too much". If you look at my code, you can see that I'm assembling the final html simply as an array of elements that gets joined as a single string at the end. Its then rendered to the DOM with a single innerHTML statement. I'm only touching the DOM one time, instead of multiple times.
5) The last bit goes into events again. At the beginning and end of the code you can see where and how I've added the events for the DOM elements. Indeed, the addEventListener at the beginning could be moved to the end to group all the event declarations together, but it doesn't really matter. I left it at the top to help you understand what's going on better.
Hope this helps.
For unlimited event bindings, either use addEventListener or attachEvent method. You cannot add more than one event of the same type using that traditional method.
I don't know if it's a typo in what you put here, but in the loop you are creating a "div" and then assigning it a type of "button". Does that work or is it throwing an error? If it is then that explains why the event handler is not getting the function. Try making it an "input" and see if it now works.
Fixed it!
blacklistitem.innerHTML += blacklist[i];
^ was messing it up, at this point in the code blacklistitem is still a javascript item, not yet appended to its to-be parent element in the document
So I just stuck blacklist[i] into a span tag and appended as a child and now it works fine :)

Using JQuery to get string value of an onclick() event

Wondered if there was good way to do this, thought I would post to the SO community...
There is a 3rd party web page that I have no control over how it renders, but they allow me to add JQuery.
Using the JQuery, I am creating a nav menu on the side of the page, it will be a list of links. The onclick event of these links I get from existing onclick events already on the page, but when I do a:
var linkLoc = $('#theLink').attr("onclick");
linkLoc returns:
function onclick(event) {
handleJumpTo("com.webridge.entity.Entity[OID[E471CB74A9857542804C7AC56B1F41FB]]", "smartform");
}
instead of what I would expect:
handleJumpTo("com.webridge.entity.Entity[OID[E471CB74A9857542804C7AC56B1F41FB]]", smartform");
I think JQuery is trying to get the event for binding, but I need the actual Javascript markup since I'm creating the HTML dynamically. I guess I could substring the "function onclick(event) {" out, but seems kind of hacky.
Any ideas of an elegant way I could get the onclick markup?
$("#theLink") would return a jQuery object whereas $("#theLink")[0] would give a DOM object. This is a resson that $("#thelink")[0].getAttributeNode('onclick').value would work.
The type of $('#theLink').attr("onclick") is a function, so you can just use that when you bind events to the links.
var linkLoc = $('#theLink').attr("onclick");
$('a#link1').live('click', linkLoc);
Example: http://jsfiddle.net/BdU6f/
You can also run other code in the click handler too, if you need:
var linkLoc = $('#theLink').attr("onclick");
$('a#link1').live('click', function(e){
// Code...
linkLoc(e);
});
Example: http://jsfiddle.net/BdU6f/1/
The "onfoo" attributes have values that are functions, not strings. The semantics of:
<whatever onclick='code code code'>
are that the browser constructs a function object as if you had code that did this:
document.getElementById('whatever').onclick = new Function("event", "code code code");
Thus you don't really need the raw string, since you've got something better: the function itself, ready to be called. You can then bind it as a handler to other elements via JavaScript code, not HTML (which is really a better way to do things anyway). You're using jQuery, you say, so you can use the jQuery ".bind()" API to bind those functions to whatever elements you need.
You should also be aware that there are other ways of binding event handlers to elements, ways that will leave the "onfoo" attributes completely unset.
If I understand where you're going with this, you should be able to assign the returned onclick function straight through to the onclick of your new nav element...
$('#NewNavElement').click($('#theLink').attr('onclick'));
If you need to add additional code to the handler, you can just bind another click handler.
try this;
$('#theLink').getAttributeNode('onclick').value
Revised as per comment:
$('#theLink').get().getAttributeNode('onclick').value

How do you use the click event properly to call another function within the class?

I was confused on how to use the click event in order to call another function within the class.
$.fn.imageareaselect(image)
{
this.click(function(){
$.fn.pinpointImage.add(image);
});
}
The selector that is passed into this function is an image. I wan't to make it so when you click the image it calls that function.
jQuery's kinda funny about passing an HTML element when you'd expect a jQuery one. try using $(this) instead of this.
Also, jQuery functions like to take functions as params, but i'm not sure exactly what this code is trying to do now. The first "(image)" should probably be "= function(image)" instead.

About Events to Textbox and Div

I have assigned a onClick event to textbox. When I am clicking on textbox, I want to execute the click event of div also. How to do that in Javascript?. The div and textbox are not nested they are on different position in document.
Thanks in advance for the Help.
I would recommend using a function that is called by both.
You need to know even bubbling in order to do that.
I recommend reading PPK's blog post about events. It's a bit old, but it weathers the test of time well. See:
http://www.quirksmode.org/js/events_order.html
If the elements are nested the event will bubble up (if you aren't cancelling it) so:
<div onclick="foo()">
<input type="text" onclick="bar()" />
</div>
Will result in a call to bar then foo. This is a bit of a kludge though since you don't really want to have inline event binding if you can help it. This is one of those cases where use jquery might be appropriate since $('#mydiv, #myinput').click(baz) is quite clean.
Try this:
function twoActions(){
var textboxId = document.getElementById("textboxId");
var divId = document.getElementById("divId");
textboxId.style.border = "red"; // action one
divId.style.border = "red"; // action two
}
you tie this function to the textbox - onClick it will change the border color of the text box and that of the Div.
If you're not nesting the divs, you'll need to explicitly call the .click() of the div separately.
function textEvent() {
// Do all the stuff you want to do for the textbox
// Fire the event for the div too
div = document.getElementById('#secondDiv');
div.click();
}
I am reading it as if you have 2 different functions. We'll just say textbox(); and div();
your onclick for the textbox should read
onclick="textbox(); div();"
That should call both functions on the same event, where with the div you can put only the div() function or both like the example above. Just seperate the function calls with a semi-colon.

Categories