Responsive Design and onclick events - javascript

I have a mobile menu button (only viewable with display:block by using media queries). When the button is clicked, my main "mobile" menu appears - I do this using simple javascript code (see below).
The problem ... if I click the button to expand the menu (changing the inline style from display:none to display:block), and then increase the browser size ... my menu doesn't disappear anymore. So, the inline style doesn't recognize the media query...
Below is the script that expands my menu...
<!-- Menu Expander / Toggle Visibility -->
<script type="text/javascript">
function toggle_menu(id) {
var e = document.getElementById(id);
if (e.style.display == 'block') e.style.display = 'none';
else e.style.display = 'block';
}
</script>
Here are some of the styles.... you'll see the menu-mobile (which is the actual menu) and the mobile-menu-but (which is the button) is hidden (with display:none). When the browser window is reduce, the button appears (with display:block in the media query), but the menu is still hidden. Then when you click the javascript button, the inline style display:block is added to set for the mobile-menu.
#mobile-menu-but, #menu-mobile { display:none; }
#menu a, #menu a:link { padding: 15px 16px 12px 16px; }
#media (max-width: 790px) {
/* Switch to Mobile Menu when too long */
#menu { display:none; } /* Hide Main Menu */
#mobile-menu-but { display:block; float:right; margin:0 20px 0 0; height:50px; padding:5px 0; }
#mobile-menu-but a { float:right; }
.menu-txt { margin:10px 10px 0 0; float:right; }
#menu-mobile { width:100%; background-color:#000; text-transform:uppercase;
font-size:16px; font-family:"AvantGarde", "Helvetica Neue", Arial, Helvetica, sans-serif; } }

Instead of directly manipulating element styles, you can add and remove class values in order to change element appearance. The rules for the class(es) can be affected by media queries because they'll go right into the stylesheet.
Modern browsers provide the .classList API:
function toggle_menu(id) {
var e = document.getElementById(id);
if (e.classList.contains("showing"))
e.classList.remove("showing");
else
e.classList.add("showing");
}
Now, in your CSS, you can have:
#menu { display: none; }
#menu.showing { display: block; }
If you only want to show the menu when the screen is big, add this after those lines above:
#media screen and (max-width: 700px) { /* or whatever size you want */
#menu.showing { display: none; }
}
(There are other strategies for arranging rules in media queries, depending on what you're trying to do.

Rather than add and remove the inline style with e.style.display , use
var e = document.getElementById("someID");
e.className = "someClass";
The problem you have is your inline style is overriding your CSS. Inline style will always have this priority (unless !important I guess - not sure about that).

Here's a trick you can use to avoid JavaScript altogether:
#menu {display:none}
#secret_checkbox {position: absolute; left:-9999px}
#secret_checkbox:checked + #menu {display: block}
<label for="secret_checkbox">Click to open/close menu</label>
<input type="checkbox" id="secret_checkbox" />
<div id="menu">Hello!</div>
The label can be anywhere, the important thing is for the "hidden" checkbox to be immediately before the element it affects. This can make it a lot easier to change how things behave in CSS, plus it has the added benefit of working even if the user has JavaScript disabled ;)

Related

Unwanted White Space Mobile View HTML / Burger Menu Size

I've recently been making a website and for some reason working on media queries for it to fit mobile view. It has lots of extra white space which is confusing to me.
My problem : Extra white space in mobile view, that im positive is caused by the "MainMenu" dropdown from a "Burger" that I'm using. It seems like MainMenu has a min-width instead of width 100% but I don't know why. Also on Mobile View you can scroll really far out of the webpage and get all this extra white space.
Here is some code of the MainMenu :
CSS -
/* Nav Main Menu */
nav .mainMenu {
display:flex;
list-style: none;
}
nav .mainMenu li a {
display: inline-block;
padding: 30px;
margin:10px;
text-decoration: none;
color: rgb(0, 0, 0);
font-size: 1.5rem;
font-family:'Courier New', Courier, monospace;
}
nav .mainMenu li a:hover {
color: rgb(0, 110, 255);
}
JS Burger Script -
function show(){
mainMenu.style.display = 'flex';
mainMenu.style.top = '0';
}
function close(){
mainMenu.style.top = '-100%';
}
Here is some reference images of my problem :
My Question : How can I remove extra white space on my page, and set the burger menu to width of 100%.
Heres my github/website to check it out fully : https://github.com/ConstantineLinardakis/TwinPlayzOfficial
https://constantinelinardakis.github.io/TwinPlayzOfficial/index.html
The error you are facing isn't because of the Menu. I debugged your website using the dev tools and I found out that
<p> © TwinPlayz 2021</p>
This is the line that is consumingunnecessary space. Add an id to that paragraph like this,
<p id="copyright_text"> © TwinPlayz 2021</p>
And then add the following CSS with the media query
#media (max-width: 600px) {
#copyright_text {
width: 130px; //adjust to your own needs
}
}

How do I stop button from scrolling down to Contact form?

