After initial click, have to click twice with Jquery click() - javascript

Couldn't find a solution that actually worked, but I want that on a click, a div shows.
Now this works when I load the page, but then after that first click, I have to click twice every time for the div to show.
Any ideas?
$(document).ready(function () {
setMenu();
});
function setMenu()
{
var headerExtIsOpen = false;
$('#headerExt').hide();
$('#header').click(function () {
if (!headerExtIsOpen) {
$('#headerExt').show();
headerExtIsOpen = true;
} else {
$('#headerExt').hide();
headerExtIsOpen = false;
}
});
}

There is no need to remember the state, just use toggle()
$(function () {
setMenu();
});
function setMenu()
{
$('#headerExt').hide();
$('#header').on("click", function (e) {
e.preventDefault();
$('#headerExt').toggle();
});
}
You said you want to toggle other things.
Best thing would be to toggle a class to change the color
$('#header').on("click", function (e) {
e.preventDefault();
$(this).toggleClass("open");
$('#headerExt').toggle();
});
another way is to check the state
$('#header').on("click", function (e) {
e.preventDefault();
var child = $('#headerExt').toggle();
var isOpen = child.is(":visibile");
$(this).css("background-color" : isOpen ? "red" : "blue" );
});
if the layout is something like
<div class="portlet">
<h2>Header</h2>
<div>
<p>Content</p>
</div>
</div>
You can have CSS like this
.portlet h2 { background-color: yellow; }
.portlet > div { display: none; }
.portlet.open h2 { background-color: green; }
.portlet.open > div { display: block; }
And the JavaScript
$(".portlet h2 a").on("click", function() {
$(this).closest(".portlet").toggleClass("open");
});
And there is layouts where it would be possible to have zero JavaScript involved.

Turns out I had some script hidden in my .js file that closes the menu again when the user clicks elsewhere, that I forgot about.
function resetMenu(e) {
var container = $('#headerExt');
if (!container.is(e.target) // if the target of the click isn't the container...
&& container.has(e.target).length === 0) // ... nor a descendant of the container
{
$('#header').css("background-color", "inherit");
container.hide();
headerExtIsOpen = false;
}
}
I forgot to set the headerExtIsOpen back to false again after closing it in this function (code above shows the fix). Now it works fine :)

Related

Closing toggle menu not working properly with JQuery code

I am working on closing toggle menu for mobiles and having a small problem. So what i want is when the toggle menu is active, user to be able to close it by touching somewhere on the screen on his device. I almost got it working, but when closed the basket in the header disappears and the menu doesn't retrieve to a hamburger icon. I am working on Wordpress website, just to notice.
I guess the problem comes from this: aria-expanded="true" , because the default value should be false after the user has closed it.
So my website is:
https://www.ngraveme.com/bg
my JQuery code is:
jQuery(document).ready(function($) {
var $menu = $('.menu');
$('.menu-toggle').click(function() {
$menu.toggle();
});
$(document).mouseup(function(e) {
if (!$menu.is(e.target) // if the target of the click isn't the container...
&&
$menu.has(e.target).length === 0) // ... nor a descendant of the container
{
$menu.hide();
}
});
});
and the original js code written from the theme i am using in wordpress is:
/**
* navigation.js
*
* Handles toggling the navigation menu for small screens.
* Also adds a focus class to parent li's for accessibility.
* Finally adds a class required to reveal the search in the handheld footer bar.
*/
(function() {
// Wait for DOM to be ready.
document.addEventListener('DOMContentLoaded', function() {
var container = document.getElementById('site-navigation');
if (!container) {
return;
}
var button = container.querySelector('button');
if (!button) {
return;
}
var menu = container.querySelector('ul');
// Hide menu toggle button if menu is empty and return early.
if (!menu) {
button.style.display = 'none';
return;
}
button.setAttribute('aria-expanded', 'false');
menu.setAttribute('aria-expanded', 'false');
menu.classList.add('nav-menu');
button.addEventListener('click', function() {
container.classList.toggle('toggled');
var expanded = container.classList.contains('toggled') ? 'true' : 'false';
button.setAttribute('aria-expanded', expanded);
menu.setAttribute('aria-expanded', expanded);
});
// Add class to footer search when clicked.
document.querySelectorAll('.storefront-handheld-footer-bar .search > a').forEach(function(anchor) {
anchor.addEventListener('click', function(event) {
anchor.parentElement.classList.toggle('active');
event.preventDefault();
});
});
// Add focus class to parents of sub-menu anchors.
document.querySelectorAll('.site-header .menu-item > a, .site-header .page_item > a, .site-header-cart a').forEach(function(anchor) {
var li = anchor.parentNode;
anchor.addEventListener('focus', function() {
li.classList.add('focus');
});
anchor.addEventListener('blur', function() {
li.classList.remove('focus');
});
});
// Add an identifying class to dropdowns when on a touch device
// This is required to switch the dropdown hiding method from a negative `left` value to `display: none`.
if (('ontouchstart' in window || navigator.maxTouchPoints) && window.innerWidth > 767) {
document.querySelectorAll('.site-header ul ul, .site-header-cart .widget_shopping_cart').forEach(function(element) {
element.classList.add('sub-menu--is-touch-device');
});
}
});
})();
Try replacing your jQuery code with this:
jQuery(document).ready(function($) {
$(document).mouseup(function(e) {
var $menuContainer = $('.menu');
var $menu = $menu.find('ul');
var $container = $('.site-navigation');
var $button = $container.find('button')
if (!$menuContainer.is(e.target) && $menuContainer.has(e.target).length === 0) {
if ($container.hasClass('toggled')) {
$button.attr('aria-expanded', false);
$menu.attr('aria-expanded', false);
}
}
});
});
It uses the vanilla-js code from the template for hiding/showing the menu, but with jQuery synthax.

