I have a list maker that appends items but also appends a trash can item to each of the list items which is made. I have a function on the trash can that should remove the parent element when it is clicked but it doesn't work.
Here is a simple version of what I'm trying to do
JSFiddle
$('button').click(function() {
$('#contain').append('<div class="div"></div>').append('<div class="nested"></div>');
});
$('.nested').click(function() {
$(this).parent().remove();
});
How can I remove the parent element of only the nested div that is clicked?
Use on() because you're calling an event on dynamically appended element.
$('body').on('click', '.nested', function(){
$(this).parent().remove();
});
Also we can use $('#contain') instead of $('body') as well.
$('button').click(function() {
$('#contain').append('<div class="div"></div>').append('<div class="nested"></div>');
});
$('body').on('click', '.nested', function() {
$(this).parent().remove();
});
.div {
width: 100px;
height: 50px;
background: #000;
margin-top: 50px;
}
.nested {
width: 50px;
height: 25px;
background: red;
z-index: 100;
margin-top: -25px;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Add
</button>
<div id="contain">
</div>
try this:
$('#contain').on('click', '.nested', function(){
});
you have to listen to clicks on the container for appended elements, since they're not in the DOM when the page is loaded
Two issues:
As the others have mentioned, you're binding your .nested click
event before your element is created, meaning it won't have the
event handler attached. As the others mentioned, something like $("#contain").on("click", ".nested", function() {}) will fix the issue
$.append returns the element you are appending to not the element being appended so your .nested is nested under the $("#contain"). This means the $(this).parent() is actually returning the #contain element. A fix for the issue is
$("<div class='nested' />").appendTo($("<div class='div' />").appendTo("#contain"));
Change :
$('.nested').click(function() {
$(this).parent().remove();
});
To:
$(document).on("click",".nested",function(){
$(this).parent().remove();
})
Related
I was tripping over an odd bug in my code where an event on a parent element appeared to fire before the event on it's child, meaning that my e.stopPropagation() had no effect.
Demo:
$(document).ready(function() {
// Binding directly to the elements
$(".red1").on("click", function(e) {
alert("Clicked red1");
});
$(".green1").on("click", function(e) {
alert("Clicked green1");
e.stopPropagation();
});
// Binding the child from a descendant selector
$(".red2").on("click", function(e) {
alert("Clicked red2");
});
$("body").on("click", ".green2", function(e) {
alert("Clicked green2");
e.stopPropagation();
});
});
.red1,
.red2 {
display: inline-block;
width: 200px;
height: 200px;
background-color: #800;
}
.green1,
.green2 {
display: inline-block;
width: 100px;
height: 100px;
background-color: #080;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="red1">
<div class="green1"></div>
</div>
<div class="red2">
<div class="green2"></div>
</div>
Clicking the green square on the left works as expected and shows a single alert.
Clicking the green square on the right appears to fire the parent's event, followed by the child's.
I assume that this is due to a misunderstanding of how the binding works on my part, but I can't seem to get my head around why they're occurring in this order.
Can anyone explain why this is happening?
The issue is because you're using a delegated event handler.
This means that for the event to fire it has to bubble up to the designated parent element (body in your case). As the event passes through .red2 the static handler you assigned to that element fires. Then delegated event handler checks to see if the event originator was .green2. If it was then delegated event handler is executed. This is why the parent handler fires first.
To avoid this behaviour, you can either avoid delegated event handlers, which isn't always possible as they are incredibly useful, or place all events on the parent elements, and check the originator manually, like this:
$(".red2").on("click", function(e) {
if ($(e.target).is('.green2')) {
alert("Clicked green2");
e.stopPropagation();
} else {
alert("Clicked red2");
}
});
.red1,
.red2 {
display: inline-block;
width: 200px;
height: 200px;
background-color: #800;
}
.green1,
.green2 {
display: inline-block;
width: 100px;
height: 100px;
background-color: #080;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="red2">
<div class="green2"></div>
</div>
This probably cannot be done, but I have a fixed-position div on top of inline html in the page body. The inline html has clickable elements, and the fixed div has a hover event.
The fixed element is an empty div, so it is invisible.
Currently, the fixed element is blocking click events on the item under it.
Is it possible?
This solution is too complicated
https://stackoverflow.com/a/9616491/209942
Possible solution?
https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events
Thx
The fixed element should not be prevent the clicks from the item under it unless you are stopping the event propagation.
See this fiddle: https://jsfiddle.net/pv0mygz5/
-- it demonstrates that without event.stopPropagation the event should be intercepted by the listener on the span element.
$('#click-me').on('click', function (e) {
console.log('click triggered');
});
$('.box').on('mouseover', function (e) {
//don't stop event from bubbling
console.log('hover triggered');
});
Could you also include a code snippet that demonstrates your problem?
although IE10 doesn't support it you can use
pointer-events: none;
http://jsfiddle.net/leaverou/XxkSC/light/
In this fiddle you can see a drop down being covered with other elements, the other elements has pointer-events: none so you can click on the arrow down button and the click actually goes to the select element itself.
BR,
Saar
You can also try using z-index. Depending on your layout it may not be a solution, but if your front div is invisible, then it shouldn't create unwanted effect. Like this for example:
document.querySelector('#under').addEventListener('click', function(e) {
e.target.style.color = "blue";
});
document.querySelector('#notunder').addEventListener('click', function(e) {
e.target.style.color = "blue";
});
#fix {
width: 60px;
height: 200px;
position: fixed;
z-index: -1;
top: 0px;
border: 1px solid black;
}
#under {
display: inline;
}
#fixnozindex {
width: 100px;
height: 200px;
position: fixed;
left: 75px;
top: 0px;
border: 1px solid black;
}
#notunder {
display: inline;
}
<div id="fix"></div>
<div id="under">Clickable</div>
<div id="fixnozindex"></div>
<div id="notunder">Not clickable</div>
I want to create a circle everytime I click the button but the once I click it, it creates a circle but when i click it again nothing happen.
$(document).ready(function() {
var circle = $("<div class='circleClass'></div>");
$(".t-testbody").on("click", "#clickMe", function() {
$(".t-testbody").append(circle);
});
});
.t-testbody {
margin-top: 100px;
margin-left: 50px;
}
.circleClass {
width: 50px;
height: 50px;
border-radius: 100%;
background-color: blue;
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="t-testbody">
<div class="circleClass"></div>
<button id="clickMe">Button</button>
</div>
Currently you have created the element and appended it to the div. so second append statement has not effect as the element already exist in the div.
Instead of element use HTML string
var circle = "<div class='circleClass'></div>";
$(".t-testbody").on("click", "#clickMe", function () {
$(".t-testbody").append(circle);
});
DEMO
You can use .clone()
var circle = $("<div class='circleClass'></div>");
$(".t-testbody").on("click", "#clickMe", function () {
$(".t-testbody").append(circle.clone());
});
DEMO
You are defining your HTML element only once, so instead of this
$(document).ready(function() {
var circle = $("<div class='circleClass'></div>"); // Move this into event handler callback
$(".t-testbody").on("click", "#clickMe", function() {
$(".t-testbody").append(circle);
});
});
Do this:
$(document).ready(function() {
$(".t-testbody").on("click", "#clickMe", function() {
var circle = $("<div class='circleClass'></div>"); // Move this here
$(".t-testbody").append(circle);
});
});
What's happening is that jQuery creates the HTML element, then on click it moves that element to the div. When you click it again, it moves that same element into where it just was, giving the illusion that it did nothing, but it just moved it into the position it already was.
When you move the variable declaration into the callback, it will generate a new html element every time you click that element, therefore jQuery will be appending a newly defined element to the div.
circle holds the reference of element being appended. So it has no difference after first click.
You can create circle inside the callback function like this :
$(document).ready(function(){
$(".t-testbody").on("click","#clickMe",function(){
var circle = $("<div class='circleClass'></div>");
$(".t-testbody").append(circle);
});
});
.t-testbody {
margin-top: 100px;
margin-left: 50px;
}
.circleClass {
width: 50px;
height: 50px;
border-radius: 100%;
background-color: blue;
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="t-testbody">
<div class="circleClass"></div>
<button id="clickMe">Button</button>
</div>
Demo : http://jsfiddle.net/vikashvverma/ou52j2xn/
I spent a few hours last night trying to figure out what was going wrong here, but was unsuccessful.
I have a div that when clicked will expand and create a close button that will return the div to its original state. I am doing this by adding and remove classes. The issue I am having is that when the original div (.talent) is clicked it does change to fill the containing div. However when the button (.btn) is clicked the div does not return to its original state.
JS -
$(".talents .talent").click(function(){
if ($(this).hasClass("talent")) {
$(this)
.removeClass("talent")
.addClass("tree")
.append("<div class=\"close btn\">X</div>");
$(".tree .btn").click(function(){
console.debug("WORKING!?!?!?");
$(".tree").addClass("talent");
$(".tree").removeClass("tree");
$(".talents .talent").show();
$(this).remove();
});
$(".talents .talent").hide();
}
});
CSS -
.talents{
border:1px solid white;
border-radius:10px;
overflow:hidden;
height:165px;
margin:10px;
}
.talents .talent{
text-align:center;
font-size:2.4em;
height: 50px;
width: 50px;
background-repeat: no-repeat;
background-position: center;
background-size: 100% 100%;
display: inline-block;
border: 3px solid white;
border-radius: 15px;
margin: 5px 7px 5px 7px;
}
.tree{
position:relative;
width:100%;
height:100%;
}
$(".talents .talent").click(function(){
if ($(this).hasClass("talent")) {
THE ABOVE CODE WILL ALWAYS EVALUATE TO TRUE
if you want this to work better, whatever element has the class of talent should also have another class, and work similiar like this(I would say use .tree as .other_class but can't be 100% certain without seeing html):
$(".talents .other_class").click(function(){
if ($(this).hasClass("talent")) {
Also, it would be a better practice to keep the btn click handler outside the first click handler.
Events are bound to the elements in question, not to a specific class. You need to delegate the events in such cases as the classes are being added dynamically.
In your case if you put a debug point you can see the issue properly. Th event bubbles up to the parent which at that time is .talent . So first it works as expected when clicked on close, but then fires the click event on .talent again which places the tree class on that element again. Event delegation should solve this problem.
$(".talents").on('click', ".talent", function () {
$(this)
.removeClass("talent")
.addClass("tree")
.append("<div class=\"close btn\">X</div>");
$(".talents .talent").hide();
});
$(".talents").on('click', ".tree .btn", function () {
console.debug("WORKING!?!?!?");
$(".tree").addClass("talent");
$(".tree").removeClass("tree");
$(".talents .talent").show();
$(this).remove();
});
Check Fixed Fiddle
Haven't tested but another problem may be because the class .tree is appended dynamically. Also try using on like:
$(document).click('.tree .btn',function(){
console.debug("WORKING!?!?!?");
$(".tree").addClass("talent");
$(".tree").removeClass("tree");
$(".talents .talent").show();
$(this).remove();
});
First remove the class and then try to add a class and see if it is working.
$(".tree").removeClass("tree");
$(".tree").addClass("talent");
I'm experiencing some problems with jQuery's slideUp and slideDown functions. If you go to this site
www.confide.re/confide
and click on one of the boxes, it normally works fine, but after you scroll the page and it loads some more boxes, then the slide function bugs and does it twice for no reason, if you get what I mean.
Is this something I've done wrong somewhere or is this a known bug?
Thanks
Here is the code:
var state = 'down';
$('.overlay').click(function() {
if(state == 'down') {
$(this).next().slideDown(155);
state = 'up';
} else {
$(this).next().slideUp(150);
state = 'down';
}
.overlay is a transparent div on top of each of the boxes.
Define your click event outside your ajax success callback like this (Use a better selector that body, it is just for the example)
$("body").on("click", ".overlay", function(e){
$(this).next().slideToggle(150);
$(this).css('background-color', 'rgba(0,0,0,0)');
});
you should do something like this: http://jsfiddle.net/chanckjh/Jak6Q/
html:
<div class="something">
<div class="bar">
</div>
</div>
jquery:
$(function() {
$('.something').click(function() {
$('.bar').slideToggle();
});
});
css:
.something{
width: 500px;
height: 500px;
border: 1px solid red;
}
.bar{
display: none;
width: 500px;
height: 50px;
background: blue;
}
or like this for the child: http://jsfiddle.net/chanckjh/Jak6Q/1/
$(function() {
$('.something').click(function() {
$(this).find('.bar').slideToggle();
});
});
You can not share a single variable state amongst many elements which need to record their specific status. Instead, you have to keep state for each of the elements.