I have this code:
$(".div").click(function ()
{
alert("hi");
});
...but when I create new div:
$("body").append("<div>1</div>");
...and click on this div, it doesn't say "hi".
I know that I can do onclick="callfunction()" on the div element, but I would like to avoid using that method.
Problems
You were attempting to create a bind on an element that didn't yet exist - so it couldn't be bound.
You used .div as a selector. The selector .div is looking for an element with class="div" rather than an element of type div.
Solution 1 - Delegation
With delegation you create a bind on an element that exists in the structure above where you will be dynamically adding an element that you want to listen for.
To use delegation, change to this:
$("body").on("click", "div", function ()
{
alert("hi");
});
Here is an example showing delegation vs binding on a future element without delegation:
Fiddle
Solution 2 - Bind to element on creation
The alternative would be to add the bind on the creation of the new element, that would look something like this:
$newEle = $("<div>1</div>").click( function() {
alert("hi");
});
$("body").append($newEle);
Fiddle
Use the appendChild() method to add the DIV to the end of your document. See: http://www.w3schools.com/jsref/met_node_appendchild.asp
Your other logic can follow the creation of the div.
Related
How do I bind an html event such as onclick to a function myFunc(e){}?
I do not want to use document.getElementByClass or Id.
I do not want use jQuery.
Try this:
document.getElementsByTagName('body')[0].addEventListener('click', function(){alert("you clicked on the page")})
This adds an event listener to the body tag. Once you click on the page, it will fire the alert function.
You can get the elements by either class name, id and/or tag name:
document.getElementById('someId')
document.getElementsByClassName('someClassName')
document.getElementsByTagName('body')
Keep in mind, the "getElementsByClassName" and "getElementsByTagName" return arrays, so you might want to add the index like this
getElementsByTagName('body')[0]
document.getElementsByClassName('someClassName')[1]
...
If it's still the 1990s where you are and jQuery hasn't been invented, then sure:
<div onclick="myFunc">
</div>
First you must find the element on the page, for example var element = document.getElementById('clickme'), then you must add a listener to the click event element.addEventListener('click',function)
Say I have:
<a href="http://foo.com" class="SiteClass">
Then I via jQuery I do some tests and conditionally update the class depending on the outcome, for example adding SiteDown css via jQuery addClass method, resulting in:
<a href="http://foo.com" class="SiteClass SiteDown">
I have the following JavaScript which does not fire:
$("a .SiteDown").on('click', function(e){
e.preventDefault();
e.stopPropagation();
alert('Clicked SiteDown');
});
What do I need to be able to fire an alert (or any other code there) when a link with class SiteDown is clicked, keeping in mind this class can be added dynamically.
You selector is incorrect, remove space to convert it to element with class selector.
$("a.SiteDown").on('click', function(e){
//....
});
As of now its descendant selector.
As you are approach when manipulation selector, use Event Delegation using on().
$(document).on('click', "a.SiteDown", function(e){
//....
});
In place of document you should use closest static container.
In your code $("a .SiteDown") you are looking for an element that is child of a remove space and it will be ok. use $("a.SiteDown") meaning a with class SiteDown
I am using this code to remove and a CSS class:
$('.called').click(function() {
$('called').removeClass('fa-phone-square').addClass('fa-check');
})
The problem is, it removes and adds classes to ALL tags with the class '.called'. I want this function to work only for the single item that has been clicked.
How would I do this?
In jQuery event handlers this gets bound the the DOM node that fired the event.
$('.called').click(function() {
$(this).removeClass('fa-phone-square').addClass('fa-check');
})
You would have to do this:
$('.called').click(function() {
$(this).removeClass('fa-phone-square').addClass('fa-check');
})
"this" inside the click handler refers to the element that has been clicked and which you want to apply the changes.
If you instead apply the ".called" selector again it will select all items with the "called" class and apply the removeClass and addClass to all of them which is the behavior you are experiencing now.
Inside the callback, $(this) refers to the element that was clicked.
You can also have the event as an argument in the callback and get the clicked element with event.target - https://api.jquery.com/event.target/
Difference between using $(this) and event.target - Difference between $(this) and event.target?
I am simply appending an element that is on the DOM like:
$("#div_element").append('test');
Right after I append it I need access to the element I just made in order to bind an click function to it, I tried:
$("#div_element").append('test').click(function(){alert("test")});
But the above didn't work. I could uniquely id the element but that seems like a bit to much work when perhaps there is a way I can get the element right after I append it.
You can do this:
var el = $('test');
$("#div_element").append(el);
el.click(function(){alert("test")});
// or preferrably:
el.on('click', function(){alert("test")});
The append function accepts two types of arguments: a string or a jQuery element.
In case a string is passed in, it will create a jQuery element internally and append it to the parent element.
In this case, you want access to the jQuery element yourself, so you can attach the event handler. So instead of passing in the string and let jQuery create an element, you have to create the element first and then pass it to the append-function.
After you've done that, you still have access to the jQuery element to be able to attach the handler.
var $a = $('<a />', {href:"#"})
.text("test")
.on('click', function(e) {
alert('Hello')
})
.appendTo('#div_element');
http://jsfiddle.net/33jX4/
Why not save a reference to the new element before you append it:
var newElement = $('test');
$("#div_element").append(newElement);
newElement.click(function(){alert("test")});
The last element would be the new element
$('a:last','#div_element').on('click',function(){
// do something
});
Add identity to that element then use it as follows
$("#div_element").append('<a id="tester" href="#">test</a>');
$('#tester').on('click', function(event) {
console.log('tester clicked');
});
You can attach event to element when you create it --
var ele =$("<a href='#'>Link</a>");
ele.on("click",function(){
alert("clicked");
});
$("#div_element").append(ele);
Just attach the click handler to the anchor BEFORE you append it.
$("#div_element").append($('test').click(function(){alert("test")}));
I am not very sure with the use of "this" [current context] in jquery.What I know is- it prevents the dom from searching all the elements, it just work on that current element, which improve performance[correct me if I am wrong].Also I am not sure when to use this and when not.
lets say, should I go for
$("span",this).slice(5).css("display", "none")
or
$("span").slice(5).css("display", "none")
both will work, but I am not very clear as how really it works.can somebody explain it with a diff/proper example, and when to use what?
[EDIT]
$(function() {
$("#clickme").click(function() {
$("span",this).slice(5).css('display', 'block');//doesn't work ? why?
$("span").slice(5).css('display', 'block');//works..why?
});
});
enter code here <span id="clickme">Click me</span>
<span>itam1</sapn>
<span>itam2</sapn>
<span>itam3</sapn>
<span>itam4</sapn>
<span>itam5</sapn>
...upto10
Usually you can use the this keyword on event handlers since it will be a reference to the element that triggered the event and other jQuery functions like $.each.
For example when handling a click event lets say:
$('.parentElement').click(function () {
$('.foo', this).hide();
});
The above code, will hide all the elements with class foo that are descendants of the currently parentElement that was clicked.
The use of the context argument of the jQuery function is the equivalent of making a call to the find method:
$(expr, context);
// is just equivalent to:
$(content).find(expr);
EDIT: Looking at your example:
$("#clickme").click(function() {
$("span",this);//... (1)
$("span");//.. (2)
});
The first line, will look for all the span elements that are inside of #clickme (its descendants), since that element was the one that triggered the click event.
The second line, will look for all the span elements on the whole page.
How it works
Lets use this HTML for the examples:
<div id="container">
<div class="column">Link 1</div>
<div class="column">Link 2</div>
</div>
<div id="footer">
Link 3Link 3
</div>
The scoping parameter of the jQuery function should only be used if you already have a cached reference to a DOM element or jQuery wrapped element set:
var $set = $('#container');
$('a', $set).hide(); // Hides all 'a' tag descendants of #container
Or in an event:
$("#container").click(function(e){
$('a', this).hide(); // Same as call above
}
But it makes no sense to use it like this:
$('a', '#container').hide()
When it should be written like this:
$('#container a').hide();
Having said all that, it is generally cleaner and clearer to just use .find() instead of using the second parameter in the jQuery function if you already have the jQuery or DOM element. The first example I gave would be written this way instead:
var $set = $('#container');
$set.find('a').hide(); // Hides all 'a' tag descendants of #container
If this one call was the only reason you grabbed the #container object, you could also write it this way since it will still scope the search to the #container element:
$("#container a").hide(); // This is the same as $('a', "#container");
Why would you scope your selections
When jQuery looks for an unscoped selector, it will search through the entire document. Depending on the complexity of the selector, this could require a lot of searching. If you know that the element you are looking for only occurs within a specific parent, it will really speed up your code to scope the selection to that parent.
Regardless of what method of scoping you choose, you should always scope your selectors whenever possible.