I use jQuery to add some HTML to the DOM. After the insertion I would like to create an eventhandler which is called on keyup and clicks on the link added to el. However, jQuery does not find the a element as it was added after loading the page.
var el = $("#name");
// add content to el
$(document).keyup(function(e) {
el.find('a').click();
});
How can I update the DOM in el? I know that there is on() (and its predecessors) in jQuery. However, they do not help me as the event is not registered on the added element itself, but on the document and another event just happens on the newly added element. Any ideas on how to solve this?
Thanks to the response of #Johan I was doing further debugging and found the solution:
el.find('a')[0].click();
So the real problem was not the changing DOM but the click() event that apparently can only be applied to a single element and not to a list of only one element.
Some further discussion about click() not firing can be found here: Can I call jquery click() to follow an <a> link if I haven't bound an event handler to it with bind or click already?
Related
i'm creating an application where a user can make a html layout and attach javascript to it.
Now i'm trying to make it so when they click a button, they go to a preview mode where they can see it in action.. so when they click i add the javascript tag ( with their javascript) in the head of the iframe.. this all works fine!
But the problem is when they leave the preview mode, i remove the javascript tag, however when i have code like this:
$('#button').click(function()
{
alert("ok");
});
it still alerts ok when i click the html button (when not in previewmode!), which shouldn't happen!
It seems that when removing the javascript tag, the listeners aren't removed.. Or am i doing it wrong?
Now my question: is there a way to make it so these added eventlisterens are removed when i remove the script tag?
AND YES: i know you can remove eventhandlers with .off(), but since i already have event handlers attached, these will be removed also, and i don't want this!
So two options i can think off:
- rebuild the whole iframe
- store the eventhandlers that were added by the user and when leaving the preview mode, removing them.
Thanks in advance
Each time you "evaluate" JavaScript, it becomes part of the browser's "image", and whether the source is present on the page no longer matters. You need to manually unbind the event, or replace the html segment to which the event was bound.
To remove events from an html element, you can use:
element.parentNode.innerHTML = element.parentNode.innerHTML
This rebuilds the DOM tree using the same HTML.
you need to unbind event.
You can do it by using jquery unbind() or off()
like this:
$("#button").unbind("click");
or
$("#button").off("click");
Demo: http://jsfiddle.net/a6NJk/664/
jquery Doc: http://api.jquery.com/off/
Another good answer: Best way to remove an event handler in jQuery?
Set the event:
var $button = $('#button');
$button.on("click", function() {
alert("ok");
});
Take off the event:
$button.off("click");
You can take off that specific function too
var $button = $('#button');
var eventFunction = function() {
alert("ok");
});
// Set event up
$button.on("click", eventFunction);
// Take event off
$button.off("click", eventFunction);
If you want to remove all events from an element you can use
$("#yourSelector").off()
Because it's not jQuery in general but also vanilla javascript, it would be too much work to keep track of javascript changes, so rebuilding the iframe would be the best option here.
I have the following code:
var $reviewButton = $('span.review_button');
$reviewButton
.live('click',
function(){
$('#add_reviews').show();
}
)
Later in the script, I use an AJAX call to load some content and another instance of $('span.review_button') enters the picture. I updated my code above to use '.live' because the click event was not working with the AJAX generated review button.
This code works, as the .live(click //) event works on both the static 'span.review_button' and the AJAX generated 'span.review_button'
I see however that .live is depracated so I have tried to follow the jquery documentations instructions by switching to '.on' but when I switch to the code below, I have the same problem I had before switching to '.live' in which the click function works with the original instance of 'span.review_button' but not on the AJAX generated instance:
var $reviewButton = $('span.review_button');
$reviewButton
.on('click',
function(){
$('#add_reviews').show();
}
)
Suggestions?
The correct syntax for event delegation is:
$("body").on("click", "span.review_button", function() {
$("#add_reviews").show();
});
Here instead of body you may use any static parent element of "span.review_button".
Attention! As discussed in the comments, you should use string value as a second argument of on() method in delegated events approach, but not a jQuery object.
This is because you need to use the delegation version of on().
$("#parentElement").on('click', '.child', function(){});
#parentElement must exist in the DOM at the time you bind the event.
The event will bubble up the DOM tree, and once it reaches #parentElement, it is checked for it's origin, and if it matches .child, executes the function.
So, with this in mind, it's best to bind the event to the closest parent element existing in the DOM at time of binding - for best performance.
Set your first selector (in this case, div.content) as the parent container that contains the clicked buttons as well as any DOM that will come in using AJAX. If you have to change the entire page for some reason, it can even be change to "body", but you want to try and make the selector as efficient as possible, so narrow it down to the closest parent DOM element that won't change.
Secondly, you want to apply the click action to span.review_button, so that is reflected in the code below.
// $('div.content') is the content area to watch for changes
// 'click' is the action applied to any found elements
// 'span.review_button' the element to apply the selected action 'click' to. jQuery is expecting this to be a string.
$('div.content').on('click', 'span.review_button', function(){
$('#add_reviews').show();
});
I have two select-boxes, each of them is in span element with specific id. The first select-box is country, the other one is city list. When I select a country the innerHtml of city select-box container span is replaced by response of ajax function everything is good. But I want to fire a function by useing onchange attribute of selectbox if at the begining of page loading addeventListener function works fine but affter replacement of innerHtml of span it does not work and after replacement the id of city selecbox is same es before replacement. I am just using.
document.getElementById('to_city').addEventListener('change',doSomething,false);
this code is initialized by onload of window element.
It works without ajax replacement but dont after.
When you replace contents with AJAX you need to bind event again. so its good idea to bind event again after replacing content.
There is a way to avoid it using event bubbling.
JQuery 1.4+ supports onchange event propagation so you can use jquery delegate function to achieve same. http://api.jquery.com/delegate/
with Jquery only one line do the work.
$("#container").delegate("#to_city", "change", doSomething); // Workd in all browsers
I ignored IE in below example as you are using addEventListener which is not supported by IE.
Without Jquery
Working example (Not working in IE) : http://codebins.com/bin/4ldqpb1/2
document.getElementById("container").addEventListener( 'change', function(e) {
var targ=e.target;
if (targ.id == "to_city") { //you just want to capture to_city event
//DO STUFF FOR SELECT
//DO STUFF
doSomething();
alert("id: " + targ.id + "\nvalue: " + targ.value);
}
}, false)
Explanation:
When you bind any events they are bound to that particular element not the selector or ID. so when you replace the content and new replace element with the new element with the same ID, new element doesnt have any event attached. so you need to attache event again. so if you attach event after AJAX content replace doSomething will work. but that is not a very good solution.
We are using event bubbling concepts. many events are bubbled to the top of the document. (IE doesn't bubble change event)
So we write handler on the container and listen for the event. each event has a target or srcElement which says which dom element firing this event. if the dom element is what we are looking for execute function. in this can we are looking for element with ID to_city that's why if condition.
I am a bit confused, I have a bunch of elements that get added via jquery using a ajax call and I want to attach a click handler to them (there could be a lot).
But I have no idea how to even begin this, I looked at .on and it is really confusing. I want to attach a click event handler for a certain class so that when I click on it, I get the this.id and then do stuff with it.
What you're trying to do is called event delegation.
You want to set the event listener on a higher element in the DOM that'll never change, but only fire off the event handler if the child element that has been clicked matches a specific selector.
Here's how it's done with jQuery's .on():
$(document).on('click', '.your-selector', function(){
alert(this.id);
});
P.S. You could probably apply the event listener to an element lower down in the DOM tree...
This will get you the id of a clicked element with the class "test"...
$(".test").on("click", function() {
var id = $(this).attr("id")
});
You'll need to run that after the ajax call returns. It will only bind the click event to elements that exist when it runs, so it's no good at document.ready.
Assume I get a table element with ID="emTab", how do I call JS to click it?
Thanks.
document.getElementById("emTab").onclick = function() {
// your code goes here
};
See element.onclick
To trigger click event
document.getElementById("emTab").click();
See element.click
The click method is intended to be
used with INPUT elements of type
button, checkbox, radio, reset or
submit. Gecko does not implement the
click method on other elements that
might be expected to respond to
mouse–clicks such as links (A
elements), nor will it necessarily
fire the click event of other
elements.
Non–Gecko DOMs may behave differently.
When a click is used with elements
that support it (e.g. one of the INPUT
types listed above), it also fires the
element's click event which will
bubble up to elements higher up the
document tree (or event chain) and
fire their click events too. However,
bubbling of a click event will not
cause an A element to initiate
navigation as if a real mouse-click
had been received.
Cross browser way
If you can use jQuery then it would be
$("#emTab").trigger("click");
Firing events cross-browser - http://jehiah.cz/archive/firing-javascript-events-properly
its simple using JQuery
$('#emTab').click(functionToCall);
while in JS
document.getElementById('emTab').onclick = function() {};
for details on DOM events:
http://www.howtocreate.co.uk/tutorials/javascript/domevents