Javascript override of media query - javascript

I'm creating a responsive site. I have a media query set up so that when the screen width drops below 768 px a class (lets call it "hiddenClass") is hidden. Then I implement Javascript to toggle this class into view on a button click. The problem I'm running into is that javascript seems to override the media query. So if I shrink the screen below 768px the "hiddenClass" disappears....then I click the button which displays the "hiddenClass".....then click the button once more to hide it on the smaller device again.....now I expand the window and the "hiddenClass" stays hidden even after it gets to the 768px. If I take out the javascript and shrink the window the "hiddenClass" performs like it should...which tells me javascript is overriding it.
Is there a CSS fix to this? I know I could always check for a window resize event in javascript to display the hiddenClass after it reaches 768px. Was just wondering if this can be handled with CSS....or if javascript is the way to fix it.
Update JSfiddle with JS commented out so you can see how it should work...then add in the JS to see the issue described above. The button is the 'menu' navigation element when you shrink the screen down and "hiddenClass" would be the "menu" class in the li's:
http://jsfiddle.net/or5vy17L/1/
HTML:
<ul>
<li class="menuButton">- Menu -</li>
<a href="index.html">
<li class="menu" >
Home
</li>
</a>
<a href="instagram.html">
<li class="menu" >
Instagram
</li>
</a>
<li class="menu">Clients</li>
<li class="menu">Nutrition</li>
<li class="menu">About Me</li>
<li class="menu">Contact</li>
</ul>
css:
li {
display:inline;
color:$font-color--nav;
cursor:pointer;
font-size:1.5em;
padding: .7em .7em .7em .7em;
//for space between margins
margin-right:-4px;
border-radius:.5em;
}
ul {
text-align:center;
}
.menuButton {
display:none;
}
#media (max-width:768px) {
ul {
padding:0px;
}
li {
display:list-item;
border:1px solid white;
padding:.2em .2em .2em .2em;
border-radius:0px;
}
.menu {
display:none;
}
.menuButton {
display:list-item;
}
}
javascript:
/****
$('ul').on('click', '.menuButton', function() {
$('.menu').slideToggle();
});
****/

The .hiddenclass is staying hidden because it is a inline style, and inline styles override nearly all other styles. You have two options, one is to override the inline style with a CSS, as described in this CSS Tricks post:
<div style="background: red;">
The inline styles for this div should make it red.
</div>
div[style] {
background: yellow !important;
}
JSFiddle Demo
According to this article, this CSS solution works in:
Internet Explorer 8.0
Mozilla Firefox 2 and 3
Opera 9
Apple Safari, and
Google Chrome
Or, use JS or JQuery to remove the inline style when the screen is resized:
$(window).resize(function(){
if($(this).width() >= 768){
$('.hiddenclass').show();
}
else{
$('.hiddenclass').hide();
}
});
JSFiddle Demo

I seem to have come across this issue myself and following the advice here, I've come up with this solution:
window.onresize = function() {
var menu = document.getElementById('nav').getElementsByTagName('ul')[0];
if(window.innerWidth >= 1024) menu.style.display = '';
};
function toggleMenu() {
var menu = document.getElementById('nav').getElementsByTagName('ul')[0];
var link = document.getElementById('nav').getElementsByTagName('a')[0];
if(menu.style.display == 'block') {
menu.style.display = 'none';
link.innerHTML = '▼';
}else{
menu.style.display = 'block';
link.innerHTML = '▲';
}
}
Explanation:
The toggleMenu() function controls the display/hiding of the menu, and the issue presented itself after resizing the window from < 1024px (drop-down style menu) to > 1024px, my normal "desktop" menu disappeared completely. Given that JavaScript inserts styles inline (i.e. as a element attribute, ) then on a resize of 1024 or higher, this inline style should be gone.
Problem fixed.

Related

i want to show footer navbar on different situation in JQUERY MOBILE

