I am trying to execute a window resize and page reload event simultaneously. When the screen size is less than 768 px, I am adding an attribute to an element. I also need that attribute added when the page is reload and a specific size as well, not just when its resized. The code I have below works, except when my screen size hs < 769 px, it takes a few seconds for the attribute to be added which affects how it looks. Any tips on how I can fix this?
window.onload = function(event) {
var element = document.querySelector('.filter-select');
if (window.innerWidth < 768) {
element.classList.add('testing');
element.removeAttribute("size", "4")
element.removeAttribute("multiple", "yes")
} else {
element.classList.remove('testing');
}
}
document.addEventListener("DOMContentLoaded", function(event) {
var element = document.querySelector('.filter-select');
function resize() {
if (window.innerWidth < 768) {
element.classList.add('testing');
element.removeAttribute("size", "4")
element.removeAttribute("multiple", "yes")
} else {
element.classList.remove('testing');
}
}
window.onresize = resize;
});
My only guess is that you doubled up the same process under different events and these events happen at different times thus the NOTICABLE lag.. if this doesn't solve.. this is an amazing question I already upvoted..
function resize() {
var element = document.querySelector('.filter-select')
if (window.innerWidth < 768) {
element.classList.add('testing')
element.removeAttribute("size", "4")
element.removeAttribute("multiple", "yes")
}
else {
element.classList.remove('testing');
}
}
window.onload=resize
Related
I want the following:
Detect page width on load and add/remove class if it's below/above 959px
If I resize the page I want to do the same
$(window).on("resize load", function(e) {
e = $("body").width();
if (e <= 959) {
$("#button").addClass("active")
}
if (e >= 960) {
$("#button").removeClass("active")
}
})
This code works, but it removes the active class even if I resize the window from 500px to 501px. I want that to only add the class if I go above 960px or remove it if I go below 959px. How can I do that?
EDIT
Thanks for the answers! In the meantime I figured out a solution that works and suit my needs.
$(window).one("load", function () {
r = $("body").width();
if (r >= 960) {
$("body").attr("mobile","0")
//do something
}
if (r <= 959) {
$("body").attr("mobile","1")
//do something
}
});
$(window).on("resize", function() {
r = $("body").width();
if ($("body").attr("mobile") == "0") {
if (r <= 959) {
//do something
$("body").attr("mobile","1")
}
}
if ($("body").attr("mobile") == "1") {
if (r >= 960) {
//do something
$("body").attr("mobile","0")
}
}
})
Explanation:
It's a very specific solution since I modify the tabindex values in mobile view and I don't want to change these values back to 0 on a simple resize, only in the case I switch from mobile view to desktop.
The width of the window is different than the width of the body. Using $('body').width() will account for the overflow, whereas using $(window).width() will give you the actual screen width.
$(window).on('load resize', function() {
$('#button').toggleClass('active', $(this).width() <= 959)
});
However, using media queries is much more straight forward if in fact, you are just adding CSS properties.
#button {
opacity: 0.5;
}
#media (max-width: 959px) {
#button {
opacity: 1;
}
}
You could ouse window.matchMedia for this. If you look at the perf test, matchMedia is a lot faster than resize.
var mq = window.matchMedia("(min-width:959px)");
// onload
setButton(mql);
// add listener for the query
mq.addListener(setButton);
function setButton(mq) {
if (mql.matches) {
// do something with your setButton
} else {
// no match....
}
}
Here you go with a solution https://jsfiddle.net/hLkv1xan/1/
$(window).on("resize load", function(e) {
e = $("body").width();
if (e <= 959) {
$("#button").addClass("active")
} else {
$("#button").removeClass("active")
}
});
.active{
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="button">
Submit
</button>
I just modified your code a bit, change in the condition.
Hope this will help you.
I am currently using the code:
// Resize when less than 768
$(document).ready(function(){
$(window).on('resize',function(){
if ($(window).width() < 768) {
location.reload(); // refresh page
}
else {
// Width greater than 768px for PC
}
});
});
But this reloads the page constantly when the browser is resized less than 768px. Is it possible to have a code that only reloads the page on resize when the browser is say, between 480px and 768px? Thanks!
Yes, of course:
// Resize when less than 768
$(document).ready(function(){
$(window).on('resize',function(){
if (($(window).width() > 480) && ($(window).width() < 768)) {
location.reload(); // refresh page
}
else {
// Width greater than 768px for PC
// Or width is smaller than 480 for mobile
}
});
});
I was trying to find a solution about this one, when I saw the accepted answer..
Please be carefull with your words mate:
But this reloads the page constantly when the browser is resized less
than 768px.
The keyword constantly is misleading, making others to believe that the problem is the constant refreshing of the page, and not the limitation of the conditional.
Anyway, for those poor fellows who thought the problem is the constant renewing, here is a working fiddle of my humble solution:
$(document).ready(function(){
//Set flag refresh to true
var refresh = true;
//If the window width is between wanted limit set flag to false. This is needed for the resize*.
if (($(window).width() > 480) && ($(window).width() < 768)) {
refresh = false;
}
$(window).resize( function(){
/* When resize hits limits check if flag is true, then refresh.
Flag is set to false from above*, after refresh.
Time is needed for the page to load and set the flag to false.
Otherwise flag is not updated and constant refresh keeps happening while resizing. */
if (($(window).width() > 480) && ($(window).width() < 768) ) {
if (refresh == true) location.reload();
} else {
refresh = true;
}
});
});
You could set a variable when the page first loads (in the ready() handler) that checks the initial size of the window. Then only use the resize event if necessary.
$(document).ready(function(){
var initialSize = $(window).width();
//don't resize on small sizes
if (initialSize < 768) { return; }
//otherwise continue
$(window).on('resize',function(){
if ($(window).width() < 768 && ) {
location.reload(); // refresh page
}
else {
// Width greater than 768px for PC
}
});
});
I am using plain JavaScript code to detect browser viewport and which is as follows:
function setLocation(url) {
if (window.location.href.indexOf(url) === -1)
window.location = url;
}
function reloadPage(width) {
if (width < 701) {
setLocation("layout700.php");
} else if (width < 900) {
setLocation("layout900.php");
} else {
setLocation("layout1200.php");
}
}
var done = false;
function ready() {
if(!done) {
done = true;
reloadPage(document.width);
}
}
if(window.addEventListener) {
window.addEventListener('DOMContentLoaded', ready, false);
window.addEventListener('load', ready, false);
} else if(window.attachEvent) {
window.attachEvent('onload', ready);
}
window.onresize = function() {
reloadPage(document.width);
};
My question is : How can I define width range in this?
What I mean is.... Is it correct if I use as
function reloadPage(width) {
if (width <= 701 && >= 480) {
setLocation("layout700.php");
} else if (width <= 900 && >= 701) {
setLocation("layout900.php");
} else {
setLocation("layout1200.php");
}
}
If this is not correct then what is the correct syntax? Kindly help.
function reloadPage(width) {
if( width >= 480 ) {
if (width <= 701 ) {
setLocation("layout700.php");
} else if ( width <= 900 ) {
setLocation("layout900.php");
} else {
setLocation("layout1200.php");
}
}
}
What is changed from your code ?
- After the logical operator " && " you did not mention the variable name, which is incorrect.
- You need not check for " width > 701 " in the second condition, because, if it was <= 701, the first condition would have been satisfied.
EDIT : Added a wrapper if() to check the page is greater than 480, since you don't have any layouts specific to that.
Start at the largest and move to the smallest. Also, because setLocation should immediate halt execution, you can optionally leave out the "else" stuff. Finally, I assume if width is less than 900, you should go to layout700, even if the width is less than 700? It seems like it would be the closest-fit for a very thin browser.
if (width>1200) {
setLocation("layout1200.php"); }
if (width>900) {
setLocation("layout900.php"); }
setLocation("layout700.php");
I'd be tempted to borrow this (http://adactio.com/journal/5429/) technique that Jeremy Keith has just blogged about and use the content attribute to store the correct page for the relevant dimensions - you could then use media queries to differentiate between the various sizes.
Something else you might want to consider... is using Device Atlas or
WUFRL to detect the end users browser and serve them out the correct layout to start - redirects are poor experience for end users and particularly slow over mobile.
I'm curious is there an event listener or perhaps a way to construct a method that will trigger when a CSS change happens?
My stylesheet uses media queries and I want to know if there's a way to attach a listener to see when those media queries kick in and out. For example I have a media query that hides a button at certain screen widths
#media screen and (max-width: 480px) {
#search-button {
display: none;
}
}
What event listener would I use to detect when that display changes? I'm currently doing this:
$(window).resize(function() {
if($('#search-button').css("display") == "none") {
//do something
} else {
//do something else
}
});
Which works fine, but it calls the listener every time the user changes the screen and I'd rather just have it fire only when the css of the button changes. I hope that makes sense.
for example this is what I'd like
$('#search-button').cssEventListenerOfSomeKind(function() {
alert('the display changed');
});
Binding to the window.resize is your best option (I believe). There isn't any event fired when you change an element's CSS. You can however optimize a bit by caching the selector used:
var $searcButton = $('#search-button');
$(window).resize(function() {
if($searcButton.css("display") == "none") {
//do something
} else {
//do something else
}
});
Or you can use $(window).width() to check the width of the viewport:
var $window = $(window);
$window.resize(function() {
if($window.width() <= 480) {
//do something
} else {
//do something else
}
});
UPDATE
You can always throttle your own event handler:
var $window = $(window),
resize_ok = true,
timer;
timer = setInterval(function () {
resize_ok = true;
}, 250);
$window.resize(function() {
if (resize_ok === true) {
resize_ok = false;
if($window.width() <= 480) {
//do something
} else {
//do something else
}
}
});
This will prevent the code in your resize event handler from running more than once every quarter second.
If it is only a one time event you could try to unbind the event.
http://api.jquery.com/unbind/
I know this is old but I managed to solve it with this logic
// set width and height of element that is controlled by the media query
var page_width = $page.width();
var page_height = $page.height();
$window = $(window).resize(function(){
if( $page.width() != page_width ) {
// update page_width and height so it only executes your
// function when a change occurs
page_width = $page.width();
page_height = $page.height();
// do something
// ...
}
});
I have this code working, but it seems clunky to me, is there a way to simplify? The gist of it is I'm checking the page width when the page loads and showing or hiding a div based on that (based on if the browser is wider or skinnier than 480 pixels). Then if the user resizes the browser window, I check the width again and show/hide the proper divs. Anyway this could be simplified with jquery or just js?
function pageWidth() {
return window.innerWidth != null? window.innerWidth: document.body != null? document.body.clientWidth:null;
}
//Show/hide the correct div when the page loads
if (pageWidth() >= 480) {
$(".siteSearchDropdown").css("display", "none");
$(".siteSearchSelect").css("display", "block");
}
if (pageWidth() < 480) {
$(".siteSearchDropdown").css("display", "block");
$(".siteSearchSelect").css("display", "none");
}
// Show/hide the correct dropdown when the browser window is resized
$(window).resize(function() {
if (pageWidth() >= 480) {
$(".siteSearchDropdown").css("display", "none");
$(".siteSearchSelect").css("display", "block");
}
if (pageWidth() < 480) {
$(".siteSearchDropdown").css("display", "block");
$(".siteSearchSelect").css("display", "none");
}
});
Rather than writing the code twice, write it once inside the window.resize event handler and then trigger a resize event on the window element:
$(window).resize(function() {
if (pageWidth() >= 480) {
$(".siteSearchDropdown").css("display", "none");
$(".siteSearchSelect").css("display", "block");
}
if (pageWidth() < 480) {
$(".siteSearchDropdown").css("display", "block");
$(".siteSearchSelect").css("display", "none");
}
}).trigger('resize');
Also, since this code will run many times when someone resizes their browser you should optimize your code by caching the selectors:
var $siteSearchDrioopdown = $(".siteSearchDropdown"),
$siteSearchSelect = $(".siteSearchSelect");
$(window).resize(function() {
if (pageWidth() >= 480) {
$siteSearchDrioopdown.css("display", "none");
$siteSearchSelect.css("display", "block");
}
if (pageWidth() < 480) {
$siteSearchDrioopdown.css("display", "block");
$siteSearchSelect.css("display", "none");
}
}).trigger('resize');
Note: I mentioned how resize event handler code is run many times when the browser is resized. To test this for yourself, just add this code to a page and watch your developer console fly:
$(window).resize(function (e) {
console.log(e);
});
After looking at the code again you can optimize further by using an if/else statement rather than running the pageWidth() function twice:
var $siteSearchDrioopdown = $(".siteSearchDropdown"),
$siteSearchSelect = $(".siteSearchSelect");
$(window).resize(function() {
if (pageWidth() >= 480) {
$siteSearchDrioopdown.css("display", "none");
$siteSearchSelect.css("display", "block");
} else {//notice the change in structure so the `pageWidth()` function is only called once
$siteSearchDrioopdown.css("display", "block");
$siteSearchSelect.css("display", "none");
}
}).trigger('resize');
If you can target CSS3 compatible browsers you should take a look at media queries. Alternatively there are javascript libraries such as Respond that provide the same functionality to older browsers.
Something like:
function pageWidth() {
return window.innerWidth || document.body.clientWidth;
}
function reconfig() {
if (pageWidth() >= 480) {
$(".siteSearchDropdown").hide();
$(".siteSearchSelect").show();
} else {
$(".siteSearchDropdown").show();
$(".siteSearchSelect").hide();
}
}
$(window).resize(reconfig);
reconfig();
You don't need function pageWidth(), just use $(window).width(). Also, you don't have to duplicate the code to show/hide the divs, create a function to do it.
function showHide() {
var isBigLayout = $(window).width() > 480;
$(".siteSearchDropdown").css("display", isBigLayout ? "none" : "block");
$(".siteSearchSelect").css("display", isBigLayout ? "block" : "none");
}
$(window).resize(showHide); //Run when resized
showHide(); // Run initially, or $(showHide) to run after DOM is loaded