Hide Element on Load, Appear on Hover with Mouseenter - javascript

I have a menu that hides/shows child elements with mouseenter & mouseleave, but the child elements appear when the page loads.
I'd like it so the elements don't appear when the page loads but only on mouseenter & mouseleave.
How would I accomplish this with my code below?
$('.side-nav>li.has-flyout', this).on('mouseenter mouseleave', function(e) {
if (e.type == 'mouseenter') {
$('.side-nav').find('.flyout').hide();
$(this).children('.flyout').show();
}
if (e.type == 'mouseleave') {
var flyout = $(this).children('.flyout'),
inputs = flyout.find('input'),
hasFocus = function(inputs) {
var focus;
if (inputs.length > 0) {
inputs.each(function() {
if ($(this).is(":focus")) {
focus = true;
}
});
return focus;
}
return false;
};
if (!hasFocus(inputs)) {
$(this).children('.flyout').hide();
}
}
});
Doing just $('.side-nav>li.has-flyout').hide(); obviously hides the whole nav item. FWIW I'm using Foundation 5's framework.

Ideal: all your initial styles (like display: none) which is what .hide() does should be written in your stylesheet.
/* css */
.side-nav > li.has-flyout .flyout {
display: none;
}
Less ideal:
// JavaScript
$('.side-nav>li.has-flyout').children('.flyout').hide();

Through CSS, if your sub element list has class e.g. .sub-menu
then just add css
.sub-menu { display: none; }

Related

Javascript keydown event twice to cancel