I am making a mobile application with jQuery Mobile, but I have a problem with the Navbar Widget.
Here is the relevant part of my HTML code:
<div data-role="footer" data-position="fixed" data-tap-toggle="false">
<div data-role="navbar">
<ul id="abc">
<li>a</li>
<li id="a">b</li>
<li id="b">c</li>
<li id="c">d</li>
<li id="d">e</li>
<li id="e">f</li>
<li id="f">g</li>
</ul>
</div>
</div>
I want to change the navbar depending on the situation, like this:
f(variable=='?'){
$("#a").hide();
$("#b").hide();
$("#c").show();
$("#d").show();
$("#e").show();
$("#f").show();
}else if(variable=='?'){
$("#a").hide();
$("#b").hide();
$("#c").hide();
$("#d").show();
$("#e").show();
$("#f").show();
}
But the Navbar is still not displayed the way I want. Also, the Navbar does not appear to be displayed in a well-designed way.
How can I obtain this?
I think you're looking for Window.matchMedia which allows you to set a rule like "when the screen size is less than 480px, do this, else other thing".
Here's an example from w3
function myFunction(x) {
if (x.matches) { // If media query matches
document.body.style.backgroundColor = "yellow";
} else {
document.body.style.backgroundColor = "pink";
}
}
var x = window.matchMedia("(max-width: 700px)")
myFunction(x) // Call listener function at run time
x.addListener(myFunction) // Attach listener function on state changes
I'd add that this is also accomplishable via CSS which a lot of folks do to handle this kind of thing - see libraries like Bootstrap or MaterialUI. For more info media queries - check this MDN out.
You have a few errors and unecessary commands in your HTML code example. Consider this simplified example HTML code:
<div data-role="footer" data-position="fixed" data-tap-toggle="false">
<div data-role="navbar" id="mynavbar">
<ul>
<li>Back</li>
<li id="a">a</li>
<li id="b">b</li>
<li id="c">c</li>
<li id="d">d</li>
</ul>
</div>
</div>
Likewise JavaScript code:
let variable = "?";
//let variable = "";
if (variable == '?') {
$("#a").hide();
$("#b").hide();
$("#c").show();
$("#d").show();
} else {
$("#a").hide();
$("#b").hide();
$("#c").hide();
$("#d").show();
}
Check out this Fiddle.
Note that Navbar widget version 1.4.5 official demosite will display differently if the number of items exceeds 5 - in which case the items will be displayed in two columns with multiple rows.
JQM doesn't support out-of-the-box a variable number of navbar buttons. At widget creation, the framework is checking how many items there are inside the list. Then, to get this nice-looking equal-width-buttons effect, the framework is applying some CSS rules: either a two-, three-, four- or five-columns style:
two-columns: each column has 50% width (grid A)
three-columns: 33% width (grid B)
four-columns: 25% width (grid C)
five-columns: 20% width (grid D)
To get an idea of that CSS rules, see here a description of the Grid widget: Grids - jQuery Mobile Demos.
Now, I believe the simplest solution to Your needs is to check how many toolbar buttons You need:
Example: adding an extra column to get a total of max. 6 columns:
.ui-grid-e {
overflow: hidden;
}
.ui-grid-e > .ui-block-a,
.ui-grid-e > .ui-block-b,
.ui-grid-e > .ui-block-c,
.ui-grid-e > .ui-block-d,
.ui-grid-e > .ui-block-e,
.ui-grid-e > .ui-block-f {
width: 16.666%;
}
.ui-block-f {
margin: 0;
padding: 0;
border: 0;
float: left;
min-height: 1px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
and then, depending from Your situation, override the original CSS rule with Your custom style, i.e. 100% / n. of cols. Hidden columns doesn't matter, while the visible columns will take the full-width space.

Make anchor link go some pixels above id

I'm currently working on a website and I'm having a trouble with anchors. My header is fixed and when I click on anchor it sends me on other page how it is supposed to be, but I'm missing 80 pixels which is height of my fixed header. There is a script that made accordion opened on new page when I click on anchor but it should scroll 80px less... here is some code I have over there in my .jsp file
<a href="${parentLink}#${menuItem.name}" class="${menuItem.classes[anchorClasses]}">
and there is a .js that makes my accordion opened on the new page
$(document).ready(function () {
if (location.hash != null && location.hash != "") {
$('.collapse').removeClass('in');
$(location.hash + '.collapse').collapse('show');
}
});
I think that you guys will need more info, so ask me anything that could help you. I'm new in this and I don't even know which code should I post here to help you guys realize what the problem is... Thank you (:
One common way is to add an invisible pseudo element to the original target element of the link via CSS, like this:
#your_anchor_id::before {
display: block;
content: " ";
margin-top: -80px;
height: 80px;
visibility: hidden;
pointer-events: none;
}
This will "extend" the element with that ID in a way which causes the anchor to be 80px above the main element, without causing any other visible changes.
Another idea is to use smooth scrolling with an offset. (View the example "Full Page" by clicking that link at top right of the snippet window)
$("nav ul li a").on('click', function(event) {
if (this.hash !== "") {
var myOffset = $('#myOff').val(); //get value from input (offset value)
if (myOffset==='') $('input').addClass('alert');
event.preventDefault(); // Prevent default anchor click behavior
var hash = this.hash; // Store hash
// jQuery animate() method for smooth page scroll
// 900 is the number of ms to scroll to the specified area
$('html, body').animate({
scrollTop: $(hash).offset().top - myOffset
}, 900);
} // End if
});
//$('div:contains(Section)').css('font-weight','bold');
html,body{margin:0;padding:0;font-family:Calibri;}
body{height:2500px;}
ul,li{margin:0;padding:0;}
*{box-sizing:border-box;}
section{
display: grid;
place-items: center;
width: 100%;
height: 500px;
}
nav{position:fixed;width:80vw;background:white;border:1px solid red;}
::placeholder{color:#ccc;}
nav ul li{
display: inline-block;
padding:0;
border: 1px solid rgba(200,200,200,0.3);
}
nav ul li:hover{background: #ddd;}
a{text-decoration:none;padding:10px 25px;display:inline-block;}
#one{background:palegreen; padding:50px;}
#two{background:palegoldenrod;}
#twa{background:lightblue;}
#fer{height:1500px;}
.alert{border:1px solid red;background:#ffc0cb99;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<ul>
<li>NAV / HEADER:</li>
<li>One</li>
<li>Two</li>
<li>Three</li>
<li><input id="myOff" type="text" placeholder="Offset (e.g. 75):" /></li>
</ul>
</nav>
<section id="one">
<div>
<div style="text-align:center">Section One</div>
<div>Directions:<br>(a) View as Full Page (link at top right)<br>(b) Enter offset number (for how many pixels the smooth-scroll will stop short)<br>(c) Click nav "Two" or "Three" and observe<br>(4) Repeat using a different offset value<br>Note: The fixed header is deliberately not full width in order to show the top of the next section scrolling UNDER the header (undesireable) The offset prevents that, and is what you are asking about.</div>
</div>
</section>
<section id="two">
Section Two
</section>
<section id="twa">
Section Three
</section>
<section id="fer">
Section Four
</section>
Example code ripped off from:
w3schools Company Theme example

How to get rid the inline style using jquery or javascript

How to remove these two inline style beside the .dropdwon menu, I tried the remove attribute [ jQuery('.dropdown-menu').removeAttr('style'); ] unfortunately it doesn't remove the inline style. Every time I hover the nav the inline style change to display block and when it hover out the inline style is set to display:none
<ul role="menu" class=" dropdown-menu" style="display: none;">
<ul role="menu" class=" dropdown-menu" style="display: block;">
Here's my code. I'm trying to remove this on size 767 or mediaquery max-width(767)
jQuery(window).resize(function() {
var width = jQuery(window).width();
if( width < 767 ) {
jQuery('.dropdown-menu').removeAttr("style");
}
});
jQuery(document).resize(function() {
var width = jQuery(document).width();
if( width < 767 ) {
jQuery('.dropdown-menu').removeAttr("style");
}
});
please see the two attached image for better visualization
When I hover the nav(About) the subpage show(ul.dropdown-menu) and the inline style will set to display block
When I hover out the nav(About) the subpage (ul.dropdown-menu) inline style will set to display none
Please help me get rid these two inline style the style="display:none"; and style="display:block";
Try with show()
jQuery('.dropdown-menu').show()
or css()
jQuery('.dropdown-menu').css('display','block')
Drag the output window of the fiddle .They will show the menu on resize
Demo Fiddle
There is a JavaScript somewhere that is adding those styles. I guess you are using some framework or template you found in the Internet. Now you either have to remove the not-needed code that adds the styles (recommended!) or bind over it to be removed each time, something like what you have written but in different event:
jQuery('.dropdown-menu').hover(function() {
jQuery('.dropdown-menu').removeAttr("style");
}, function() {
jQuery('.dropdown-menu').removeAttr("style");
});
Ensuring this is after the piece of code that does the style adding at first place.
Or you can try totally removing the behaviour for the menu and write your own:
jQuery('.dropdown-menu').unbind();
Try to append at the end of your main css file a rule-set declaration on .dropdown-menu selector with the property display:none for media-query < 767:
#media screen and (max-width: 766px) {
.dropdown-menu {
display:none;
}
}
You can use click instead of hover for mobile, and display: none; by default, set in CSS. Then add a media queries for PC (here > 767px) to force display: block;. The good thing is that you limit the use of JS.
This is a working example of what can be done.
EDIT
I updated the snippet with an example which is, I think, closer to your code.
$('.menu-item').click(function() {
$(this).toggleClass("active");
});
.menu-item .dropdown-menu {
display: none;
}
.menu-item.active .dropdown-menu {
display: block !important;
}
#media only screen and (min-width: 767px) {
.menu-item .dropdown-menu {
display: block !important;
}
}
<ul role="menu" class="menu">
<li class="menu-item">Menu 1</li>
<li class="menu-item">
Menu 2
<ul role="menu" class="dropdown-menu" style="display: none;">
<li>Submenu 1</li>
<li>Submenu 2</li>
<li>Submenu 3</li>
</ul>
</li>
</ul>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Media Query conflicts with $(window).resize()

I've got a left nav div that hides via media query at < 768 and a filter button that displays at < 768. When you click the filter button it uses JQuery to toggle the display of the left nav via show()/hide(). When the window is resized >= 768 I use JQuery to set the display of the left nav back to show.
As I said, my media query handles hiding the left nav when the window width goes below 768, but the problem is it only fires if I have not clicked the filter button. Once I size it under 768 and then click the filter button to turn it on and then click it again to turn it off and then size up over 768 and then back down the left nav is still there. It's like the media query no longer works for the display:none attribute. There are other css properties I change in the media query like width and color and those still work, but it's no longer hiding the div.
I've simplified the code to illustrates the problem.
HTML
Button
<div id="navLeft">NavLeft</div>
CSS
#navLeft {
background-color:orange;
}
#filterButton {
background-color:silver;
display: none;
}
#media only screen and (max-width: 300px) {
#navLeft {
display: none;
}
#filterButton {
display: inline;
}
}
JS
$(window).resize(function()
{
var $theWindowSize = $(this).width();
if($theWindowSize > 300)
{
$('#navLeft').show();
}
});
// Filters
$('#filterButton').bind('click',function(event)
{
event.preventDefault();
if ($('#filterButton').hasClass('filtersActive'))
{
$('#navLeft').hide();
$('#filterButton').removeClass('filtersActive');
}
else
{
$('#navLeft').show();
$('#filterButton').addClass('filtersActive');
}
});
Here's the fiddle. To replicate the behavior follow the steps below.
https://jsfiddle.net/athcy8fL/
1) Resize the width of the Result viewport several times under and above 300px before clicking anything and you'll see everything works as planned. Under 300px the button comes on and the NavLeft div hides. Over 300px and the Button hides and the NavLeft shows
2) Size the Result viewport below 300px and click the Button link. The NavLeft div should appear. Good.
3) Size the Result viewport above 300px and the Button hides. Good.
4) Size the Result viewport below 300px, the NavLeft should hide but it does not. Not Good.
Why doesn't the media query work after using Javascript to alter its display property?
The problem is that when you call .show() in an element that is not already visible, jquery will add an inline style to show the element and override your css, causing the media-query not to work.
I modified your code a little bit to take the inline-style priority into account
http://jsfiddle.net/yjs3fou7/
basically I changed the resize function:
$(window).resize(function()
{
var $theWindowSize = $(this).width();
if($theWindowSize > 300)
{
$('#navLeft').show();
$('#filterButton').removeClass('filtersActive')
} else {
if (!$('#filterButton').hasClass('filtersActive'))
$('#navLeft').hide();
}
});
inline styles have more priority than id or class styles according to css specificity rules so once you start manipulating things from javascript you must remember it may cause your css to stop being applied
The problem is the use of inline styles which has more specificity than the css rules.
$(window).resize(function() {
var $theWindowSize = $(this).width();
if ($theWindowSize > 300) {
$('#navLeft').removeClass('show');
$('#filterButton').removeClass('filtersActive');
}
});
// Filters
$('#filterButton').bind('click', function(event) {
event.preventDefault();
$('#filterButton').toggleClass('filtersActive');
$('#navLeft').toggleClass('show', $('#filterButton').hasClass('filtersActive'));
});
#navLeft {
background-color: orange;
}
#filterButton {
background-color: silver;
display: none;
}
#media only screen and (max-width: 300px) {
#navLeft {
display: none;
}
#filterButton {
display: inline;
}
#navLeft.show {
display: block;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Button
<div id="navLeft">NavLeft</div>
Demo: Fiddle

