I'm working on a responsive website that has a clickable drop down menu for mobile size screens. It works on small laptop screens on a mouse click but I'm having trouble figuring out how to have it react in the same way to a touch for mobile. Either plain Javascript or Jquery methods welcome. The class to_nav is the button that should reveal the menu.
$(window).ready(function() {
$(window).on('resize', function(){
var win = $(this);
if (win.width() >= 600) { document.getElementById('menu').style.display='inline'; }
});
});
displaynav= function () {
var nav = document.getElementById("menu");
if (nav.style.display == 'none'){
nav.style.display = "block";
}
else { nav.style.display = 'none';}
}
$(document).on("ready",function(){
$('.to_nav').click(function(){
displaynav();
})
});
Related
trying to get my burger icon to show the mobile menu from hidden to block with "display", code works on desktop with chrome simulator but not on the actual mobile device.
my website is www.rikuzit.co.il
window.onclick = function(event){
var burger = document.getElementById("burgerIcon");
var mobileMenu = document.getElementById("mobileMenu");
if(event.target == burger){
alert("burger was pressed");
console.log(event.target);
mobileMenu.style.display = "block";
} else {
alert("clicked outside burger");
console.log(event.target);
mobileMenu.style.display = "none";
}
}
i expect that when the button is tapped the menu should appear.
As shown in this answer, it's better to use touchstart for mobile devices:
window.ontouchstart = function(event){
var burger = document.getElementById("burgerIcon");
var mobileMenu = document.getElementById("mobileMenu");
if(event.target == burger){
alert("burger was pressed");
console.log(event.target);
mobileMenu.style.display = "block";
} else {
alert("clicked outside burger");
console.log(event.target);
mobileMenu.style.display = "none";
}
}
You can do something like this
window.onclick = eventHandler
window.ontouch = eventHandler
function eventHandler(event){
...
}
(copied Shubham Chaudhary's answer)
i hope this should work
window.onclick = eventHandler
window.ontouch = eventHandler
function eventHandler(event){
...
}
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.
I have a problem with my positioning on a mobile navigation element layout of my design.
Because I have used various Z-index’s and positioning’s when you click on the Nav button to displays mobile navigational links, part of my design is still visible and it obscures the 'return back to normal' nav button.
What I would like to do is add some more JavaScript to the code that it will remove/hide the part of my normal design that is obscuring the Nav button when clicked and then toggle back to display normally when it’s clicked again.
Here is the JS I am using:
jQuery(document).ready(function($){
//move nav element position according to window width
moveNavigation();
$(window).on('resize', function(){
(!window.requestAnimationFrame) ? setTimeout(moveNavigation, 300) : window.requestAnimationFrame(moveNavigation);
});
//mobile version - open/close navigation
$('.cd-nav-trigger').on('click', function(event){
event.preventDefault();
if($('header').hasClass('nav-is-visible')) $('.moves-out').removeClass('moves-out');
$('header').toggleClass('nav-is-visible');
$('.cd-main-nav').toggleClass('nav-is-visible');
$('.cd-main-content').toggleClass('nav-is-visible');
});
//mobile version - go back to main navigation
$('.go-back').on('click', function(event){
event.preventDefault();
$('.cd-main-nav').removeClass('moves-out');
});
//open sub-navigation
$('.cd-subnav-trigger').on('click', function(event){
event.preventDefault();
$('.cd-main-nav').toggleClass('moves-out');
});
function moveNavigation(){
var navigation = $('.cd-main-nav-wrapper');
var screenSize = checkWindowWidth();
if ( screenSize ) {
//desktop screen - insert navigation inside header element
navigation.detach();
navigation.insertBefore('.cd-nav-trigger');
} else {
//mobile screen - insert navigation after .cd-main-content element
navigation.detach();
navigation.insertAfter('.cd-main-content');
}
}
function checkWindowWidth() {
var mq = window.getComputedStyle(document.querySelector('header'), '::before').getPropertyValue('content').replace(/"/g, '').replace(/'/g, "");
return ( mq == 'mobile' ) ? false : true;
}
});
So what I would like to do is add to this a function the removes the div: “#bar_bg_default” onclick and then displays it again when its clicked again.
Something like this would work, but how would I fit it into my Nav JS code?
<script type="text/javascript">
<!--
function toggle_visibility(id) {
var e = document.getElementById(id);
if(e.style.display == 'block')
e.style.display = 'none';
else
e.style.display = 'block';
}
//-->
</script>
Click here to toggle visibility of element #bar_bg_default
<div id="bar_bg_default">This is foo</div>
I just came into this project, the code was already written but we noticed a problem. When you click anywhere in the menu it turns the whole thing gold, you can't see any of the links within that section of the menu. You can click on it again and it will return back to the normal state. This only happens in Internet Explorer 9 and Chrome, no problems in Firefox. The link at the bottom provides an image so you can see the problem.
We have an onclick on the LI for the mobile and IE8 version of the site so they get a nice drop-down menu as well.
When I remove the onclick it takes care of the problem but also prevents the drop-down for the mobile and IE8 users.
Here is the code that I think pertains to this problem:
HTML:
<li id="prospective" class="rightborder" onclick="javascript:showElement('prospective-links')">Future Students
<ul id="prospective-links">
<li>Undergraduate Admissions</li><li>More Links</li></ul>
JS
function showHide() {
var s=document.getElementById("buttonbar").style;
if ($(window).width() > 949) {
s.display = "block";
document.getElementById("prospective-links").style.display = "block";
document.getElementById("current-links").style.display = "block";
document.getElementById("academic-links").style.display = "block";
document.getElementById("facstaff-links").style.display = "block";
document.getElementById("parent-links").style.display = "block";
document.getElementById("alumni-links").style.display = "block";
document.getElementById("visitor-links").style.display = "block";
$("#accordion").accordion('destroy');
$("#buttonbar").unbind('mouseenter');
$("#buttonbar").unbind('mouseleave');
$.fn.pause=function(a){$(this).stop().animate({dummy:1},a);return this};
function mouseleft(){$("#buttonbar").triggerHandler("mouseleave")}
$(document).ready(function()
{$("#buttonbar").mouseenter(function() {$(this).stop().pause(160).animate({height:"12.7em"},400,"easeOutQuart")}).mouseleave(function(){$(this).stop().pause(160).animate({height:"2.2em"},400,"easeOutQuart")});});$(function(){$("#accordion").accordion({fillSpace:!0,icons:{header:"accordion-header",headerSelected:"accordion-headerselected"}})});
if((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)) || (navigator.userAgent.match(/iPad/i))) {
$("#buttonbar li").bind('touchstart', function(){
console.log("touch started");
});
$("#buttonbar li").bind('touchend', function(){
console.log("touch ended");
});
}
}
else {
/*$("#accordion").accordion({active:false});*/
$("#accordion").accordion('destroy');
$("#buttonbar").unbind('mouseenter');
$("#buttonbar").unbind('mouseleave');
$("#buttonbar li").unbind('touchstart');
$("#buttonbar li").unbind('touchend');
s.display = "none";
document.getElementById("prospective-links").style.display = "none";
document.getElementById("current-links").style.display = "none";
document.getElementById("academic-links").style.display = "none";
document.getElementById("facstaff-links").style.display = "none";
document.getElementById("parent-links").style.display = "none";
document.getElementById("alumni-links").style.display = "none";
document.getElementById("visitor-links").style.display = "none";
/*$("#buttonbar").accordion('destroy');*/
}
}
else { function showElement(d){ var s=document.getElementById(d).style;
if (s.display != "block" ) { s.display = "block"; } else { s.display = "none"; } };
And the CSS:
#prospective-links li,
#current-links li,
#academic-links li,
#facstaff-links li,
#parent-links li,
#alumni-links li,
#visitor-links li {
width: 80%;}
prospective-links,
current-links,
academic-links,
facstaff-links,
parent-links,
alumni-links,
visitor-links {
display: none;
}
Menu problem
I'm going to give this a shot with the limited info you have provided.
So the section below the "Future Students" in the image is what you are talking about. You clicked on it and it "turned it gold" like the image.
In actuality what happened was that you clicked on it and it disappeared. Which according to the function you are calling is the correct behavior. It was being displayed so now it hides it. By the way, showElement is a horrible name for this function since that is not what it is doing but you inherited it so you may not have control over that. Something like toggleElement would be better.
function showElement(d){
var s=document.getElementById(d).style;
if (s.display != "block" ) {
s.display = "block";
} else {
s.display = "none";
}
}
My guess is that in mobile and ie8 these sub-menus start out as hidden so this function does what it is supposed to, i.e. shows the sub-menu on first click and then hides it when clicked again. Although the function you show here says that should be happening for any window with a width less than 949px $(window).width() > 949
That is the best I can do with what we have so far.
I'd like to mimick iPhone main screen in JavaScript on Safari / Chrome / Firefox.
By mimicking I mean:
- Having a couple of pages
- Switching between the pages by clicking & dragging / swiping with my mouse
- Having those dots from the bottom iPhone main screen displaying which page it is
The closest to what I want is:
http://jquery.hinablue.me/jqiphoneslide/
But the sliding doesn't work nearly as good as in iPhone (i have to slide first, and the animation appears after i release the mouse button), and there are no dots at the bottom.
I solved the problem by using jQuery & jquery.slide-0.4.3.js .
jQuery Slide automatically slides between each page, so I had to add a mouse event (onMouseDrag) that stops automatic slide & reacts to user. It works very well.
This is what I added to jSlide
var jSlide = function(element, options)
{
element = $(element);
$('ul.layers li', element).sliderDisableTextSelect();
// my code here
var dragging = false;
var srcX;
var offsetX;
var diff;
this.manualDown = function(event) {
dragging = true;
srcX = event.pageX;
offsetX = parseFloat($('ul.layers li', element).css('marginLeft'));
obj.settings.easing = "easeOutExpo";
if(obj.settings.loopNr != null) {
obj.toggleLoop(0);
};
return false;
};
this.manualMove = function(event) {
if (dragging) {
diff = event.pageX - srcX;
$('ul.layers li', element).css('marginLeft',(offsetX+diff)+'px');
console.log((offsetX+diff)+'px');
};
return false;
};
this.manualUp = function(event) {
if (dragging) {
dragging = false;
if ((diff<-obj.settings.layerWidth/5) && (obj.settings.slidePos<obj.settings.layersSize-1)) {
obj.slideTo(parseInt(obj.settings.slidePos)+1);
} else if ((diff>obj.settings.layerWidth/5) && (obj.settings.slidePos>0)) {
obj.slideTo(parseInt(obj.settings.slidePos)-1);
} else { // if not slid far enough nor is it the last slide
obj.slideTo(obj.settings.slidePos);
};
};
};
this.manualLeave = function(event) {
if (dragging) {
dragging = false;
if ((diff<0) && (obj.settings.slidePos<obj.settings.layersSize-1)) {
obj.slideTo(parseInt(obj.settings.slidePos)+1);
} else if ((diff>0) && (obj.settings.slidePos>0)) {
obj.slideTo(parseInt(obj.settings.slidePos)-1);
} else { // if it's the last slide
obj.slideTo(obj.settings.slidePos);
};
};
};
element.mousedown(this.manualDown);
element.mousemove(this.manualMove);
element.mouseup(this.manualUp);
element.mouseleave(this.manualLeave);
And also, to prevent text selection when dragging with mouse I added before jSlide class declaration:
$.extend($.fn.disableTextSelect = function() {
return this.each(function(){
if($.browser.mozilla){//Firefox
$(this).css('MozUserSelect','none');
}else if($.browser.msie){//IE
$(this).bind('selectstart',function(){return false;});
}else{//Opera, etc.
$(this).mousedown(function(){return false;}); // this is handled in jSlide
}
});
});
$.extend($.fn.sliderDisableTextSelect = function() {
return this.each(function(){
if($.browser.mozilla){//Firefox
$(this).css('MozUserSelect','none');
}else if($.browser.msie){//IE
$(this).bind('selectstart',function(){return false;});
}else{//Opera, etc.
// $(this).mousedown(function(){return false;}); // this is handled in jSlide
}
});
});
I'm not sure if all the code is necessary... most probably you'll still need to tweak it after pasting into jquery.slide, but it should get you started..