My intention is to make div when keydown, and remove div when the same key is pressed again.
This is my code.
let keydown = false;
document.addEventListener('keydown', function(e) {
if (e.code === 'Space') {
if (!keydown) {
keydown = true;
console.log("space")
e.preventDefault(); //space doesn't manipulate position
$("body").append($("<div id='refactor'></div>"))
$(refactor).append($(".highlight").text())
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
What should I do to remove the div when Space is hit again?
First of all...jquery...avoid this bloatware by all means, please...
Of course this is based on what you've asked here, but I'd recommend instead of store true/false for the pressed key, store the new div element instead. This way, you'll have instant access to it without need search in the DOM.
To remove a node from the DOM, you just need execute node.removeChild(child)
let div = null;
document.addEventListener('keydown', function(e) {
if (e.code === 'Space') {
console.log("space")
e.preventDefault(); //space doesn't manipulate position
if (div)
{
//remove div from DOM
div.parentNode.removeChild(div);
div = null;
}
else
{
//create new div
div = document.createElement("div");
div.id = "refactor";
div.textContent = document.querySelector(".highlight").textContent;
document.body.appendChild(div);
}
}
})
#refactor
{
background-color: lightgreen;
}
<div class="highlight">test</div>
If your whole goal is to show/hide an element, than you should do so via CSS instead of adding/removing elements from DOM, it's significantly faster and allows add additional animations/styles:
let div = document.getElementById("refactor");
document.addEventListener('keydown', function(e) {
if (e.code === 'Space') {
console.log("space")
e.preventDefault(); //space doesn't manipulate position
if (div.classList.contains("hidden"))
{
div.textContent = document.querySelector(".highlight").textContent + " " + Date();
}
div.classList.toggle("hidden");
}
})
#refactor
{
background-color: lightgreen;
transition: height 0.5s, width 0.5s, background-color 0.5s;
height: 1.5em;
width: 100%;
overflow: hidden;
}
#refactor.hidden
{
height: 0;
width: 0;
background-color: pink;
}
<div class="highlight">test</div>
<div id="refactor" class="hidden"></div>
<div>blah</div>

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.

How can i make smaller js code in js?

I have 5 css classes with different type of colors in a buttons for on hover function, in my page might be have 5 buttons with diffenent classes. When i hover the each button, color should be set as per respective class name so far its working fine for me. but now i can see huge code, i want to make it smaller. Please suggest anyone.
$('[class^="button"]').parent().each(function(){
var parentElement = $(this);
var buttonfullwidth = $(parentElement).hasClass('buttonfullwidth');
var buttonfullwidth_1 = $(parentElement).hasClass('buttonfullwidth_1');
var buttonfullwidth_2 = $(parentElement).hasClass('buttonfullwidth_2');
var buttonfullwidth_3 = $(parentElement).hasClass('buttonfullwidth_3');
var buttonfullwidth_4 = $(parentElement).hasClass('buttonfullwidth_4');
if(buttonfullwidth_1 !== false) {
$(parentElement).hover(function(){
$(this).addClass('buttonfullwidth_1');
}, function(){
$(this).removeClass('buttonfullwidth_1');
});
}
if(buttonfullwidth_2 !== false) {
$(parentElement).hover(function(){
$(this).addClass('buttonfullwidth_2');
}, function(){
$(this).removeClass('buttonfullwidth_2');
});
}
if(buttonfullwidth_3 !== false) {
$(parentElement).hover(function(){
$(this).addClass('buttonfullwidth_3');
}, function(){
$(this).removeClass('buttonfullwidth_3');
});
}
if(buttonfullwidth_4 !== false) {
$(parentElement).hover(function(){
$(this).addClass('buttonfullwidth_4');
}, function(){
$(this).removeClass('buttonfullwidth_4');
});
}
if(buttonfullwidth !== false) {
$(parentElement).hover(function(){
$(this).addClass('buttonfullwidth');
}, function(){
$(this).removeClass('buttonfullwidth');
});
}
});
You need CSS for this job by using the :hover pseudo selector
The :hover CSS pseudo-class matches when the user interacts with an element with a pointing device, it is generally triggered when the user hovers over an element with the mouse pointer.
For example, if you want this button to turn blue when hovered:
.myButton {
background-color: lightgreen;
}
.myButton:hover {
background-color: lightblue;
}
<button class="myButton">Hover this button</button>
Notice how I can set properties to the element when it is in his hover state.
So for your code you simply need to use the following selectors:
buttonfullwidth
buttonfullwidth:hover
buttonfullwidth_1
buttonfullwidth_1:hover
buttonfullwidth_2
buttonfullwidth_2:hover
buttonfullwidth_3
buttonfullwidth_3:hover
buttonfullwidth_4
buttonfullwidth_4:hover
in the same manner as I did in my example.

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

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 :)

Putting body into a DIV kills the event

dont ask me why, but I want to put the whole body into a div, and shrink the content. I have this so far:
$('#newButton').click(function() {
if ($('#xxxx').length == 0)
{
$('body').html('<div id="xxxx">'+$('body').html()+'</div>');
$('#xxxx').css('background-color', 'red').css('overflow', 'scroll');
}
alert ($('#xxxx').width());
$('#xxxx').width (parseInt($('#xxxx').width())-10+'px');
});
this is ok so far - but then this click() method never triggers again. For an unknown reason, its killed....
You destroyed the original DOM element when you updated the .html(). Then you created a new element with the same ID, but no event handler. (Remember, HTML isn't the same as the DOM elements. When you remove and replace the HTML, whole new DOM elements are created from that code.)
You could solve this with event delegation:
$('document').on('click','#newButton',function() {
But I would use .wrapAll() instead:
if ($('#xxxx').length == 0) {
$('body > *').wrapAll('<div id="xxxx">');
try this:
<style>
#xxxx{ position: absolute; top: 0px; left: 0px; background: none; display: none; }
</style>
$('#newButton').click(function() {
if ($('#xxxx').length == 0)
{
$('body').append('<div id="xxxx">'+$('body').html()+'</div>');
$('#xxxx').css('background-color', 'red')
.css('overflow', 'scroll')
.css("display", "block";
}
alert ($('#xxxx').width());
$('#xxxx').width (parseInt($('#xxxx').width())-10+'px');
});
this will copy a new "body" (actually it's a div with the same content) on top of the old body.
for those why I want it (it might be weird, but we programmers has to get used to weird solutions).
I wanted to simplify to check the site with shrank windows, so with - and + you can decrease/increase the "window":
$(document).ready(function() {
var doResizing = function (increaseWith)
{
if ($('#xxxx').length == 0)
{
$('body').css('margin', 0).css('padding', 0);
$('body > *').wrapAll('<div id="xxxx" /></div>');
$('#xxxx').css('background-color', 'red').css('overflow', 'scroll').css('padding', 0).css('margin', 0).css('position', 'absolute').width('100%');
}
$('#xxxx').height(parseInt($(window).height())+'px').width(parseInt($('#xxxx').width())+increaseWith+'px');
}
$(document).keypress(function(e) {
if (e.which == 45) { doResizing (-10); }
if (e.which == 43) { doResizing (+10); }
});
});
enjoy!

Categories

Resources