Button auto size in Jquery Mobile

I am developing a jquery/PhoneGap application. I have been trying hard to get the buttons behave the way I want to. In short I am trying to achieve the following:
I put a set of six Jquery-Mobile buttons (mini, normal or button-group).
The above set needs to be in one horizontal line so I have put them in a div.
The numbers of buttons and its text dynamically changes, so I need a CSS/JS trick that allows me to resize the button size and text based on the div/screen size. When I started with Jquery mobile (two weeks ago), I thought that this will be a basic functionality :) but alas !
Some code that I am trying right now is:
//TO CREATE BUTTONS
for(var button_id=0; button_id < window.g_maxLength/2; button_id++){
var bt_id= "<button class =\"tile\" data-theme=\"e\" data-inline=\"true\" data-mini=\"true\" id =\"button_tid"+button_id+"\";>.</button>";
$("#buttoncontainer1").append($(bt_id));
}
//HTML
<div id="tiled" align="center">
<div data-role="controlgroup" data-type="horizontal" id="buttoncontainer1">
<!-- Button will be added by JS-->
</div>
</div>
//CSS
#tiled {
align:center;
height:23%;
position:absolute;
text-align :center;
padding: 1px;
width:90%;
top:73%;
margin-right:4%;
margin-left:4%;
background-color:#b0e0e6;
border-radius: 10px;
border-width: 3%;
border-style:double;
Right now what I have is works fine on small screen devices, but as soon as I open my app in large screen device the buttons look very small with lot of empty spaces. Any help here will be appreciated !!
PS: Also used media queries - but they somehow do not work on jquery-mobile.
#media (min-width: 500px) {
html { font-size: 120%; }
}
Here's a workaround for auto-adjust width and font-size of buttons.
Demo: http://jsfiddle.net/Palestinian/UYa4Y/
// Number of buttons
var buttons = $('[data- role=controlgroup]').find('a').length;
// Parent div width
var btn_width = $('#tiled').width() / buttons;
// Remove left/right button padding
$('.ui-btn-inner').css({
'padding-left': 1,
'padding-right': 1
});
// Set button new width
$('.ui-btn-inner').width(btn_width - 4);
// Adjust font-size for each button based on text
$('.ui-btn-text').each(function () {
while ($(this).width() > $('.ui-btn-inner').width()) {
var font = parseFloat($(this).css('font-size')) - 1 + "px";
$(this).css('font-size', font);
}
});

Categories