I'm working on the toggle menu of my WP website. The theme that i am using isn't giving me any possibilities to customize it, so i went on customizing it by my own. The thing is that i want when for mobiles the menu is been clicked to darken the whole page and open the menu items from left like here:
https://cdn3.wpbeginner.com/wp-content/uploads/2016/09/responsivemenudemo-1.gif
But i know i have to make changes to the js file, which bothers me when it comes to WP.
Here is my website:
https://www.ngraveme.com/bg/
and here is the js code:
( 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' );
} );
}
} );
} )();
You can use this CSS as starting point
.main-navigation.toggled div.menu:last-child {
/*display:block;*/
background-color: #000;
color: #fff;
left: 0;
top: 0;
width: 60%;
padding: 0 10px;
height: 100%;
overflow: auto;
opacity:1;
z-index: 99;
transition: 0.5s ease-in-out all;
}
.main-navigation div.menu:last-child{
/*display:none;*/
opacity: 0;
left:-60%;
position: fixed;
}
.main-navigation.toggled div.menu:last-child a {
color: #fff;
padding: 6px 0;
}
you can paste this css in your custom.css or style.css file and check you dont need to change any html its all css change
Related
I'm using fullpage.js and I'm having a problem with the onloadedmeta function that resizes my background video.
It works perfectly when accessing the page URL directly including the section id with the video. That is to say it resizes to take up the entire screen.
If the section id I'm trying to access is not the section with the background video I see the below error - in this scenario the video resizes correctly but the remaining pages are 144px out from the top (this error fixes itself when I then go to scroll through sections).
Error: Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause().
When I refresh the page using any section id other than the section id that contains the background video the above error is not thrown and the pages resize correctly - but the video does not. The video is just the default size.
I haven't actually noticed this problem previously and some of the aforementioned issues do seem somewhat sporadic. Today I've been created the footer (which contains no JS) and adjusted my mobile menu a little but nothing different to what it was in terms of JS.
I've pasted the JS file below - as you'll see I'm using Fullpage in conjunction with Smoothstate.
If anyone has any suggestions or feedback I'd be eternally grateful.
Thanks very much in advance for your time,
Kind regards
Tom
Edit: all works perfectly if I remove the video from the section
( function( $ ) {
function addFullPage() {
if( $( 'html' ).hasClass( 'fp-enabled' ) ) {
$.fn.fullpage.destroy( 'all' ); // uninitialise fullpage
}
$( '#fullpage' ).fullpage( {
anchors: [ '2d', '3d', 'character','motionandgraphics', 'vfx', 'footer' ],
scrollOverflow: false,
fixedElements: '#masthead',
afterLoad: function( anchorLink, index ) {
if( index == 1 ) {
console.log( 'afterload function' );
$( '#video' ).get( 0 ).play();
}
}
} );
$( '#section0 video' ).on( 'loadedmetadata', function() {
console.log( 'onloadedmetadata function' );
var $width, $height, // Width and height of screen
$vidwidth = this.videoWidth, // Width of video (actual width)
$vidheight = this.videoHeight, // Height of video (actual height)
$aspectRatio = $vidwidth / $vidheight; // The ratio the video's height and width are in
( adjSize = function() { // Create function called adjSize
$width = $( window ).width(); // Width of the screen
$height = $( window ).height(); // Height of the screen
$boxRatio = $width / $height; // The ratio the screen is in
$adjRatio = $aspectRatio / $boxRatio; // The ratio of the video divided by the screen size
// Set the container to be the width and height of the screen
$( '#section0' ).css( { 'width' : $width+'px', 'height' : $height+'px' } );
if( $boxRatio < $aspectRatio ) { // If the screen ratio is less than the aspect ratio..
// Set the width of the video to the screen size multiplied by $adjRatio
$vid = $( '#section0 video' ).css( { 'width' : $width*$adjRatio+'px' } );
} else {
// Else just set the video to the width of the screen/container
$vid = $( '#section0 video' ).css( { 'width' : $width+'px' } );
}
} )(); // Run function immediately
// Run function also on window resize.
$( window ).resize( adjSize );
} );
function iedetect( v ) {
var r = RegExp( 'msie' + ( !isNaN(v) ? ( '\\s' + v ) : '' ), 'i' );
return r.test( navigator.userAgent );
}
}
$( document ).ready( function(){
addFullPage();
console.log( 'document ready function' );
mobMenu();
} );
function addBlacklistClass() {
$( 'a' ).each( function() {
if ( this.href.indexOf( '/wp-admin/' ) !== -1 || this.href.indexOf( '/wp-login.php' ) !== -1 ) {
$( this ).addClass( 'wp-link' );
}
} );
}
$( function() {
addBlacklistClass();
var settings = {
anchors: 'a',
blacklist: '.wp-link',
onStart: {
duration: 1000,
render: function ( $container ) {
$( '#content' ).addClass( 'fade-out' );
}
},
onAfter: function( $container ) {
addFullPage();
console.log( 'on after function in smoothstate' );
mobMenu();
$( '#content' ).removeClass( 'fade-out' );
var $hash = $( window.location.hash );
if ( $hash.length !== 0 ) {
var offsetTop = $hash.offset().top;
$( 'body, html' ).animate( {
scrollTop: ( offsetTop - 60 ),
}, {
duration: 280
} );
}
}
};
$( '#page' ).smoothState( settings );
} );
} )( jQuery );
Ultimately the cleanest solution for me was to simply use CSS to resize the video rather than JQuery. I'm also relying on the built-in functionality of Fullpage.js to play/pause the video as it goes in and out of the viewport rather than trying to manipulate it myself.
The DOM play() exception is still thrown but after much testing it doesn't seem as though it's causing any harm on the front-end.
#fullpage .section video { position:absolute; top:0; left:0; width:100%; height:100%; display:none; }
#media ( min-aspect-ratio:16/9 ) {
#fullpage .section video { width:100%; height:auto; }
}
#media ( max-aspect-ratio:16/9 ) {
#fullpage .section video { width:auto; height:100%; }
}
I am trying to slide toggle my twenty-thirteen mobile menu with slide toggle and it only slide down but it comes back quickly (no slide). I injected other code to make it slide but it is buggy. Here's the original code
/**
* Enables menu toggle for small screens.
*/
( function() {
if ( ! nav || ! button ) {
return;
}
// Hide button if menu is missing or empty.
if ( ! menu || ! menu.children().length ) {
button.hide();
return;
}
button.on( 'click.twentythirteen', function() {
nav.toggleClass( 'toggled-on' );
if ( nav.hasClass( 'toggled-on' ) ) {
$( this ).attr( 'aria-expanded', 'true' );
menu.attr( 'aria-expanded', 'true' );
} else {
$( this ).attr( 'aria-expanded', 'false' );
menu.attr( 'aria-expanded', 'false' );
}
} );
and here is what i added
jQuery(document).ready(function () {
jQuery("button").on("click", function () {
jQuery( ".menu-primary-nav-container" ).slideToggle( "slow" );
});
});
Template link: https://twentythirteendemo.wordpress.com/
That template already has script assigned to click event and it toggles the class toggled-on on the menu list (and that is the reason you see no sliding). What you need to do is to disable new class this way:
.toggled-on .nav-menu, .toggled-on .nav-menu > ul {
display: none; /* It was block */
}
I have the following js code:
This code is used on a FAQ toggle page.
It works basically as every toogle code, but I would like to add the auto-close function when clicking to an other question.
Hide the prev question content, then show the next one.
Any ideas?
if ( 'function' !== typeof(window[ 'vc_toggleBehaviour' ] ) ) {
window.vc_toggleBehaviour = function ( $el ) {
function event( e ) {
e && e.preventDefault && e.preventDefault();
var title = jQuery( this );
var element = title.closest( '.vc_toggle' );
var content = element.find( '.vc_toggle_content' );
if ( element.hasClass( 'vc_toggle_active' ) ) {
content.slideUp( {
duration: 300,
complete: function () {
element.removeClass( 'vc_toggle_active' );
}
} );
} else {
content.slideDown( {
duration: 300,
complete: function () {
element.addClass( 'vc_toggle_active' );
}
} );
}
}
if ( $el ) {
if ( $el.hasClass( 'vc_toggle_title' ) ) {
$el.unbind( 'click' ).click( event );
} else {
$el.find( ".vc_toggle_title" ).unbind( 'click' ).click( event );
}
} else {
jQuery( ".vc_toggle_title" ).unbind( 'click' ).on( 'click', event );
}
}
}
Whenever any of the questions are clicked, if you were to hide all active questions you won't have to worry about which one -if any- are currently active.
(on question click):
$('.vc_toggle_active').each(function(){
$(this)slideUp( {
duration: 300,
complete: function () {
$(this).removeClass( 'vc_toggle_active' );
}
});
});
After sliding up any currently active question, go ahead and show the clicked one.
NB. Code not tested, since you have no fiddle and no html. Hope you get the concept though.
I need some help in jQuery and I really hope that I could find some help here. I would like when I use my navigation arrows (next/previous) when I am on a hidden item that the parent item stays highlight. For the first item home, it works but for the rest not. Does anybody can help me please?
here my fiddle
<div id="cssmenu">
<ul id="list">
<li>Home</li>
<ul class="hide"><li></li></ul>
<li>Newsletter</li>
... </div>
I tried to fiddle something :
$(document).ready(function(){
$('#cssmenu').find('li.active').removeClass('active');
//adding the state for this parent menu
$(this).parents('li').addClass('active');
});
I manage my next and previous button like that :
$( "#next, #prev" ).click( function ( event ) {
var
positionActiveClass = menu.find( "> li.active" ).index(),
menuLength = menu.find( "> li" ).length - 1,
buttonId = $( this ).attr( "id" );
if ( buttonId === "next" ) {
if ( positionActiveClass === ( menuLength ) ) {
newElementActiveClass = menu.find( "li" ).eq( 0 );
newPositionActiveClass = newElementActiveClass.find( "> a" ).attr( "href" );
animation( newPositionActiveClass );
} else {
newElementActiveClass = menu.find( "li" ).eq( positionActiveClass + 1 );
newPositionActiveClass = newElementActiveClass.find( "> a" ).attr( "href" );
animation( newPositionActiveClass );
}
} else {
if ( positionActiveClass === 0 ) {
newElementActiveClass = menu.find( "li" ).eq( menuLength );
newPositionActiveClass = newElementActiveClass.find( "> a" ).attr( "href" );
animation( newPositionActiveClass );
} else {
newElementActiveClass = menu.find( "li" ).eq( positionActiveClass - 1 );
newPositionActiveClass = newElementActiveClass.find( "> a" ).attr( "href" );
animation( newPositionActiveClass );
}
}
event.preventDefault();
} );
There is an extra ul after the first li which has a class hide. What is that for? Just remove that ul and everything works fine.
I am trying to use the dotimeout plugin to create a delay for the effect of showing a sub-nav when hovering over the top nav. The plug in seems to work well when the active class is added to the first li but when added to subsequent li's, it stops showing the hidden ul for this above the active li.
Here's my script:
$(function(){
$('ul.main-nav').each(function(){
var nav = $(this);
nav
.mouseover(function(e){
nav.doTimeout( 'main-nav', 500, over, e.target );
}).mouseout(function(){
nav.doTimeout( 'main-nav', 500, out );
});
function over( elem ) {
var parent = $(elem).closest( 'li.main-nav' );
out( parent );
parent.children( 'a' ).addClass( 'hover' );
parent.children( 'ul:hidden' ).slideDown( 'fast' );
};
function out( elem ) {
var parents = elem
? $(elem).closest( 'li.main-nav' ).siblings()
: nav.children();
if ( nav.is( '.main-nav-horizontal' ) ) {
parents = parents.not( '.active' );
}
parents.children( 'a' ).removeClass( 'hover' );
parents.children( 'ul' ).hide();
};
});
});
Here's my jsfiddle
I can see people are using this plugin so this issue seems like it should be easily solved but everything as far as I can see should work properly.
Change your out function to this.
function out( elem ) {
var parents;
if (elem) {
parents = $(elem).closest( 'li.main-nav' ).siblings();
}
else {
parents = nav.children();
showthisone = parents.filter( '.active' );
parents = parents.not( '.active' );
}
parents.children( 'a' ).removeClass( 'hover' );
parents.children( 'ul' ).hide();
if (!elem) {
showthisone.children( 'a' ).addClass('hover');
showthisone.children( 'ul' ).show();
}
};