I'm not a coder or developer. I'm trying to save us money, and fix a problem with my wife's responsive WordPress site.
We hired an SEO guy who said he could also write custom JavaScript for us. He created a call to action button that behaves differently between desktop (scroll to Contact Us form) and mobile (Call Now).
I noticed he was duplicating the function, in the header custom HTML, to scroll to form on both function calls of the button. I changed his custom code in the header to use href="tel:xxxxxxxxxx".
It still scrolls to the contact form. I used the same HTML for our contact info in the footer, and that works fine. I'm stumped.
Please help.
Here is the code he wrote:
JavaScript:
setTimeout(function() {
window.scrollTo(0, 0);
}, 1);
jQuery(function($){
function scrollToForm() {
$([document.documentElement, document.body]).animate({
scrollTop: $('#contact-form').offset().top
}, 1000);
}
if (window.location.hash == '#contact-form'){
setTimeout(function(){
scrollToForm();
}, 1000);
}
$('.top-cta-btn').click(function(e){
scrollToForm();
if (window.location.href == 'https://www.sironatherapies.com/#contact-form' ||
'https://www.sironatherapies.com/') {
return false;
}
});
});
Custom HTML Header:
<style>
.top-cta-btn {
background: #dd9f27;
padding: 13px;
color: #000;
cursor: pointer;
}
.top-cta-btn:hover {
color: #fff;
}
#media (min-width: 320px) and (max-width: 767px) {
.header_bottom_right_widget_holder {display: block !important}
.top-cta-container {display: none}
.top-cta-container-mobile {display: block;
margin-bottom: 30px;
margin-top: 35px;}
.testimonials-section {display: none}
.side_menu_button {display: none;}
.vc_custom_1454330137581 {display: none;}
}
#media only screen and (max-width: 1000px){
.q_logo a {
left: -80%;
width: auto!important;
}
}
#media only screen and (min-width: 768px) {
.top-cta-container {display: block}
.top-cta-container-mobile {display: none}
}
</style>
<div class="top-cta-container">
<a class="top-cta-btn" href="/#contact-form">Book an Appointment Today</a>
</div>
<div class="top-cta-container-mobile">
<a class="top-cta-btn" href="tel:xxxxxxxxxx">Call Now</a>
</div>
You need to change the CSS selector in the Call-to-Action event handler, in order to target only the Desktop CTA button and not the mobile one:
Now:
$('.top-cta-btn').click(function(e){
scrollToForm();
...
Should be:
$('.top-cta-container .top-cta-btn').click(function(e){
scrollToForm();
...
This way, you are limiting the scrolling, only when the element .top-cta-btn that is inside the .top-cta-container element (Desktop/Contact Form link) is clicked.
The mobile CTA button will not get triggered since it is inside another element, the .top-cta-container-mobile.
Also, there's no need for the duplicate code. You can remove it.

replace link text with graphic through css

I want to replace the links in my bootstrap navigation with icons. But only when A class is added to the navigation. I currently have a fixed navigation which 'shrinks' when the user scrolls using
html (head)
$(function(){
var shrinkHeader = 100;
$(window).scroll(function() {
var scroll = getCurrentScroll();
if ( scroll >= shrinkHeader ) {
$('header').addClass('shrink');
}
else {
$('header').removeClass('shrink');
}
});
with the 'shrink' class added to header div when scrolled 100px.
css
.navbar-custom .nav>li>a {
font-size: 1.15em;
font-weight: 400;
etc...
header.shrink {
min-height: 50px;
}
header.shrink .nav>li>a { line-height: 50px; }
when the 'shrink' class gets added to the .header I want the links (which are currently text) to turn into icons. not sure the approach for this
I have fontawesome installed and usable
In my previous project, I had the icons already inside the DOM but only hidden. I made them display if the parent had a certain class
.nav>li>a>.fa { display: none; }
.shrink .nav.li.a.fa { display:block; }
Edit:
Added jsfiddle
Edit2:
Updated jsfiddle. You can add font awesome icons using pseudo classes. You can get the unicode easily with a bit of googling
I would add the HTML markup for the icons inside your anchor tag and hide it by default:
header .nav > li > a > span.icon {
display: none;
}
And show it when the header has the .shrink class:
header.shrink .nav > li > a > span.icon {
display: block; (or inline)
}

JavaScript add and remove class function on click

Basically I have this problem. I have an accordion that toggles one heading open at a time and I am having a problem adding in the open/close image that sits to the right of the heading.
I have it so far so that once you click a heading it removes the 'open' image and toggles another class for the 'close' image. Now I need to basically swap out these classes again so that if you toggle another heading it removes the other image and goes back to the original.
Here is the code I am using.
JavaScript
<SCRIPT>
$("#accordion > li").click(function () {
$("#accordian li").removeClass("faq-header");
$(this).addClass("faq-header2");
if (false == $(this).next().is(':visible')) {
$('#accordion > ul').slideUp(250);
$('#accordion > ul').addClass('faq-header');
$(this).removeClass("faq-header");
}
$(this).next().slideToggle(300);
});
$('#accordion > ul:eq(0)').show();
</SCRIPT>
CSS
#accordion {
list-style: none;
margin-left:-38px;
}
#accordion ul:eq {
background-image:url(../img/faq-open.gif);
background-repeat:no-repeat;
background-position:right;
padding-right:20px;
}
#accordion li{
display: block;
background-color: #FFF;
font-weight: bold;
cursor: pointer;
}
.faq-header {
text-align:left;
background-image:url(../img/faq-close.gif);
background-repeat:no-repeat;
background-position:right;
margin-right:20px;
}
.faq-header2 {
text-align:left;
background-image:url(../img/faq-open.gif);
background-repeat:no-repeat;
background-position:right;
margin-right:20px;
}
#accordion ul {
list-style: none;
display: none;
}
#accordion ul li{
font-weight: normal;
cursor: auto;
background-color: #fff;
border-bottom:1px solid #999;
margin-left:-38px !important;
}
I have removed one class and added another class as you can see $("#accordian li").removeClass("faq-header"); and added the following $(this).addClass("faq-header2");
But I need to now remove .faq-header2 and add back .faq-header after it is no longer the section selected. It doesn't seem too hard to me but i just can't figure out how to code it. Should be a basic if function I would think...
The jQuery UI accordion is a well proven cross browser widget, and does images on open and close (by default on the left, but one change of CSS will put them on the right)
as per here
if you don't won't to use it, I would persue an option with toggleClass, here
EDIT
Thanks for posting your HTML, I didn't necessarily mean the whole page, just the HTML for you accordion functionality, but hey thats cool
First point though, your HTML seems a bit heavy for just doing an accordion. Its also not entirely valid to put a ul inside a ul (they tend to go inside li, as in a drop down menu style). Further more it doesn't seem to be much point in all those ul and li as each ul only has one li anyway, just seems like a lot more tags than you would really need. ul and li tend to come with a lot of default styling (bullet points, margins, padding, indents etc), which can mean a lot more CSS than need to make them display how you want. I would have gone with a simpler structure, makes it easier to write your jQuery. A bit more like this
<div id="accordion">
<h3>First header</h3>
<div>First content</div>
<h3>Second header</h3>
<div>Second content</div>
</div>
Anyway, that was just a comment from my experience. To your problem at hand, this worked for me
$("#accordion > li").click(function () {
var self = $(this);
self.next('ul').slideToggle(300, function () {
if ($(this).is(':visible')) {
self.removeClass('faq-header').addClass('faq-header2')
}
else {
self.removeClass('faq-header2').addClass('faq-header')
}
});
self.siblings().removeClass('faq-header2').addClass('faq-header').next('ul').slideUp(250);
});
toggleClass, although useful, in your circumstance as to how you want classes to be added and removed, may not be as useful as I would have thought
I think that toggle() function is a bit not intuitive. I usually use my pwn method replaceClass() to do as you want:
void replaceClass(Object classList, String surrogateClass, String classToReplace);
defined as follow
function replaceClass(elementClassList, firstClass, secondClass) {
if(elementClassList.contains(firstClass)){
{
elementClassList.remove(firstClass);
elementClassList.add(secondClass);
}
}

Strange behavior in IE when combining click handler with CSS sibling selector

I am trying to design a menu that is triggered by clicking a button. When the user clicks the button, a click handler runs which adds a class to the button, and a CSS rule using an sibling selector makes the menu visible. It works fine in all the browsers I tested except IE 7 and 8.
In IE 7 and 8, I am experiencing these problems:
Clicking the button toggles the class but the menu doesn't appear or disappear until I move the mouse around a little bit.
The menu doesn't work at all unless I have a CSS :hover declaration for children of the menu. It doesn't matter what I put in the declaration, or if I put anything at all, but the menu does not show up without it.
Can anyone tell me why this is happening and what I can do about it? I was thinking of adding a separate class to the menu but I am wondering if there is a simpler fix or workaround. Here is my code:
<!DOCTYPE html>
<html><head>
<title>IE selector test</title>
<style type="text/css">
button {
border: outset 1px #eeeeee;
}
button.active {
border-style: inset;
}
.menu {
display: none;
border: solid 1px #888888;
}
button.active ~ .menu {
display: block;
}
.menu > :hover {
/* For some reason, the menu doesn't work at all without this declaration */
}
</style>
</head>
<body>
<button type="button" id="menuButton">Menu</button>
<div class="menu">
<div>option</div>
</div>
<script>
document.getElementById("menuButton").onclick = function() {
if (this.className) {
this.className = "";
} else {
this.className = "active";
}
};
</script>
</body>
</html>
You can also test it at http://jsfiddle.net/QKqpn/.
You can work around it by forcing page redraw:
document.body.className = document.body.className;
See http://jsfiddle.net/uGW4M/
BTW, in your case you can use + (one immediate sibling) combinator instead of more common ~ (all subsequent siblings):
button.active + .menu {/* ... */}

Categories