jQuery click handler only fires once - javascript

Appended images used as buttons to show/hide content below a heading:
<!DOCTYPE html>
<html>
<body>
<h2>
the heading
</h2>
<p>
the content
</p>
</body>
</html>
$(document).ready(function () {
var $imag = $("<img src='arrow_down.jpg'>");
var $imag2 = $("<img src='arrow_up.jpg'>");
$("h2").append($imag);
$($imag).on("click", function(){
$("p").hide();
($imag).remove();
$("h2").append($imag2);
});
$($imag2).on("click", function () {
$("p").show();
($imag2).remove();
$("h2").append($imag);
});
});
$(document).main(ready);
At first the images work when clicked. but the next time you click it, it doesn't
without having to refresh the page. Why?

This is because event handlers like click() have to be appended to elements that are already in the DOM when the page is loaded. For elements that are added later the event has to be delegated from a static parent element using on(), like:
$(document).on("click", $imag, function(){
$("p").hide();
($imag).remove();
$("h2").append($imag2);
});
$(document).on("click", $imag2, function () {
$("p").show();
($imag2).remove();
$("h2").append($imag);
});
Just added a Fiddle with an adjustment as I wasn't sure if this would work with the variables $imag / $imag2 (it doesn't). Instead you should just add classes to your images, e.g. like this:
var $imag = $("<img class='down' src='arrow_down.jpg'>");
var $imag2 = $("<img class='up' src='arrow_up.jpg'>");
with adjusted code
$(document).on("click", '.down', function(){
$("p").hide();
$('.down').remove();
$("h2").append($imag2);
});
$(document).on("click", '.up', function () {
$("p").show();
$('.up').remove();
$("h2").append($imag);
});
For reference: https://api.jquery.com/on/#on-events-selector-data-handler, section "Direct and delegated events":
"Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on()."

Related

jquery (hover and load) events binding on dynamically created elements

