<script>
$(".image-popup").on('click', function() {
$(this).find(".myModal").addClass("modal-active");
$(".modal-active").css("display", "block");
});
$(".close").on('click', function() {
$(".modal-active").css("display", "none");
var myVar = $(this).closest(".image-popup");
myVar.find(".myModal").removeClass("modal-active");
$(".modal-active").css("display","none");
});
</script>
I am attempting to have a modal appear and then disappear when I click the close button. The problem is that the removeClass() will not work and the "display", "none" will not override the first click function. Any Help?
My guess from your question and your comment above is that the event from your second handler is bubbling up to your first handler:
$(".image-popup").on('click', function() {
$(this).find(".myModal")
.addClass("modal-active")
.show();
});
$(".close").on('click', function(evt) {
evt.preventDefault();
$(this).closest(".image-popup")
.find(".myModal")
.removeClass("modal-active");
.hide();
});
Try to prevent the event from bubbling out of the .close handler by using evt.preventDefault();
You can fix it with this simple solution:
HTML
<div class="image-popup">
<div class="show-modal btn btn-success">Show Modal</div>
<div class="myModal">
<div class="close btn btn-success">Close</div>
<p>My Modal is active</p>
</div>
</div>
CSS
.modal-active .myModal{
display: block;
}
.myModal{
display:none;
}
.close{
color:red;
display:block;
}
JS
$(function(){
$('.show-modal').click(function(){
$(this).parent().addClass('modal-active');
});
$('.close').click(function(){
$(this).closest('.image-popup').removeClass('modal-active');
});
});
See this fiddle for more details https://jsfiddle.net/a3yze54w/1/
Related
I have a div that expands when clicked. I also have a link inside this div. Expected behavior is for the click event to be ignored when the link is clicked, but obviously clicking anywhere in the div will trigger the event. I've tried stopPropagation(), but it doesn't seem to work.
$('#infobox').on('click', expandFunction);
$('#infobox a').on('click', function(event) {
event.stopImmediatePropagation();
});
<div class="infobox">
Link
</div>
function expandFunction() {
alert("expanded")
}
document.getElementById("infobox").addEventListener('click', function (event) {
if (event.target.tagName != event.currentTarget.tagName) return;
expandFunction();
});
document.querySelector("#infobox a").addEventListener('click', function (event) {
alert("linkclicked")
})
div{
padding:15px;
background-color:gray;
}
a{
padding:15px;
background-color:silver;
color:white;
margin:5px;
display:inline-block
}
<div id="infobox" class="infobox">
Link
</div>
first you must set Id for infobox
<div id="infobox" class="infobox">
you can use this code to prevent click from other elements
$('#infobox').on('click', function(event){
if(event.target.id!= event.currentTarget.id) return;
expandFunction();
});
This question already has an answer here:
toggleclass not binding click event
(1 answer)
Closed 4 years ago.
I have no idea why this is not working. Seems like such a simple concept. I have some classes being toggled when a button is clicked. These classes just control the display of text open menu and close menu. That part is working, however, I need to have some additional scripts run when the button is clicked when its in it's opened state. When I click the button when it has the class opened then nothing in my button.opened click function happens.. it just runs the button.closed function. What am I doing wrong?
https://jsfiddle.net/dmcgrew/sfvhtahq/7/
$("button.closed").on("click", function(){
console.log("open the menu");
$(this).toggleClass("opened");
$(this).toggleClass("closed");
});
$("button.opened").on("click", function(){
//why does nothing in here happen?
console.log("close the menu");
$(this).toggleClass("opened");
$(this).toggleClass("closed");
});
.expand {width:100px; height:100px; background:red; display:block;}
.close, .open {display:none;}
.opened .close {display:inline;}
.closed .open {display:inline;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="expand closed"><span class="open">open menu</span><span class="close">close menu</span></button>
When you assign these event handlers, no button with class "opened" exists, so that event doesn't get attached to anything.
The easiest way to solve this is to instead assign delegated event handlers to a DOM element that does already exist. Now it doesn't matter whether button.closed or button.opened existed when the handler was assigned; it will check for the existence of the child node when the event occurs.
(In practice it's better to not hang everything on the body; choose a DOM node that's a closer parent to the nodes you're delegating to, but for now body will do:)
$("body").on("click", "button.closed", function(){
console.log("open the menu");
$(this).toggleClass("opened");
$(this).toggleClass("closed");
});
$("body").on("click", "button.opened", function(){
console.log("close the menu");
$(this).toggleClass("opened");
$(this).toggleClass("closed");
});
.opened .open, .closed .close {display:none}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="expand closed">
<span class="open">open menu</span>
<span class="close">close menu</span>
</button>
Meanwhile: it's rarely necessary to have two separate classes controlling the same state change. Treat one state as the default, and add CSS rules only for the other state:
$('body').on("click", "button", function() {
$(this).toggleClass("opened");
if ($(this).hasClass('opened')) {
console.log("opened the menu")
} else {
console.log("closed the menu")
}
});
.expand .close,
.expand.opened .open {
display: none
}
.expand.opened .close {
display: block
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="expand">
<span class="open">open menu</span>
<span class="close">close menu</span>
</button>
Since the .opened class does not exist on the button at assignment, you will have to use an event-delegation approach. Like so:
<div class="dynamic-button">
<button class="expand closed">
<span class="open">open menu</span>
<span class="close">close menu</span>
</button>
</div>
$(".dynamic-button").on("click", "button.closed", function(){
console.log("open the menu");
$(this).toggleClass("opened");
$(this).toggleClass("closed");
});
$(".dynamic-button").on("click", "button.opened", function(){
console.log("close the menu");
$(this).toggleClass("opened");
$(this).toggleClass("closed");
});
For more explanation, read more about $.on().
Try unbinding the click event first and then binding it again.
$("button.opened").off("click").on("click", function(){
console.log("close the menu");
$(this).toggleClass("opened");
$(this).toggleClass("closed");
});
I have managed to create a button that shows my div. but I want to have the button disappear as that happens.
At the moment my button only disappears the second time I click it. Any help appreciated.
$(document).ready(function() {
$('.click').click(function() {
$('#contact-form').toggle('slide', 500)
$('.click').toggle();
});
});
.click {
display: block;
}
#contact-form {
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="click">click</button>
<div id="contact-form"></div>
The reason why it is not working is, you are mixing the display between CSS and JavaScript. jQuery uses the current inline style to check if the button is hidden to display it, when you use .toggle(). Since it doesn't have anything at first, it adds a display: block (or whatever the initial value is) and then when you do the second time, it correctly identifies and removes.
The best thing to do is to use classes. I would suggest something like this parent class.
$(document).ready(function() {
$('.click').click(function() {
$("body").toggleClass("contact-form-open");
});
});
.contact-form-open .click,
#contact-form {
display: none;
}
.contact-form-open #contact-form {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="click">Click Me</button>
<div id="contact-form">
Contact Form
</div>
This way, you control everything using CSS and you don't mess up with the event listeners or add the yucky inline CSS.
I've tried what you've tried and it seems to be working. Maybe it's because you don't close the div tag ?
$(function() {
$('.click').click(function() {
$('.myDiv').toggle();
$('.click').toggle();
})
});
http://plnkr.co/edit/wD0bwf8XK3CFXXM7rVWF?p=preview
but I want to have the button disappear as that happens.
So just use hide() instead of toggle :
$('.click').click(function() {
$('.click').hide();
$('#contact-form').toggle('slide', 500)
});
Hope this helps.
$(document).ready(function() {
$('.click').click(function() {
$('.click').hide();
$('#contact-form').toggle('slide', 500)
});
});
#contact-form {
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="click">click</button>
<div id="contact-form">Form content</div>
More easy:
$(document).ready(function() {
$('.click').click(function() {
$("#contact-form").show();
$(this).remove();
});
});
#contact-form{display:none;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="click">Click Me</button>
<div id="contact-form">
Contact Form
</div>
<script>
$(".alert").click(function(){
$(this).fadeOut(300, function(){
$(this).remove();
});
});
</script>
<div class="alert alert-error">
<h4>title</h4>
<textarea class="pull-right">text...</textarea>
</div>
So the above code works perfectly except that I need to make it so that a user can select the text inside the textarea. At this moment logically when they click the textarea, as its contained by .alert, it instantly gets removed with the div.
I can't remove the textarea from the div as I need it both contained by the div, and removed when other parts of the div are clicked.
So how can I specifically exclude the textarea from the click event of its containing div while still allowing the click event from the containing div to remove the textarea.
You can do this by preventing the click event from propagating (bubbling) from the textarea to the div:
$(".alert textarea").on("click", function(e) {
e.stopPropgation();
});
Example:
$(".alert").click(function(){
$(this).fadeOut(300, function(){
$(this).remove();
});
});
$(".alert textarea").on("click", function(e) {
e.stopPropagation();
});
<div class="alert alert-error">
<h4>title</h4>
<textarea class="pull-right">text...</textarea>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Alternately, in your existing handler, check to see if the event passed through the textarea:
$(".alert").click(function(e){
if (!$(e.target).closest("textarea").length) {
$(this).fadeOut(300, function(){
$(this).remove();
});
}
});
Example:
$(".alert").click(function(e){
if (!$(e.target).closest("textarea").length) {
$(this).fadeOut(300, function(){
$(this).remove();
});
}
});
<div class="alert alert-error">
<h4>title</h4>
<textarea class="pull-right">text...</textarea>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Note that that second one relies on the fact that your .alert element can never be inside another textarea, because of the nature of the elements. It won't work in the general case. This would, but it's a pain:
$(".alert").click(function(e){
var $t = $(e.target);
if (!$t.is("textarea") && !$t.parentsUntil(this, "textarea").length) {
$(this).fadeOut(300, function(){
$(this).remove();
});
}
});
you can also use the not selector to do this :
<script>
$(".alert *:not(textarea)").click(function(){
$(this).fadeOut(300, function(){
$(this).parent().remove();
});
});
</script>
<div class="alert alert-error">
<h4>title</h4>
<textarea class="pull-right">text...</textarea>
</div>
see this fiddle: https://jsfiddle.net/zLq6dztu/
HTML:
<div id="accordion">
<div class="top">
Show all | Hide all
</div>
<div class="body">
<div class="item">
item1
<div class="content">
<p>
Item1 content;
</p>
Back to top
</div>
</div>
<div class="item">
Item2
<div class="content">
<ul>
<li>item2 content;</li>
<li style="list-style: none">Back to top</li>
</ul>
</div>
</div>
</div>
</div>
JS:
$("#accordion .content").slideUp();
$("#accordion .item a.head").click(function (e) {
//open tab when click on item
e.preventDefault();
$(this).toggleClass('active');
$(this).next().stop().slideToggle();
if ($(this).hasClass('active')) {
$(this).attr('title', 'hide');
} else {
$(this).attr('title', 'show');
}
});
$("#accordion .showAll").click(function (e) {
//open all tab
e.preventDefault();
$("#accordion .item a").each(function () {
if (!$(this).hasClass('active')) {
$(this).click();
}
});
});
$("#accordion .hideAll").click(function (e) {
//hide all tab
e.preventDefault();
$("#accordion .item a").each(function () {
if ($(this).hasClass('active')) {
$(this).click();
}
});
});
$(".backToTop").click(function (e) {
//scroll to top
e.preventDefault();
$('body, html').animate({
scrollTop: 0
}, 450);
});
basically it's an accordion, a very simple one done in jquery
JSfiddle here:
http://jsfiddle.net/PqaXZ/6/
(note*: you have to scroll down to see the example)
Anyone can explain why I click "Show All" button, it trigger a click on "Back to top" button?
I don't see anything can possibly cause it in the code
Thanks a lot in advance
Well, in your "show all" click handler, you're clicking all "inactive" links in the accordion:
$("#accordion .item a").each(function () {
if (!$(this).hasClass('active')) {
$(this).click();
}
});
If at least one of the "back to top" links anywhere in the accordion doesn't have the class "active", you're triggering its click event.
Because you're triggering a click on it.
$("#accordion .item a") includes the "show all" button, then you promptly $(this).click(); which simulates a user clicking on that link. Hence, sending them back to top.
Because you are using spaces inside your selector, it is 'clicking' on any a under any .item that is under the #accordion, which includes your 'back to the top' button. If you instead make your selector: #accordion .item>a, then it will only 'click' on as that are immediate children of .items.
#accordion .item a is triggering all the links inside .item you should use
#accordion .item > a
to trigger al the first links but not the childs