Event handler triggered twice instead of once - javascript

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>

Related

get Contenteditable div html

Jsfiddle at demo.
I have a contenteditable div. I want the html of whatever I write in that div, on the click of anchor tag.
Right now, div is working but nothing is showing on click of the anchor tag.
function getcode()
{
var content = $('#my-contenteditable-div').html();
alert (content);
}
You can do this as well:
$("a").click(function () {
alert($('#my-contenteditable-div').html());
});
Here is the JSFiddle
Then you don't need to write separate functions and attach it to the onclick event attribute of the a tag
Try This
// get the link
var link = document.getElementById("linkId");
// add click listener to it
link.addEventListener("click",getcode,false);
// you handler
function getcode()
{
var content = document.getElementById("my-contenteditable-div");
alert (content.innerHTML);
}
Just you can go with jquery
Working Fiddle
$(document).ready(function() {
$('#gethtml').on('click', function(e) {
var content = $('#my-contenteditable-div').html();
alert (content);
});
});
can use this use id in a and a div to show data
<div contenteditable="true" id="my-contenteditable-div">
sdfsdfds
</div>
<a href="#" id="getcode" >Get HTML</a>
<div id="show"></div>
and jQuery
$( "#getcode" ).click(function() {
var contents = $('#my-contenteditable-div').html();
$("#show").text(contents);
});

How to corectly bind events in a loop

On a page I have couple of divs, that look like this:
<div class="product-input">
<input type="hidden" class="hidden-input">
<input type="text">
<button class="remove">X</button>
</div>
I'm trying to bind an event to that remove button with this code (simplified):
$('.product-input').each(function() {
product = $(this);
product_field = product.find('.hidden-input');
product.on('click', '.remove', function(event) {
product_field.val(null);
});
});
It works perfectly when there is only one "product-input" div. When there is more of them, all remove buttons remove value from the hidden field from the last product-input div.
https://jsfiddle.net/ryzr40yh/
Can somebody help me finding the bug?
You dont need to iterate over the element for binding the same event. you can rather bind the event to all at once:
$('.product-input').on('click', '.remove', function(event) {
$(this).prevAll('.hidden-input').val("");
});
If the remove buttons are not added dynamically, you will not need event delegation:
$('.remove').click(function(event) {
$(this).prevAll('.hidden-input').val("");
});
Working Demo
You need to declare product and product_field as local variables, now they are global variables. So whichever button is clicked inside the click handler product_field will refer to the last input element.
$('.product-input').each(function() {
var product = $(this);
var product_field = product.find('.hidden-input');
product.on('click', '.remove', function(event) {
product_field.val(null);
});
});
Demo: Fiddle
But you can simplify it without using a loop as below using the siblings relationship between the clicked button and the input field
$('.product-input .remove').click(function () {
$(this).siblings('.hidden-input').val('')
})
Demo: Fiddle

jQuery click handler only fires once

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()."

How to remove class after it been added

So I need a little bit of help. I'm playing around with addClass and removeClass and I can't seem to remove a class after it's set. What I basically want is:
When someone clicks an h3, it adds to its parent div class
When someone clicks a div with added class, class needs to be removed
First step I got out of way and it's working
$(function(){
$('div h3.itemTitle').on('click', function(){
$(this).parent().addClass('active').siblings().removeClass('active');
});
});
Now when I define:
$(function(){
$('div.active').on('click', function(){
$(this).removeClass('active');
});
});
It does nothing, as if it doesn't see classes. It sets only those set in onload...
Help, anyone?
The child element "h3.itemTitle" already had a click event listener on it and the parent can't actually capture the click event.
Your $('div.active').on('click', ...) never actually fires because you click the h3 not the div.
I recommend this approach: http://jsfiddle.net/c3Q6Q/
$('div h3.itemTitle').on('click', function () {
// saves time not to write $(this).parent() everything so i store in a _parent var
var _parent = $(this).parent();
if (_parent.hasClass('active')) {
_parent.removeClass('active');
} else {
_parent.addClass('active').siblings().removeClass('active');
}
});
Try
$('body').on('click','div.active', function(){$(this).removeClass('active');});
Instead of
$('div.active').on('click', function(){$(this).removeClass('active');});
I would go with this way:
$('div').on('click', function(e){
var el = e.target;
if($(el).is('h3') && $(el).hasClass('itemTitle')){
$(this).parent().addClass('active').siblings().removeClass('active');
}else if($(el).is('div') && $(el).hasClass('active')){
$(this).removeClass('active');
}
});
Not sure why every is talking about elements generated outside of the initial DOM load.
Here's a JSFiddle showing that it works: http://jsfiddle.net/H25bT/
Code:
$(document).ready(function() {
$('.itemTitle').on('click', function() {
$(this).parent().addClass('active').siblings().removeClass('active');
});
/* $('.parent').on('click', function() {
$(this).removeClass('active');
}); */
$('.clicky').on('click', function() {
$(this).parent().removeClass('active');
});
});
The reason it's not working for you is that if you put the removeClass click event on the parent div itself, clicking on the child text causes a conflict with which click handler to use, and it won't work out. Code works fine if you don't assign the click to the parent div itself.

jquery onclick penetrating to parent element

How would I stop onclick for an inner element from also clicking through to its parent element.
<div id="1" onclick="alert('1')">
<div id="2" onclick="alert('2')"></div>
</div>
If the second div (id="2") is visibly on top of the first, and it is clicked, You will get both alerts 1 & 2.
How can I avoid this so I only get the alert from what I'm (visibly) clicking on,
Without completely disabling any onclick function the outer div may possess.
Example: http://jsfiddle.net/DPCx8/
​var outer = document.getElementById('outer');
outer.onclick = function(event)
{
alert('outer');
event.stopPropagation();
}​​
var inner = document.getElementById('inner');
inner.onclick = function(event)
{
alert('inner');
event.stopPropagation();
}
http://jsfiddle.net/DYykA/1/
You need to stop the propagation at the child, so the event doesn't bubble up to the parent.
$("#inner").on("click", function(e){
e.stopPropagation();
});
use event.stopPropogation(); to prevent bubbling of event

Categories