I am able to bind click event to element with class name keybox. And this element is generated dynamically.
$('body').on('click','.keybox', function(){
// some code here
});
But for same element I tried binding hover and load event using following code:
$('body').on('hover','.keybox', function(){
// some code here
});
$('body').on('load','.keybox', function(){
// some code here
});
....and its not working as expected.
Can someone help with this problem? I want to bind hover and load event to my element with class name keybox and this element is generated dynamically.
Instead of hover, use mouseenter and mouseleave event. Instead of body.load use
$(document).ready(function() {
You can use following approach to bind multiple events and get object information via event object.
$('body').bind('click hover load', '.keybox', function(e){
if ( e.type === 'hover') {
// do something
}
else if(e.type === 'click') {
// do something
}
....
});
Make sure you bind events in $(document).ready(function() {} or load javascript just in bottom of html document body.
Since hover is deprecated you should use mouseenter and mouseleave for load you can write using event using on(load is equivalent to ready).
$(function(){
$(document).on('mouseenter', '.keybox', function () {
$(this).css('color','red');
});
$(document).on('mouseleave', '.keybox', function () {
$(this).css('color','black');
});
$(document).on('click', '.keybox', function () {// click on dynamically loaded events.
$(this).css('color','green');
});
$('#btn').click(function() {
$('#parent').append("<div class='keybox'>sample1</div>");
$('#parent').append("<div class='keybox'>sample2</div>");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="parent">
zdhsdhsau
</div>
<input type="button" id="btn" value="create"/>

jQuery getting data attribute not working

I have a script that produces a number of buttons with a class and I want it to alert the data attribute on click but it's not working.
Here is the output of HTML
<button class="request box-button" data-value="18492500814">Request</button>
jQuery code
$(document).ready(function(){
$('.request').each(function () {
var photoID = $(this);
photoID.click(function () {
alert($(this).data('value'));
});
});
});
Since your elements don't exist when the page loads, the event won't be bound to them. Fix that by using event delegation:
$(document).ready(function(){
$(document).on('click','.request', function () {
alert($(this).data('value'));
});
});
JS Fiddle demo with dynamically generated elements
Note: Here, I used $(document).on() because I don't have your page's structure. But if you insert the buttons in a container that already exists in your HTML, use this instead: $('#myContainer').on(). It won't be noticeable, but it is best for performance.
Why not just have the listener on request, instead of inside of the loop. Also use the attr to get the data-value
$(document).ready(function(){
$('.request').click(function () {
alert($(this).attr('data-value'));
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<button class="request box-button" data-value="18492500814">Request</button>
Try with attr method.
$(document).ready(function(){
$('.request').each(function () {
var photoID = $(this);
photoID.click(function () {
alert($(this).attr('data-value'));
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<button class="request box-button" data-value="18492500814">Request</button>

onmousedown doesn't callback after changing class dynamically

I have the following divs:
<div class="celula" id="838">
</div>
<div class="celula" id="839">
</div>
<div class="celula" id="840">
</div>
I change them dynamically using jquery with an ajax response so far it works great.
Imagine that it generates the following:
<div class="checked" id="838">
</div>
<div class="checked" id="839">
</div>
<div class="checked" id="840">
</div>
Complete js callback:
$(document).ready(function () {
document.getElementById("templatenome").innerHTML = screen.width + " - " + screen.height;
$('.celula').on('mousedown', function(){
var template = $("#templatenome").attr("name");
var $div = document.getElementById (this.id);
$div.style.backgroundImage = "url('../../resources/"+template+"/images/CelulaPOP.png')";
var audio = document.getElementById("audio");
audio.play();
$(document).one('mouseup', function(){
sendAjax($div.id);
$div.style.backgroundImage = "url('../../resources/"+template+"/images/CelulaSEL.png')";
});
});
$(document).on('mousedown', '.checked', function(){
$(document).one('mouseup', function(){
});
});
});
Use a delegated event handler, attached to a non-changing ancestor of the dynamic elements:
$(document).on('mousedown', '.checked', function(){
$(document).one('mouseup', function(){
alert("I was mouse-uppped on a .checked div!");
});
});
As you do not want the previous handler to operate once the class is changed (see comments below), make that a delegated handler too:
e.g.
$(document).on('mousedown', '.celula', function(){
This applies the jQuery selector at event time only, so the elements only need to match then (and not when the event was registered).
document is the best default if nothing closer is available/convenient. Do not use 'body' as it has a bug (if styling results in a calculated body height of 0 it will not bubble mouse events to body)
Here is a little demo showing how events will fire with the delegated event handlers as the classes are changed:
JSFiddle: http://jsfiddle.net/TrueBlueAussie/5xb6vohp/3/

jQuery Change Color on click

I am a jQuery beginner and want to achieve the following - whenever I click on any element of the page, I want the color of the text inside it to be changed to red. This is what I have but it doesn't work. Surprisingly the alert statement also prints nothing. But it does executes as I tested it with another alert statement. Thanks.
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<div>Cow</div>
<div>Cat</div>
<p>paragraph</p>
<p>coconut</p>
<script type="text/javascript" src="../Scripts/jquery-2.0.3.js"></script>
<script type="text/javascript">
$(this).click(function () {
var v = $(this).text();
alert(v); // this prints nothing !!!!
$(this).css("color", "red");
});
</script>
</body>
If you attach the click handler to the document, any click that bubbles up to the document will go to the event listener. If you now within the listener look for the event.target, that will be the node that initiated the event:
$(document).click(function (event) {
$(event.target).css("color", "red");
});
example: http://jsfiddle.net/E9H22/
If you specify the body element (in place of this), then it works:
$('body').click(function () {
var v = $(this).text();
alert(v); // this prints something, now.
$(this).css("color", "red");
});
JS Fiddle demo.
You could also, of course, use:
$(this.document.body).click(function () {
var v = $(this).text();
alert(v); // this prints something, now.
$(this).css("color", "red");
});
JS Fiddle demo.
If you want only the clicked-element to have its text turn red:
$('body').click(function (e) {
$(e.target).css("color", "red");
});
JS Fiddle demo.
$(this).click(function () {
This is your problem.
Instead of saying this, you need to use CSS selectors to specify which elements will change color.
For example, you could try
$('div').click(function() { // Will change the color of the divs
var v = $(this).text();
alert(v); // this prints nothing !!!!
$(this).css("color", "red");
});
$('p').click(function() { // Will change the paragraphs
...
});
$('p, div').click(function() { // Will work for either one!
...
});
$('*').click(function() { // Will work for any element on the page
...
});
In your
$(this).click(function () {
"this" doesn't refer to where the <script> tag is located, but rather it refers to window object. So in essence your code does this:
$(window).click(function (){
If you want the cow to turn red, when clicking it, change HTML to:
<div id="cow">Cow</div>
And your script:
// callback needs to be inside $(document).ready(fn) to make sure the DOM is ready when trying to use it
$(document).ready(function () {
// and we need to refer to an explicit element
$('#cow').click(function (){
// now we can refer to "this", since inside the click handler's context is the clicked element
$(this).css({color: 'red'});
});
}
You must specify to which element you wanna add a click event. E.g. this will work for all the div-elements:
$('div').click(function () {
$(this).css("color", "red");
});
You need to wrap that in a document ready statement, and attach the click listener to an actual element:
$(function(){
$("*").click(function () {
$(this).css("color", "red");
});
});
Your selector could look something like $("div, p").click(...) depending on which elements you want to be active.

Event handler triggered twice instead of once

I am sorry that I have asked two questions in a few minutes.
In a html file, I got three child DIV tags in a parent DIV tag:
<div id="container">
<div id="frag-123">123</div>
<div id="frag-124">124</div>
<div id="frag-125">125</div>
</div>
Now when I click either the three child DIV tags, I will see two alert boxes pop up instead of one:
The first alert box will show something like this:
frag-123, and the second alert box will show something like this:
container
I dont know why.
I just want to get the ID value of a child DIV, not the one from the parent DIV.
<script>
$(function() {
$("div").click(function() {
var imgID = this.id;
alert(imgID);
});
});
</script>
Please help.
This is a case of event bubbling. You can stop event bubbling by giving
e.stopPropagation()
inside the click event handler.
Try
$(function() {
$("div").click(function(e) {
var imgID = this.id;
alert(imgID);
e.stopPropagation() // will prevent event bubbling
});
});
If you want to bind click event to only child elemets inside the container div then you can give like this
$("#container div").click(function(){
var imgID = this.id;
alert(imgID);
});
That's because you're binding the event handler to all DIVs. Instead, what you want is bind it only to DIVs within container:
<script type="text/javascript">
$(function() {
$("#container div").click(function() {
var imgID = this.id;
alert(imgID);
});
});
</script>

Categories