Here's the situation. There is button and there is hidden div. After user clicks the button, hidden div appears and in the same time I'm adding event listener on body using on() to check if user clicked out of this hidden div. After that div should be hidden again and click event detached.
Everything works fine but only when user clicks the button. If I trigger click using trigger() function then on() function is called immediately and hidden div is not appearing.
Here is the code:
$('button').click(function(e){
e.stopPropagation();
$('div').toggleClass('active');
if($('div').hasClass('active')){
$('body').on('click.div', function(e){
console.log('body clicked')
if(! $(e.target).closest('div').length){
$('div').removeClass('active');
$('body').off('.div');
}
});
}else{
$('body').off('.div');
}
});
$('input').click(function(){
$('button').trigger('click');
});
div{
display: none;
}
div.active{
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Click</button>
<div>This is hidden</div>
<input type="button" value="Trigger">
I found also solution how to solve this problem, but I still dont know why using trigger() and stopPropagation() does not work.
Here is fixed code with using setTimeout():
$('button').click(function(e) {
e.stopPropagation();
$('div').toggleClass('active');
if ($('div').hasClass('active')) {
setTimeout(function() {
$('body').on('click.div', function(e) {
console.log('body clicked')
if (!$(e.target).closest('div').length) {
$('div').removeClass('active');
$('body').off('.div');
}
});
}, 0);
} else {
$('body').off('.div');
}
});
$('input').click(function() {
$('button').trigger('click');
});
div {
display: none;
}
div.active {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Click</button>
<div>This is hidden</div>
<input type="button" value="Trigger">
The reason is that the click on the input that you responded to by calling trigger propagates to body, and so it gets handled by the body handler you add. That is, the click that triggers this event handler:
$('input').click(function(){
$('button').trigger('click');
});
...gets processed; and then of course you're sending another one later.
To fix it, just stop that click from propagating:
$('input').click(function(e){
e.stopPropagation();
$('button').trigger('click');
});
$('button').click(function(e){
e.stopPropagation();
$('div').toggleClass('active');
if($('div').hasClass('active')){
$('body').on('click.div', function(e){
console.log('body clicked')
if(! $(e.target).closest('div').length){
$('div').removeClass('active');
$('body').off('.div');
}
});
}else{
$('body').off('.div');
}
});
$('input').click(function(e){
e.stopPropagation();
$('button').trigger('click');
});
div{
display: none;
}
div.active{
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Click</button>
<div>This is hidden</div>
<input type="button" value="Trigger">
The reason your setTimeout version worked is that you were delaying hooking up your body click handler until after the click on the input had reached body, so it didn't get triggered by the click on the input.
Related
Haai. I have a problem. How to I hide this button when I click outside of <input type="search">. The button show when I click <input type="search">but I don't know how to hide the button when we click outside the <input type="search">. Any idea?
HTML
<input type="search">
<button type="submit" class="search_btn" name="button">Search</button>
Jquery
$("input[type='search']").click(function() {
$(".search_btn").addClass("search_on");
});
$("*:not('input[type='search']')").click(function() {
$(".search_btn").removeClass("search_on");
});
You're looking for the blur event.
When you click on the input, it receives focus, when you leave (by clicking, keyboard interaction, etc.) it loses focus and triggers blur. So:
$("input[type='search']").blur(function () {
$(".search_btn").removeClass("search_on");
})
It might also be a good idea to use the focus event instead of click on Line 1 so that users can also tab into the field and have it work correctly:
$("input[type='search']").focus(function() {
$(".search_btn").addClass("search_on");
})
$("input[type='search']").blur(function () {
$(".search_btn").removeClass("search_on");
});
See also:
https://api.jquery.com/focus/
https://api.jquery.com/blur/
Most likely what you want can be accomplished with the focus and blur events.
$("input[type='search']").focus(function() {
$(".search_btn").addClass("search_on");
});
$("input[type='search']").blur(function() {
setTimeout(function () {
$(".search_btn").removeClass("search_on");
}, 50);
});
You'll need a timeout to allow the button to still be clicked, since clicking the button will cause the input to be blurred.
UseremoveClass
$(document).on('click', function(event) {
if (event.target.id !== 'submitButton' && event.target.id !== "search") {
$(".search_btn").removeClass("search_on");
}
})
$("input[type='search']").on({
click: function() {
$(".search_btn").addClass("search_on");
}
});
$("#submitButton").click(function() {
console.log($("#search").val())
})
.search_btn {
display: none
}
.search_on {
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="search" id="search">
<button type="submit" id="submitButton" class="search_btn" name="button">Search</button>
using event focus and blur:
$("input[type='search']").focus(function() {
$(".search_btn").addClass("search_on");
})
$("input[type='search']").blur(function () {
$(".search_btn").removeClass("search_on");
});
You can use focus and blur events. When control is inside the textbox, focus event is called. When control leaves the textbox, blur event is called.
$(document).ready(function() {
$("input[type='search']").focus(function() {
$("button[type='submit'].search_btn").addClass("search_on");
})
$("input[type='search']").blur(function () {
$("button[type='submit'].search_btn").removeClass("search_on");
});
});
.search_on { background-color: yellow; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="search">
<button type="submit" class="search_btn" name="button">Search</button>
I have this code:
$(function() {
$('#toggle4').click(function() {
$('.toggle4').slideToggle('fast');
return false;
});
});
Which works great and shows the '.toggle4' div but I want to hide it again when clicking outside/away from it.
So I added this:
$(document).click(function() {
$(".toggle4").hide();
});
Which works but it hides the div even when I click inside of the '.toggle4' div (it's an input box for a search form).
Any ideas? Thanks.
That's because when you click inside of .toggle4 that click event bubbles up the DOM and triggers the event you bound to the document. You should be able to fix that with something like:
$('.toggle4').click(function(e){
e.stopPropagation()
})
One possibility is to prevent the click event from bubbling up to the document if it took place inside the toggle.
$(function() {
$('#searchField').click(function() {
$('#toggle').slideToggle('fast');
return false;
});
});
$(document).click(function() {
$("#toggle").hide();
});
$("#toggle").click(function(e) {
e.stopPropagation();
});
#toggle {
width: 100px;
height: 100px;
background: red;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="searchField">
<div id="toggle" class="toggle4"></div>
I have in my project a window click eventListener and some click events on div elements. If i click on the div the click event on this div-element (correct) and the window click eventListener fires (not correct).
Can I bubble the div element that the window click eventListener do not fire the event?
For a better demonstration jsfiddle:
window.addEventListener('mouseup', onDocumentMouseUp, false);
function onDocumentMouseUp(event){
alert('dont fire this event on button click')
}
$('#button').on({
click: function (event) {
alert('button click event');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="button" style="height: 30px; width: 30px; background: blue"></div>
I hope somebody can help me.
Yes, you can use event.stopPropagation() like this:
$('#button').on({
click: function (event) {
alert('button click event');
event.stopPropagation();
}
});
I have this code
<style>
.Parent {width:500px;height:500px;background:#000}
.Parent .Child {width:250px;height:250px;background:#F00}
</style>
<div class="Parent">
<div class="child"></div>
</div>
<script>
$(document).ready(function() {
$('.Parent').click(function () {
$(this).hide()
});
/*
But if i click on <div class="Child"></div> ,
<div class="Parent"></div> won't get hidden .
*/
});
</script>
I want my code to hide'.parent',
When I click on areas in .Parent witch doesn't include .Child elementand if the areas I click was included in '.child' area , it don't do anything .
so what would u guys suggest ?
Simply make of event.stopPropagation(); to stop event of child from propagating to parent.
So script becomes:
$('.Parent').click(function () {
$(this).hide();
});
$('.child').click(function (e) {
e.stopPropagation();
});
See the fiddle: "http://jsfiddle.net/sftknxeo/1/"
just do this:
$('.Parent, .child').click(function(e) {
if ($(this).hasClass('child')) {
return false;
}
$(this).hide();
});
$('.Parent, .child').click(function(e) {
if ($(this).hasClass('child')) {
return false;
}
$(this).hide();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='Parent' style='width:auto; padding:50px; border:red solid 1px;'>
<div class='child' style='width:200px; height:200px;border:green solid 1px;'>
child
</div>
</div>
You can use the event's target to determine what you have clicked on. This way you can also assign an event to happen if you have clicked on the child. (If need be.)
$('.Parent').click(function(e){
if(e.target == this){
$(this).hide()
}
});
DEMO
Quick and dirty version would be simply to add another event handler. Add a click handler to child that hides parent. Then if you click on parent, it hides itself, and if you click on child, it hides parent.
$('.child').click(function (e) {
$('.parent').hide();
});
Not the most elegant solution, sure, but it's quick and easy and should get the job done.
$('.Parent').click(function () {
$(this).css("visibility", "hidden");
$(".Parent" ).children().css("visibility", "visible");
});
If you just want to hide parent then it will do the needful.
Check for the clicked element by looking at the target property of the event object. Here is something you might want to do:
$(function () {
$('.Parent').click(function (e) {
if ($(e.target).hasClass("child")) {
return false;
}
$(this).hide();
});
});
$('.parent').click(function(e) {
if ($(this).hasClass('child')) {
return false;
}
$(this).hide();
});
I would like to change the style on a div with an onclick... and remove the style when clicking somewhere outside of the div.
I have the following code setup... can someone help me to remove the style on the divs if you click anywhere else on the page?
<head>
<style type="text/css">
.account{
width: 100px;
height: 100px;
border: 1px solid #000;
}
.selected{
border: 2px solid #F00;
}
</style>
<script type="text/javascript">
$(document).ready(function(){
$(".account").click(function(){
$(".selected").removeClass("selected");
$(this).addClass("selected");
});
});
</script>
</head>
<body>
<h1>the test</h1>
<div class="account">test 1</div>
<div class="account">test 2</div>
</body>
Thank you very much for any help you can give me!!!
The following should do it:
$(document).on('click', function(e) {
if($(e.target).hasClass('account')) {
// do style change
}
else {
// undo style change
}
});
It binds the event handler to the entire document, so you'd have problems with any event handlers on more specific elements that call e.stopPropagation().
Try this.
$(document).ready(function(){
$(".account").click(function(e){
$(".selected").removeClass("selected");
$(this).addClass("selected");
e.stopPropagation();//This will stop the event bubbling
});
//This event handler will take care of removing the class if you click anywhere else
$(document).click(function(){
$(".selected").removeClass("selected");
});
});
Working demo - http://jsfiddle.net/yLhsC/
Note that you can use on or delegate to handle click event on account elements if there are many on the page.
Something like this.
Using on if using jQuery 1.7+
$('parentElementContainingAllAccounts').on('click', '.account', function(e){
$(".selected").removeClass("selected");
$(this).addClass("selected");
e.stopPropagation();//This will stop the event bubbling
});
Using delegate
$('parentElementContainingAllAccounts').delegate('.account', 'click', function(e){
$(".selected").removeClass("selected");
$(this).addClass("selected");
e.stopPropagation();//This will stop the event bubbling
});
You can achieve this behavior with attaching click listener on body element e.g.:
$("body").click(function(){
});
Try this:
$(document).ready(function() {
$('.account').click(function(e) {
e.stopPropagation();
$(this).addClass("selected");
});
$(document).click(function(){
$('.selected').removeClass('selected');
});
});