I am working with window.matchMedia(), and I cannot seem to get the function to apply a secondary class when a max or min width is reached. I've recreated the problem below with a simple font-size change.
I've read up on matchMedia() and I've tried this two different ways (both are included below). Do I need to include both a min and max value in order to have the function execute? Or am I missing something within the actual structure of the function itself?
$(document).ready(function() {
var mq = window.matchMedia('(max-width: 700px)');
if( mq.matches ) {
$('.title').addClass('big')
} else {
$('.title').removeClass('big');
}
});
/*
Second method I tried
$(function() {
if( window.matchMedia('(max-width: 700px)').matches){
$('.title').addClass('big')
} else {
$('.title').removeClass('big');
}
});
*/
.title {
font-size: 20px;
}
.big {
font-size: 30px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1 class="title">This is a title</h1>
It is working, maybe you are expecting it to detect screen resize?
You have it bound to document.ready() so you have to refresh the page to see it.
Try it out:
Make windows smaller than 700px, refresh
make window larger then 700px, refresh
Notice difference :)
In another words:
$(document).ready(your function)
Your function only executes once for each time page is loaded.
Alternatively, use this fiddle and run it. Make result window larger or smaller than 700px and run it again.
If you need to run it every time when window width resizes I would recommend binding to window.onresize as I did in this fiddle with execution on resize event
Notice the console.log I put there for you to see how and when it is triggered, you wanna remove it before going production ;)
Related
So, I've got a button that display toggles a div on a click event. It works properly. However, I can't hide the same div using nearly the same code (however, I want to toggle this div after my screen becomes too big, not after clicking), because I get the problem like in the title- 'cannot read property style of null'
The part that doesn't work (hiding a div after screen becomes too big:
if (screen.width > 900) {
document.getElementById('klik').style.display = 'none';
}
And the part that works (button toggles a div using a click event):
function showDiv() {
if (document.getElementById('klik').style.display == 'block'){
document.getElementById('klik').style.display = 'none';
}
else{
document.getElementById('klik').style.display = 'block';
}
}
I wrote this code because I want to do a scalable menu, displaying a div with list items inside after clicking on it. The menu button is visible only when screen-width <= 900px, if screen-width > 900px I've got a normal navigation bar and the button disappears.
Am I forgetting something? I'm new to Javascript. Also one more thing- it also doesn't work using #media rule, however I can change the background-color with #media. I hope it might help. Also thanks in advance.
Note Two Problems:
Ensure that the element you want to change it's display has the id="klik"
The below code will execute only once.
if (screen.width > 900) { document.getElementById('klik').style.display = 'none'; }
But why?
The answer is because you didn't set an event to run it every time when your resize the screen. Also, screen.width will always return the width of the display. What you are looking for is the window.innerWidth
So a possible solution:
window.addEventListener('resize', function(){
document.getElementById("screen").innerHTML = window.innerWidth.toString() + "px";
if(window.innerWidth < 900)
{
//Perform your desired Executions Here
}
});
<div id="screen"></div>
This will run the code every time a window.onresize is triggered. And that's exactly what #media in CSS does. It works on window.onresize behind the scene in javascript sense.
Note: I have added a simple illustration on how to work with screen.resize which you can use as the basis for modifying element properties based on a certain range. All you need to do, is to ensure that you do your styling within that block and it will work.
Hmmm, actually this is exactly what media queries are made for. Did you try
#media (min-width: 900px) {
#klik {
display: none;
}
}
If that doesn't work: Are there any other css styles that may overwrite that particular style? Something like #klik { display: block !important; } ...?
Note: I rarely use JS and jQuery so please excuse if the question is odd.
I am trying to add a div to my page (to a menu specifically) but only if the page is smaller than a certain width. Basically I need an event handler that allows me to wait for that condition to be met and run a function once it is (similar to how you would do with on.("click")) but I have no idea how to accomplish that.
Any help would be greatly appreciated!
have a look at the following code:
var $myDiv = $("<div class='myDiv'></div>");
$(window).resize(function () {
var windowWidth = $(this).width();
if (windowWidth < 200) {
$("body").append($myDiv);
} else {
$myDiv.remove();
}
});
we monitor the window resize event, and append/remove the div as per your condition.
Live Example
play around with the bottom right side of the fiddle (the result pane) and resize it to see what happens.
This is without the event handler, but you can add it in a resize event handler:
if (window.matchMedia("(min-width:700px)").matches) {
// viewport width is at least 700px
} else {
// viewport is smaller than 700px
}
hope you can help
My current project requires me to recall a set of functions on window resize so that I can keep the responsive nature correct. However the code I am using is rather twitchy as it calls the functions even if the window is resized by 1px.
I am relatively new to jQuery but learning more and more every day, but this is something I'm struggling to find a way to do.
In an ideal world I would like to call the functions when the window has been resized over a breaking point at anytime, for example:
say the breaking point is 500px, the initial load size is 400px the user resizes to 600px, so over the threshold so call the functions again.
It would also need to work in reverse... so window (or load) size 600px, breaking point 500px, resize to 400px call functions.
Here's the code I'm currently:
var windowWidth = $(window).width();
var resizing = !1;
$(window).resize(function(a) {
!1 !== resizing && clearTimeout(resizing);
resizing = setTimeout(doResize, 200);
});
function doResize() {
call_these_functions();
}
Cheers for the help guys
Thanks for the reply Zze
I am using something similar to what you've put, but I have it based within the start of my functions to filter what each thing does based on the window size. My problem is that these are getting called far too often and causing issues / twitchy behaviour.
For example I'm having issues on a tablet I'm testing on, when you scroll down, the scrollbar that appears on the right seems to trigger the window resize... causing functions to be called again that automatically accordion up or .hide() elements to their initial loaded state.
So my thinking is if I can test it's actually broken a set threshold rather than just what size the window is then it will be far more reliable.
There are some really handy jQuery functions available and it looks like you are very close to cracking this yourself. Hope this helps though.
$(window).resize(ResizeCode); // called on window resize
$(document).ready(function(e) { ResizeCode(); }); // called once document is ready to resize content immediatly
function ResizeCode()
{
if ($(window).width() < 500){
//insertCode
}
else if($(window).width() >= 500){
//insertCode
}
}
Update
If we are looking to 'restrict' the call time of this function, then you could add an interval which updates a bool every time it ticks, and then check this bool in the previous code:
var ready = true;
setInterval(function(){ready = true;}, 3000);
function ResizeCode()
{
if (ready)
{
// run code
ready = false;
}
}
But i would suggest storing the width and height of the window in a var and then comparing the current window with the var when the window is resized, that way you can tell if the window has actually been resized over 'x' amount or if it is that weird bug you've found.
Looks like i've found a solution that's going to do what i need with a little work (fingers crossed as i'm currently working on it), from http://xoxco.com/projects/code/breakpoints/
Thanks for the help Zze
So basically, I am attempting to use jQuery to give my navigation bar (Bootstrap navbar) a 100% width, but in pixels.
Of course, this has to be determined every time the browser/window is resized.
I came up with this, although it is extremely buggy. It uses the starting width of 'nav' as 'navsize', and upon resize of the window, navsize still stays the same.
$(document).on('ready', function () {
$(window).on('resize', function () {
var navsize = $('nav').width();
$('nav').css('width', navsize);
}).trigger('resize');
});
I have also tried var navsize = $('nav').innerWidth(); which was also no good.
The function is definitely being called upon resize since I have tested with console.log()
For all those who are wondering why I am doing this, I am using StickyJS to make my navigation scroll with the page. Although, since it is using 100% width, upon scrolling it becomes much smaller since the nav leaves its container.
This should work
$(document).on('ready', function () {
$(window).on('resize', function () {
$('nav').css('width', 'calc(100% + 1px - 1px)' );
console.log( $('nav').width() );
/// Use following ONLY if you specifically want to set the width in pixel
$('nav').width($('nav').width());
}).trigger('resize');
});
the console.log will have your width in pixel. Means whenever in future you will read the width , it will be in pixel.
calc(100% + 1px - 1px) converts the width and sets in px units, which we can read later on.
Are you sure that $('nav') exists?
I've done some testing using a basic bootstrap page and a slightly change of your code works.
Navigate to this page and open the console inspector.
http://getbootstrap.com/examples/starter-template/
paste the following code and you will see that the .navbar width will be logged on window resize.
$(window).on('resize', function () {
var navsize = $('.navbar').width();
console.log(navsize)
});
Cheers.
It'd be easier with the supporting HTML and CSS, but I will venture a guess based on the behavior alone.
Best Guess
It sounds like one of these options is likely.
you meant to use #nav, .nav, div.nav, etc and don't actually mean to select a "nav" element
your "nav" element is not display inline-block|block, which occurs in some browsers
you are using the "nav" tag in a browser that doesn't support it (IE 8)
your JS library doesn't support the "nav" tag
Alternative
Use JS to relocate your nav into the body (at the appropriate scroll depth) and give your html , body, and nav tags width 100%
Hope that helps.
i got a client side javascript function which is triggered on a button click (basically, its a calculator!!). Sometimes, due to enormous data on the page, the javascript calculator function take to long & makes the page appear inactive to the user. I was planning to display a transparent div over entire page, maybe with a busy indicator (in the center) till the calculator function ends, so that user waits till process ends.
function CalculateAmountOnClick() {
// Display transparent div
// MY time consuming loop!
{
}
// Remove transparent div
}
Any ideas on how to go about this? Should i assign a css class to a div (which surrounds my entire page's content) using javascript when my calculator function starts? I tried that but didnt get desired results. Was facing issues with transparency in IE 6. Also how will i show a loading message + image in such a transparent div?
TIA
Javacript to show a curtain:
function CalculateAmountOnClick () {
var curtain = document.body.appendChild( document.createElement('div') );
curtain.id = "curtain";
curtain.onkeypress = curtain.onclick = function(){ return false; }
try {
// your operations
}
finally {
curtain.parentNode.removeChild( curtain );
}
}
Your CSS:
#curtain {
position: fixed;
_position: absolute;
z-index: 99;
left: 0;
top: 0;
width: 100%;
height: 100%;
_height: expression(document.body.offsetHeight + "px");
background: url(curtain.png);
_background: url(curtain.gif);
}
(Move MSIE 6 underscore hacks to conditionally included files as desired.)
You could set this up as add/remove functions for the curtain, or as a wrapper:
function modalProcess( callback ) {
var ret;
var curtain = document.body.appendChild( document.createElement('div') );
curtain.id = "curtain";
curtain.onkeypress = curtain.onclick = function(){ return false; }
try {
ret = callback();
}
finally {
curtain.parentNode.removeChild( curtain );
}
return ret;
}
Which you could then call like this:
var result = modalProcess(function(){
// your operations here
});
I'm going to make some heavy assumptions here, but it sounds to me what is happening is that because you are directly locking the browser up with intense processing immediately after having set up the curtain element, the browser never has a chance to draw the curtain.
The browser doesn't redraw every time you update the DOM. It may woit to see if you're doing something more, and then draw what is needed (browsers vary their method for this). So in this case it may be refreshing the display only after it has removed the curtain, or you have forced a redraw by scrolling.
A fair waring: This kind of intense processing isn't very nice of you because it not only locks up your page. Because browsers generally implement only a single Javascript thread for ALL tabs, your processing will lock up all open tabs (= the browser). Also, you run the risk of the execution timeout and browser simply stopping your script (this can be as low as 5 seconds).
Here is a way around that.
If you can break your processing up into smaller chunks you could run it with a timeout (to allow the browser breathing space). Something like this should work:
function processLoop( actionFunc, numTimes, doneFunc ) {
var i = 0;
var f = function () {
if (i < numTimes) {
actionFunc( i++ ); // closure on i
setTimeout( f, 10 )
}
else if (doneFunc) {
doneFunc();
}
};
f();
}
// add a curtain here
processLoop(function (i){
// loop code goes in here
console.log('number: ', i);
},
10, // how many times to run loop
function (){
// things that happen after the processing is done go here
console.log('done!');
// remove curtain here
});
This is essentially a while loop but each iteration of the loop is done in an timed interval so the browser has a bit of time to breathe in between. It will slow down the processing though, and any work done afterwards needs to go into a callback as the loop runs independently of whatwever may follow the call to processLoop.
Another variation on this is to set up the curtain, call your processing function with a setTimeout to allow the browser time to draw the curtain, and then remove it once you're done.
// add a curtain
var curtain = document.body.appendChild( document.createElement('div') );
curtain.id = "curtain";
curtain.onkeypress = curtain.onclick = function(){ return false; }
// delay running processing
setTimeout(function(){
try {
// here we go...
myHeavyProcessingFunction();
}
finally {
// remove the curtain
curtain.parentNode.removeChild( curtain );
}
}, 40);
If you are using a js-library, you may want to look at a ready made solution for creating curtains. These should exist for most libraries, here is one for jQuery, and they can help with the CSS.
I would do something like:
unhide a div (display:inline)
make the position:absolute
give it a z-index:99
make the height and width 100%
when the processing is done set display:none
To make it transparent you'll have to set the opacity which is different in Firefox, IE, etc.
To show a loading icon you can always create a second div and position it where you want to on the page. When it's done loading, remove it along with the transparent one.
In addition to all of the above, don't forget to put an invisible iframe behind the shim, so that it shows up above select boxes in IE.
Edit:
This site, although it provides a solution to a more complex problem, does cover creating a modal background.
http://www.codeproject.com/KB/aspnet/ModalDialogV2.aspx
For the loading message, I would use a <div> with position:absolute, position it using left and top, and set the display to none.
When you want to show the loading indicator, you're going to have to use a timeout otherwise the div won't display until your processing is done. So, you should modify your code to this:
function showLoadingIndicator()
{
// Display div by setting display to 'inline'
setTimeout(CalculateAmountOnClick,0);
}
function CalculateAmountOnClick()
{
// MY time consuming loop!
{
}
// Remove transparent div
}
Because you set the timeout, the page will redraw before the time-consuming loop happens.