Hiding <div> block doesn't work on mobile

I have callback button and hidden callback form.
Form shows up after click on button and hide after click on any place on the screen except the form-space.
BUT! Form don't hide on mobile devices. I think that problem is in touch tracking on iOS.
How can i fix this problem?
function showcallbackform (objName) {
if ( $(objName).css('display') == 'none' ) {
$(objName).animate({height: 'show'}, 200);
} else {
$(objName).animate({height: 'hide'}, 200);
}
};
jQuery(function($){
$(document).mouseup(function (e){
var div = $("#callback-form");
if (!div.is(e.target)
&& div.has(e.target).length === 0) {
div.hide();
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
You can bind both actions (mouse and touch events) like this:
jQuery(function($){
$(document).bind( "mouseup touchend", function(e){
var div = $("#callback-form");
if (!div.is(e.target)
&& div.has(e.target).length === 0) {
div.hide();
}
});
});

js test if clicked element is child/descendent of

I want to test if a click is on an element within a specific hierarchy.
Using:
var elements = parentElement.getElementsByTagName("*");
I can put all elements into array, but then I can't get the test right:
function isClicked(e){
if(elements.indexOf(e.target) != -1){
//do something
}
};
How do I do this correctly, please? Thanks...
(PS I am trying to create a click-away function where clicking upon anything in the body except the displayed info will close it)
Use Node.prototype.contains:
var button = document.querySelector('button');
var dialog = document.querySelector('.dialog');
button.addEventListener('click', function () {
dialog.classList.add('open');
});
document.body.addEventListener('click', function (e) {
if (button !== e.target && dialog !== e.target && !dialog.contains(e.target)) {
dialog.classList.remove('open');
}
});
.dialog:not(.open) {
display: none;
}
.dialog {
background-color: yellow;
}
span {
color: red;
}
<button>Open dialog</button>
<div class="dialog">
<h1>Hello, World!</h1>
<p>Hello, World! <span>Nested element<span></p>
</div>
<p>Click somewhere here to close the dialog! <span>Nested element</span></p>
Try to following:
function isClicked(e){
//check e.currentTarget.children()
};
You could use the Underscore's contains function. So, your condition should be in that case:
if (_.contains(elements, e)) {
// ...
}

Hide popover on body click only if already visible

Hiding a div (for example #popover) on click is easy:
$(document).ready(function() {
$("#trigger").click(function(e) {
$("#popover").toggle();
e.stopPropagation();
});
$(document).click(function(e) {
if (!$(e.target).is('#popover, #popover *')) {
$("#popover").hide();
}
});
});
But isn't this function fired every time the user uses a click? (Which does not make sense for me). Can I somehow limit this function to fire only if #popover is already visible?
In that case you can try using $(document).one(function(e) {...}); every time you show #example.
$(document).ready(function() {
var didBindToBody = false;
function closePopOverOnBodyClick() {
didBindToBody = true;
$(document).one('click', function(e) {
if (!$(e.target).is('#popover, #popover *')) {
$("#popover").hide();
}
else {
closePopOverOnBodyClick();
}
didBindToBody = false;
});
}
$("#trigger").click(function(e) {
$("#popover").toggle();
e.stopPropagation();
if (!didBindToBody && $("#popover").is(":visible")) {
closePopOverOnBodyClick();
}
});
closePopOverOnBodyClick();
});
DEMO
You could try something like
$(document).click(function(e) {
if (!$('#example').is(":visible")) {
return false;
} else if (!$(e.target).is('#popover, .login-panel *')) {
$("#popover").hide();
}
});
Or you could combine the two conditionals into one, just thought I'd keep it separate for readability and to make my suggestion easier to spot.

click anywhere to close div inside and outside

This is a jscript to close the window when someone clicks anywhere outsite the Div to close.
my question is to make this window close when someone clicks on this by performing the action.
<div id="box"
style="height: 3em; position:absolute; top: 20%; left: 15%; border: 3px double">
<p>Click anywhere outside this box to close it.
</div>
<script>
document.onclick = function (e) {
e = e || event
var target = e.target || e.srcElement
var box = document.getElementById("box")
do {
if (box == target) {
// Click occured inside the box, do nothing.
return
}
target = target.parentNode
} while (target)
// Click was outside the box, hide it.
box.style.display = "none"
}
</script>
How to make a Div close when the click was occurred inside the DIV
In your HTML code itself,
<div id='box' style='height:10px; width:10px' onclick='CloseMe(this)'>...</div>
Implement the CloseMe function
function CloseMe( obj )
{
obj.style.display = 'none';
}
For the specific thing talking here, I didn't test it but I think change that loop to the following code could make it.
do {
if (box != target) {
// Click occured outside the box, do nothing.
return
}
target = target.parentNode
} while (target)
If you use JQuery you can use the event.stopPropagation(); on the click function for you div
$(function(){
$('html').click(function() {
$('#box').hide();
});
$('#box').click(function(event){
event.stopPropagation();
});
});
http://jsfiddle.net/nCqwy/1/

Categories

Resources