I want to check the size of the screen and toggle a class depending on the size of the screen.
Html
<div id="item" class="test"></div>
Script
window.addEventListener("load", toggleClass);
window.addEventListener("resize", toggleClass);
function toggleClass() {
var w = window.innerWidth;
item = document.getElementById("item");
if ( w > 700 ) {
item.classList.remove("test");
}else {
if ( item.classList.contains("test")) {
}else {
item.classList.add("test");
}
}
}
You don't need to test for whether test is included in the classList first - you can just add it unconditionally. Also, avoid implicitly creating global variables - always declare a new variable name with var (or, preferably, const, or let):
function toggleClass() {
var w = window.innerWidth;
var item = document.getElementById("item");
if ( w > 700 ) {
item.classList.remove("test");
}else {
item.classList.add("test");
}
}
You can also use the Conditional (ternary) operator
function toggleClass() {
var item = document.getElementById("item");
(window.innerWidth > 700) ? item.classList.remove("test") : item.classList.add("test");
}
A different approach - rather than adding a class on the smaller size - use a media query to apply the styling that you want - obviously if you are using the class for a purpose other than styling - this approach may not work - but if all you are doing is styling an element based on the width of the screen - then a media query is your friend.
The benefit of this approach (if its purely styling changes you are doing) is that there is no js required - the browser will automatically use whatever styling the media query matches. This is better for performance because the re is no js to run.
#media screen and (max-width: 699px) {
p {
font-size: 14px
}
}
#media screen and (min-width: 700px) {
p {
font-size: 16px
}
}
Related
I have this function that moves a HTML element around the DOM based on whether the window size is less than 640px or more. I'm moving the image with prepend and append, but because the function fires every time the window is resized I think I'm asking for performance issues.
The code:
function moveDealsImage() {
var mobile_width = 640;
var wi = $(window).width();
if (wi < mobile_width) {
$( ".deals-header" ).prepend( $("div.htp") );
} else {
$( ".deals-header" ).append( $("div.htp") );
}
}
window.addEventListener("resize", moveDealsImage);
moveDealsImage();
I need to keep the listener in there.
Is there a way to do that, but then only prepending/appending the element once each time that the if or else statements become true? (instead of it happening on every pixel change)
There are a few things that you can do to optimize this.
A first option is to only execute your moveDealsImage function when the state changes from mobile to desktop or reverse. All the other resizes can just be ignored.
This can be accomplished by using something like following code:
var mobile_width = 640;
var is_mobile = (window.innerWidth <= mobile_width);
function moveDealsImage(e) {
// Only execute the function when then state changes from mobile to desktop or reverse
if(
! is_mobile && window.innerWidth > mobile_width ||
is_mobile && window.innerWidth <= mobile_width
)
return;
// Update state
is_mobile = (window.innerWidth <= mobile_width);
console.log('your code here');
}
window.addEventListener("resize", moveDealsImage);
moveDealsImage();
Another and better solution would be to use CSS media queries. This can be done with the following CSS and HTML.
.desktop-deals-header {
display: block;
}
.mobile-deals-header {
display: none;
}
#media only screen
and (max-width : 640px) {
.desktop-deals-header {
display: none;
}
.mobile-deals-header {
display: block
}
}
and in your HTML you add two headers, one for desktop and one for mobile.
<div class="mobile-deals-header">Mobile header</div>
<div class="desktop-deals-header">Desktop header</div>
I'll try to explain my use case here. In my site I have a break point for desktop view, and break point for tablet view (which is more compact). I'm trying to add a function to allow seeing the tablet view when browsing from desktop, cause some members prefer the compact design in their desktop as well.
For doing that, I figured I would need to trick the '#media(max-width:X)' query. I'm looking for a JS code that can manipulate the screen width value, so when the browser calculates max-width, it would be against a value that I specified.
One thing to note, this is suppose to work on desktop browsers, so the meta viewport can't be used here.
One solution is to apply a specific class (e.g: .tablet) to the body.
<body class="tablet"></body>
In your CSS:
#media screen and (/* your query */) {
.tablet .my-class {
/* tablet specific stuff */
}
}
You could then remove the .tablet class and replace it with .desktop via JavaScript
var body = document.body;
var switchToDesktop = function() {
body.className = body.className.replace('tablet', 'desktop');
}
var switchToTablet = function() {
body.className = body.className.replace('desktop', 'tablet');
}
var toggleView = function() {
(body.className.indexOf("tablet") > -1) ?
switchToDesktop() :
switchToTablet();
}
If you are using SASS or LESS, you can nest the tablet-specific styles.
#media screen and (/* your query */) {
.tablet {
h1 {
/* tablet specific h1 */
}
.my-div {
color: red;
}
/* etc... */
}
}
I'm having a trouble debugging a site that's not acting very responsively. I have media queries like so:
#media (min-width: 768px) and (max-width: 992px)
{
.radio-page {
height: 1470px;
}
}
#media (min-width: 993px) and (max-width: 1199px)
{
.radio-page {
height: 1525px;
}
}
(There are a few more breaks at larger screen dimensions but I don't think they are relevant)
I haven't specified a height for this class at dimensions less than 768, instead opting for the following javascript/jquery:
function confirmer() {
if ($(window).innerWidth() < 767) {
var inHeight = $('.iright-4 p').offset().top +
$('.iright-4 p').height() - $('.inner-radio').offset().top;
var outHeight = inHeight + $('.inner-radio').offset().top - 42;
$('.inner-radio').css('height', inHeight + 20);
$('.radio-page').css('height', outHeight + 50);
}
// debug code to report element height
console.log('radio-page is ' + $('.radio-page').css('height'));
}
$(document).ready(function() {
confirmer();
$(window).resize(confirmer);
});
All is well when it loads. The problem occurs specifically when the window is resized from below 767px into something higher. For some reason the media queries no longer change the height value of the .radio-page element, despite the javascript changed being isolated to < 767px. .radio-page stays at exactly whatever height it was when the resize passed the threshold.
Also, I have a suspicion that the confirmer function is being disabled altogether when the window is > 767px, because I'm losing console updates. All is well when I re re-size to < 767px (the jquery operates as intended).
Any help is most appreciated,
SOLUTION
function confirmer() {
if ($(window).innerWidth() < 767) {
...
} else {
$('.inner-radio').css('height', '');
$('.radio-page').css('height', '');
}
...
When the javascript code sets your elements to have a specific height at < 767px, it is changing the style attribute of those elements. When you resize to 767 px or above, your CSS is trying to take over for the javascript, but that style attribute defining the height is still there. One possible solution is to clear it in your code:
function confirmer() {
if ($(window).innerWidth() < 767) {
var inHeight = $('.iright-4 p').offset().top +
$('.iright-4 p').height() - $('.inner-radio').offset().top;
var outHeight = inHeight + $('.inner-radio').offset().top - 42;
$('.inner-radio').css('height', inHeight + 20);
$('.radio-page').css('height', outHeight + 50);
}else{
$('.inner-radio').css('height', '');
$('.radio-page').css('height', '');
}
// debug code to report element height
console.log('radio-page is ' + $('.radio-page').css('height'));
}
$(document).ready(function() {
confirmer();
$(window).resize(confirmer);
});
As per the jQuery docs on $.css():
Setting the value of a style property to an empty string — e.g. $(
"#mydiv" ).css( "color", "" ) — removes that property from an element
if it has already been directly applied, whether in the HTML style
attribute, through jQuery's .css() method, or through direct DOM
manipulation of the style property. It does not, however, remove a
style that has been applied with a CSS rule in a stylesheet or
element.
In regards to losing console updates, I cannot answer that part of the question. Perhaps you are getting updates, but because the height value is the same, your browser recognizes them as identical messages and collapses them into one? Check if there is a small number next to your message. Here's an example from Chrome:
Another Newbie Question:
I am attempting to completely remove a class from the DOM when the screen.width is smaller than or equal to 320 px.
Attempting this without specifying a screen width works just fine. The class is removed from the page, but when I attempt to specify the conditional screen width it does not.
Can anyone help me out here?
This is what I have:
<div class="poison">Poison Text</div>
<script>
var p = document.getElementsByClassName('poison');
var cstr = "poison";
var poison = screen.width;
if (poison <= 320) {
(var i = p.length; --i >= 0;) {
var n = p[i];
while (n.className.split(" ").indexOf(cstr) == -1) {
n = n.parentNode;
}
n.parentNode.removeChild(n);
}
}
</script>
You should use media queries instead of JS for this. Add this line to your stylesheet
#media (min-width:320px){
}
and put the class/classes you wish to use at sizes above 320px inside.
You can use max-width and multiple conditions as well.
I'm using the following two pieces of CSS and JS code:
#media (max-width: 720px) {
// a code to make arrows in a carousel disappear
}
if(jQuery(window).width() <= 720){
// a code to make arrows in the carousel stop working
}
The problem with them is that the latter executes on exactly width=738px and not 720px. I suspect that this is because of browser's vertical scrollbar that has width equal to 18px in Chrome.
Is there a way to unify this? I'd like these actions to happen at the same moment in all browsers regardless of the scrollbar's width.
Tests (when browser is # 720px and CSS has already executed):
jQuery(document).innerWidth() = 703
jQuery(window).innerWidth() = 703
jQuery(document).width() = 703
jQuery(window).width() = 703
jQuery('body').width() = 703
jQuery('html').width() = 703
I had to tackle the same problem a while ago, and so far the most correct solution I found is to use media queries to pass the actual window size to Javascript. You have to follow these steps:
Add a hidden element to your page,
Use media queries to alter the max-width property of that element,
Read back the max-width property of that element through Javascript.
For instance, add the following element to your page:
<div id="currentMedia"></div>
Then write the following CSS rules:
#currentMedia {
display: none;
}
#media (max-width: 720px) {
/* Make arrows in the carousel disappear... */
#currentMedia {
max-width: 720px;
}
}
Then, from the Javascript side, you can write:
if (parseInt(jQuery("#currentMedia").css("max-width"), 10) <= 720) {
// Make arrows in the carousel stop working...
}
And it will be accurate regardless of the scrollbar size, since the value comes from the same media query that triggers the carousel's disappearance.
I tested this solution on all major recent browsers, and it gives correct results.
You will find the big summary of what properties are supported on what browsers on this page on quirksmode.org.
Your best bet is probably to grab an element in the page (using document.body where supported, or document.getElementById or whatever), walk its offsetParent chain to find the topmost element, then examine that element's clientWidth and clientHeight.
innerWidth documentation
innerWidth() says this method is not applicable to window and document objects; for these, use .width()
try
How can I get the browser's scrollbar sizes?
From Alexandre Gomes Blog
function getScrollBarWidth () {
var inner = document.createElement('p');
inner.style.width = "100%";
inner.style.height = "200px";
var outer = document.createElement('div');
outer.style.position = "absolute";
outer.style.top = "0px";
outer.style.left = "0px";
outer.style.visibility = "hidden";
outer.style.width = "200px";
outer.style.height = "150px";
outer.style.overflow = "hidden";
outer.appendChild (inner);
document.body.appendChild (outer);
var w1 = inner.offsetWidth;
outer.style.overflow = 'scroll';
var w2 = inner.offsetWidth;
if (w1 == w2) w2 = outer.clientWidth;
document.body.removeChild (outer);
return (w1 - w2);
};
in your code
if(jQuery(window).width()-getScrollBarWidth(); <= 720){
// a code to make arrows in the carousel stop working
}
A bit outdated thread, but i've found this solution
function getWidth(){
return ((window.innerWidth > 0) ? window.innerWidth : screen.width);
}
If you are using Bootstrap > 3 then I will suggest you something.
Bootstrap ships with .container class in its Css and predefined. And its altering with #media queries.So my working code sample for this is below.
function detectWidth(){
var width = $('.container').eq(0).outerWidth() ;
console.log(width);
if(width<750){
// do something for XS element
}else if(width>=750 && width<970){
// do something for SM element
}else if(width>=970 && width<1170){
// do something for MD element
}else{
// do something for LG element
}
}
I realize this is an old thread, but I think it can still benefit from this answer.
var width = window.outerWidth;
This will give you the width of the window including scrollbars, which is what media queries use, I believe.