How can I tell using jQuery if an any element within a div (panel1) was clicked? I have this piece of code that I use to show/hide a popup:
$('body').click(function (e) {
if ($(e.target).attr('id') == 'link1') {
$('#panel1').show();
} else {
$('#panel1').hide();
}
});
The problem is that the popup (panel1) gets dismissed if I click on any control/element within panel1. I'd like to keep panel1 open unless an area outside panel1 is clicked (or if link1 is clicked again). How can I revise this code to achieve this? Thanks...
Try this
$('#panel1').click(function (e) {
e.stopPropagation();
//Other code if you want to execute anything on panel click.
});
$('body').click(function (e) {
if($("#panel1").is(":visible"))
$('#panel1').hide();
});
Make a following html markup:
<body>
<div id="div1">
... all the body content here
</div>
<div id="panel1">
</div>
I suppose the popup #panel1 is positioned out of normal flow anyway, so it is no problem.
Then in jquery use div1 instead of body and that's it :-)
$('body').click(function (e) {
if ($(e.target).attr('id') == 'link1') {
$('#panel1').show();
} else if($(e.target).attr('id') != 'panel1') {
$('#panel1').hide();
}
});
Related
I have a dropdown menu within a div element. Calling the javascript function HideDropdown() hides the menu when any other main link on the page is clicked (not including links in the dropdown menu itself):
<script>
function HideDropdown() {
$("#dropdown-content-id2").hide();
$("#dropdown-content-id").hide();}
</script>
I also want to call HideDropdown() to hide the menu (if it's open) when I click anywhere on the body except the dropdown menu itself.
In the body tag I inserted this:
<body onload="ShowPage(1)" onclick="HideDropdown()">
That successfully hides the dropdown when I click anywhere on the screen. I want to exclude clicks on the link that shows the dropdown menu and anywhere on the dropdown menu itself, so I revised the body tag:
<body onload="ShowPage(1)" onclick="HideDropdownCall(e)">
and created a new javascript function to call from the body onclick:
<script>
function HideDropdownCall(e) {
if(e.target.id != "dropdown-content-id" ){
HideDropdown();
}
</script>
but that didn't work, so I revised it:
<script>
function HideDropdownCall(e) {
if(e.target.id != "dropdown-content-id" ){
$("#dropdown-content-id2").hide();
$("#dropdown-content-id").hide();}
}
</script>
but that still doesn't work.
So my question is, how can I call the HideDropdown() function from a body click, filtered so that clicks on the dropdown menu itself don't count?
Thanks very much for any help.
EDIT:
After some work, I whittled down my problem to this: I can call the HideDropdown() function from the body tag like this:
<body onload="ShowAjax(1)" onclick="HideDropdown()">
That works. But when I change it to the same function with qualifications and (not if the click event is fired by the dropdown menu), the dev console says "TypeError: e is undefined" so it has something to do with the conditional statement:
<body onload="ShowAjax(1)" onclick="HideDropdown_B()">
<script>
function HideDropdown_B(e) {
if(e.target.id != "dropdown-content-id" ){
$("#dropdown-content-id2").hide();
$("#dropdown-content-id").hide();}
}
</script>
So my problem now boils down to finding out why the new function above returns a type error when the same program without the if statement works.
What you could do is add the property data-prevent='true' on the elements that you want to prevent hiding the dropdown.For example:
Link
and modify your function to filter out those elements like so:
function hideDropdown(evt) {
evt.preventDefault(); // you might not need this (usefull in case of a tags & preventing redirects)
if (!evt.target.getAttribute('data-prevent') || evt.target.getAttribute('data-prevent') === 'false') {
$("#dropdown-content-id2").hide();
$("#dropdown-content-id").hide();
}
}
Here is an example of how it could be done:
let menu = document.getElementById('menu');
document.body.addEventListener('click', e => {
if (!menu.contains(e.target))
console.log('close menu');
});
<div id='menu'><a id='link'>link</a> and menu</div>
document body here
However, you may actually want to close menu depending on which link were clicked.
Another way to do so:
let menu = document.getElementById('menu');
menu.addEventListener('click', e => e.stopPropagation());
document.body.addEventListener('click', e => console.log('close menu'));
<div id='menu'><a id='link'>link</a> and menu</div>
document body here
Thanks to everyone who answered. I solved this problem. Here is the solution:
In the body tag:
<body onload="ShowPage(1)" onclick="HideDropdown_B(event)">
The HideDropdown_B function:
<script>
function HideDropdown_B(event) {
TargetID = event.target.getAttribute('id');
TargetClass = event.target.getAttribute('class');
if((TargetID != "dropdown-content-id") && (TargetClass != "button_01") && (TargetClass != "dropdown") && (TargetClass != "button_dropdown") ) {
$("#dropdown-content-id2").hide();
$("#dropdown-content-id").hide();}
}
</script>
That works to close the menu when clicking anywhere except the excluded elements.
Here's my function,
$(document).ready(function () {
$('.a').click(function () {
var here = $(this).next('.b');
if (here.is(":visible")) {
here.hide();
} else {
here.show();
}
return false;
});
});
So, whenever I click the button it opens a small tab on same webpage & whenever I click it again it closes it. But once I open the tab I can't close it by just clicking somewhere on webpage apart from tab. I have to click the button again to close it.
How can I close tab just by clicking somewhere on webpage also by on the button?
I end up searching for this on almost every project, so I made this plugin:
jQuery.fn.clickOutside = function(callback){
var $me = this;
$(document).mouseup(function(e) {
if ( !$me.is(e.target) && $me.has(e.target).length === 0 ) {
callback.apply($me);
}
});
};
It takes a callback function and passes your original selector, so you can do this:
$('[selector]').clickOutside(function(){
$(this).removeClass('active'); // or `$(this).hide()`, if you must
});
Nice, chainable, elegant code.
On document click, the closest helps to check whether the tab has been clicked or not:
$(document).click(function (e) {
if($('.b').is(':visible')&&!$(e.target).closest('.b').length){
$('.b').hide();
}
});
You want to check for a click on the body :
$("body").click(function(e) {
if(e.target.id !== 'menu'){
$("#menu").hide();
}
});
menu would be the id of the menu.
If the body is clicked and the id of the div clicked doesn't equal that of the menu, then it closes.
Check this implementation
jQuery(document).ready(function() {
$(document).on('click','body, #btn',function(ev){
ev.stopPropagation()
if(ev.target.id== "btn"){
if($('#modal').is(':visible')) {
$('#modal').fadeOut();
} else{
$('#modal').fadeIn();
}
} else {
$('#modal').fadeOut();
}
});
});
html, body {
height: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btn">
Click Me!
</button>
<div id="modal" style="background-color:red;display:none;">
BLA BLA BLA
</div>
To check if the clicked element is outside of a given container, i.e. a menu, we can simply check if the event target is a child of the container. Using JQuery -
$('body').click(function(e) {
if ( 0 === $(e.target).parents('#container-id').length ) {
/// clicked outside -> do action
}
})
you have to add a click listener to the parent element, like here:
$('.parent-div').click(function() {
//Hide the menus if visible
});
Also because click events bubbled up from child to the parent,
you can exclude the click on the child element to get bubbled up and count as the parent click too. you can achieve this like below:
//disable click event on child element
$('.child-div').click(function(event){
event.stopPropagation();
});
On clicking on a link I show a pop up. Here is my pop up code
<div class='' id="custom-popover">
<div class="arrow"></div>
<h3 class="popover-title">Popover left</h3>
<div class="popover-content" id="details-container">
</div>
</div>
</div>
I also add some html code using jquery when pop up show. Now I want to check if cursor is on this pop over or if user is hovering over this pop up and then I show an alert message otherwise hide the popup. How can I do this? I tried something like this
var isHovered = $('#custom-popover').is(":hover");
if (isHovered){
alert("msg");
} else {
$('#custom-popover').hide();
}
But this is not working. How can I do this?
use global variable:
var cursorOnDiv = false;
$(document).on({
mouseenter:function(){ cursorOnDiv = true; },
mouseleave:function(){ cursorOnDiv = false; },
},
'#yourDivId'
);
and check him
Try it:
$("#custom-popover").hover(
function() {
$("#custom-popover").show();
},
function() {
$("#custom-popover").hide();
});
Some thing like this,
$( "#custom-popover" ).mouseover(function() {
$('#custom-popover').hide();
});
the function is() as per doc is often useful inside callbacks, such as event handlers.
This function runs only once as it is not a callback. So in order to detect hover events use call backs.
You can have even like this if you want to have enter and leave both,
$( "custom-popover" )
.mouseenter(function() {
})
.mouseleave(function() {
})
This is what you ask:
$("#custom-popover").hover(
function() {
alert("Hovering now");
$("#custom-popover").show();
},
function() {
$("#custom-popover").hide();
});
You stored a value whether #custom-popover is being hovered or not at the time of execution, you did not bind an eventListener (hover) for the cause.
Try this:
if($('#custom-popover:hover'))
{
alert("msg");
}
else
{
$('#custom-popover').hide();
}
I have having a little trouble with the slideToggle when I have a link inside of the slideup panel. What I am trying to do is have the ability to press a button and a div will slide up and display related posts and once you press another or the related project button on the page it will close the toggle and reveal another effect that I am using (100% width and heigh popup). The script I am using works perfect but I am running into one problem. When I click a related post inside of the slideToggle it causes the div to slide down instead of going to the page that represents the link.
Here is my code below and an example http://jsfiddle.net/K8vBg/15/.
$(document).ready(function(){
// build a variable to target the #menu div
var menu = $('#menu')
// bind a click function to the menu-trigger
$('#menu-trigger').click(function(event){
event.preventDefault();
event.stopPropagation();
// if the menu is visible slide it up
if (menu.is(":visible"))
{
menu.slideUp(1000);
}
// otherwise, slide the menu down
else
{
menu.slideDown(400);
}
});
$(document).not('.projectHolder-small,#projectSpecs').click(function(event) {
event.preventDefault();
if (menu.is(":visible"))
{
menu.slideUp(400);
}
});
})
If I change .projectHolder-small,#projectSpecs in the .not function to just read #menu then I am able to click the link inside of the panel but the panel will not slideDown when I click another button on the page. The popup from #project specs will just go over the panel instead of closing it.
Is there something I am missing in my script?
Thank you
Try changing the $(document).not().click() to:
$(document).click(function(event){
if(!$(event.target).closest('.projectHolder-small,#projectSpecs').length){
if (menu.is(":visible")){
menu.slideUp(400);
}
}
});
I am using closest() instead of the usual is(), so that even clicking on the children elements of '.projectHolder-small,#projectSpecs' the panel won't close.
I rewrote the script to the following and it works perfect
$(document).ready(function () {
var $frm = $('#menu').hide();
var $bts = $("#menu-trigger").on('click', function () {
var $this = $(this)
$bts.filter(".selected").not(this).removeClass('selected');
$this.toggleClass('selected');
if ($this.hasClass('selected') && $frm.is(':visible')) {
$frm.stop(true, true).slideUp(function () {
$(this).slideDown()
});
} else {
$frm.stop(true, true).slideToggle();
}
});
$bts.filter('.selected').click();
$("#projectSpecs, #menuButton").click(function () {
$bts.filter(".selected").removeClass('selected');
$frm.slideUp();
});
});
I'm creating pulldown menus that must be clicked on to open. This code lets the user opening menus just fine. The only problem is I haven't figured out how to close the menus yet by clicking outside the menus. I tried adding the "document.onclick" shown, but it takes effect even in the menus.
I think I need to prevent document.onclick from being captured by other elements, but am not sure how to do this cross-platform. Can someone please show me how?
<script type="text/javascript">
var lastOpenedMenuId = null;
function showMenu(menuId) {
if (lastOpenedMenuId != null && lastOpenedMenuId != menuId) {
hideLastOpenedMenu();
}
setMenuVisibility(menuId, 'visible');
lastOpenedMenuId = menuId;
}
function hideMenu(menuId) {
setMenuVisibility(menuId, 'hidden');
}
function hideLastOpenedMenu() {
if (lastOpenedMenuId != null) {
hideMenu(lastOpenedMenuId);
}
}
function setMenuVisibility(menuId, visibleOrHidden) {
var menuElement = document.getElementById(menuId);
menuElement.style.visibility = visibleOrHidden;
}
document.onclick = hideLastOpenedMenu;
</script>
<div onmousedown="showMenu('foodmenu')"><a>FOOD</a></div>
<div id="foodmenu" onmouseup="hideMenu('foodmenu');">
Meat
Tofu
</div>
Thanks in advance.
I have made some progress and have reformulated the question here:
How to stop onclick event in div from propagating to the document?
Depending on whether you have a page layout like this:
<body>
<div id="menu"><!--Menu Stuff--></div>
<div id="main"><!--Main page stuff--></div>
</body>
you could put the onClick handler to close the menu on the div with the id "main" which should work
Someone pointed me to a solution that uses addEventListener. Say, the div is the menu. This code allows the user to click on the document outside the div to do something, such as close the menu. Clicking on the div (say, on a link) will not propagate to the document.
<head>
<script>
function menuHandler(event) {
alert("div clicked");
// Don't propogate the event to the document
if (event.stopPropagation) {
event.stopPropagation(); // W3C model
} else {
event.cancelBubble = true; // IE model
}
}
document.onclick = function() {
alert('document clicked');
};
function addListener() {
var foodMenuElement = document.getElementById('foodmenu');
if (foodMenuElement.addEventListener) {
foodMenuElement.addEventListener('click', menuHandler, false);
} else {
foodMenuElement.attachEvent('onclick', menuHandler);
}
}
</script>
</head>
<body onload="addListener()">
<div id="foodmenu" style="border: 1px solid red;">Click inside this div</div>
or click outside the div.
</body>
Note that the third argument "false" to addEventListener means "fire the event during the capturing phase", but the value doesn't matter because the event propagation is canceled in menuHandler.
This solution works, but I'd like to do the same thing more simply, without addEventListener, so have posted a question at How to stop onclick event in div from propagating to the document?