I am adding a dynamically created image using JavaScript, but I need to remove this object when the viewport is 600px or wider.
Here is what I've tried:
var img = document.createElement('img');
// (imagine here all the others fields being defined).
img.style='My #media Rule here';
However, it did not work. Is it possible doing this by the way I am trying to do?
Just create CSS class and apply it when image is dynamically added:
JavaScript:
var img = document.createElement('img');
img.className = "imageClass";
img.src = "image/src/image.jpg";
And stylesheet:
#media screen and (min-width: 600px) {
.imageClass {
display: none;
}
}
Example: https://jsfiddle.net/cr29y1tc/1/
Related
I grab the size of a slide image using let size = carousel_images[0].clientWidth; and clientWidth varies in different viewports, here, carousel_images is pointing to img within the .carousel and here is how it varies in different viewports:
#media screen and (min-width: 1024px) {
.carousel {
max-width: 994px;
img {
min-width: 994px;
}
}
}
#media screen and (min-width: 1200px) {
.carousel {
max-width: 1150px;
img {
min-width: 1150px;
}
}
}
so when I resize the browser it looks like:
but as I refresh the page, it looks normal again.
here is full code pen link, Thank You.
You need to add this code:
window.addEventListener('resize', ()=>{
size = carousel_images[0].clientWidth
carousel_slide.style.transform = `translateX(${-size}px)`
})
Essentially, you need to listen window resize event, update variable and execute code again wherever that variable is used.
I think you have to assign a new value to your let size. Is it a global variable? Perhaps, putting it inside a function or class is a good idea.
You could use the resize event, which fires when your window changes size.
The following demo is from:
https://developer.mozilla.org/en-US/docs/Web/API/Window/resize_event
const heightOutput = document.querySelector('#height');
const widthOutput = document.querySelector('#width');
function reportWindowSize() {
heightOutput.textContent = window.innerHeight;
widthOutput.textContent = window.innerWidth;
}
window.onresize = reportWindowSize;
<p>Resize the browser window to fire the <code>resize</code> event.</p>
<p>Window height: <span id="height"></span></p>
<p>Window width: <span id="width"></span></p>
I've been searching for a lightweight, flexible, cross-browser solution for accessing CSS Media Queries in JavaScript, without the CSS breakpoints being repeated in the JavaScript code.
CSS-tricks posted a CSS3 animations-based solution, which seemed to nail it, however it recommends using Enquire.js instead.
Enquire.js seems to still require the Media Query sizes to be hardcoded in the script, e.g.
enquire.register("screen and (max-width:45em)", { // do stuff }
The Problem
All solutions so far for accessing Media Queries in Javascript seem to rely on the breakpoint being hardcoded in the script. How can a breakpoint be accessed in a way that allows it to be defined only in CSS, without relying on .on('resize')?
Attempted solution
I've made my own version that works in IE9+, using a hidden element that uses the :content property to add whatever I want when a Query fires (same starting point as ZeroSixThree's solution):
HTML
<body>
<p>Page content</p>
<span id="mobile-test"></span>
</body>
CSS
#mobile-test {
display:none;
content: 'mq-small';
}
#media screen only and (min-width: 25em) {
#mobile-test {
content: 'mq-medium';
}
}
#media screen only and (min-width: 40em) {
#mobile-test {
content: 'mq-large';
}
}
JavaScript using jQuery
// Allow resizing to be assessed only after a delay, to avoid constant firing on resize.
var resize;
window.onresize = function() {
clearTimeout(resize);
// Call 'onResize' function after a set delay
resize = setTimeout(detectMediaQuery, 100);
};
// Collect the value of the 'content' property as a string, stripping the quotation marks
function detectMediaQuery() {
return $('#mobile-test').css('content').replace(/"/g, '');
}
// Finally, use the function to detect the current media query, irrespective of it's breakpoint value
$(window).on('resize load', function() {
if (detectMediaQuery() === 'mq-small') {
// Do stuff for small screens etc
}
});
This way, the Media Query's breakpoint is handled entirely with CSS. No need to update the script if you change your breakpoints. How can this be done?
try this
const mq = window.matchMedia( "(min-width: 500px)" );
The matches property returns true or false depending on the query result, e.g.
if (mq.matches) {
// window width is at least 500px
} else {
// window width is less than 500px
}
You can also add an event listener which fires when a change is detected:
// media query event handler
if (matchMedia) {
const mq = window.matchMedia("(min-width: 500px)");
mq.addListener(WidthChange);
WidthChange(mq);
}
// media query change
function WidthChange(mq) {
if (mq.matches) {
// window width is at least 500px
} else {
// window width is less than 500px
}
}
See this post from expert David Walsh Device State Detection with CSS Media Queries and JavaScript:
CSS
.state-indicator {
position: absolute;
top: -999em;
left: -999em;
}
.state-indicator:before { content: 'desktop'; }
/* small desktop */
#media all and (max-width: 1200px) {
.state-indicator:before { content: 'small-desktop'; }
}
/* tablet */
#media all and (max-width: 1024px) {
.state-indicator:before { content: 'tablet'; }
}
/* mobile phone */
#media all and (max-width: 768px) {
.state-indicator:before { content: 'mobile'; }
}
JS
var state = window.getComputedStyle(
document.querySelector('.state-indicator'), ':before'
).getPropertyValue('content')
Also, this is a clever solution from the javascript guru Nicholas C. Zakas:
// Test a media query.
// Example: if (isMedia("screen and (max-width:800px)"){}
// Copyright 2011 Nicholas C. Zakas. All rights reserved.
// Licensed under BSD License.
var isMedia = (function () {
var div;
return function (query) {
//if the <div> doesn't exist, create it and make sure it's hidden
if (!div) {
div = document.createElement("div");
div.id = "ncz1";
div.style.cssText = "position:absolute;top:-1000px";
document.body.insertBefore(div, document.body.firstChild);
}
div.innerHTML = "_<style media=\"" + query + "\"> #ncz1 { width: 1px; }</style>";
div.removeChild(div.firstChild);
return div.offsetWidth == 1;
};
})();
I managed to get the breakpoint values by creating width rules for invisible elements.
HTML:
<div class="secret-media-breakpoints">
<span class="xs"></span>
<span class="tiny"></span>
<span class="sm"></span>
<span class="md"></span>
<span class="lg"></span>
<span class="xl"></span>
</div>
CSS:
$grid-breakpoints: (
xs: 0,
tiny: 366px,
sm: 576px,
md: 768px,
lg: 992px,
xl: 1200px
);
.secret-media-breakpoints {
display: none;
#each $break, $value in $grid-breakpoints {
.#{$break} {
width: $value;
}
}
}
JavaScript:
app.breakpoints = {};
$('.secret-media-breakpoints').children().each((index, item) => {
app.breakpoints[item.className] = $(item).css('width');
});
I found an hackish but easy solution :
#media (min-width: 800px) {
.myClass{
transition-property: customNS-myProp;
}
this css property is just a markup to be able to know in JS if the breaking point was reached. According to the specs, transition-property can contain anything and is supported by IE (see https://developer.mozilla.org/en-US/docs/Web/CSS/transition-property and https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident).
Then just check in js if transition-property has the value. For instance with JQuery in TS :
const elements: JQuery= $( ".myClass" );
$.each( elements, function (index, element) {
const $element = $( element );
const transition = $element.css( "transition-property" );
if (transition == "custNS-myProp") {
// handling ...
}
});
Of course there is a word of warning in the wiki that the domain of css property identifiers is evolving but I guess if you prefix the value (for instance here with customNS), you can avoid clashes for good.
In the future, when IE supports them, use custom properties instead of transition-property
https://developer.mozilla.org/en-US/docs/Web/CSS/--*.
I am trying to detect the clients device dimensions using a mixture between CSS and Javascript. [From this tutorial] I created an element that I appended to the body and assigned it a class that holds a value called "z-index" that determines the device type. However when running the following code I get "undefined" as the response.
How can I get a numeric value instead of undefined?
$(document).ready(function() {
var indicator = document.createElement('div');
indicator.className = 'state-indicator';
document.getElementsByTagName('body')[0].appendChild(indicator);
function getDeviceState() {
var index = parseInt(window.getComputedStyle(indicator).getPropertyValue('z-index'), 10);
var states = {
0: 'desktop',
1: 'small-desktop',
2: 'large-tablet',
3: 'medium-tablet',
4: 'phone'
};
return states[index];
}
console.log(getDeviceState());
});
/*default */
.state-indicator {
z-index: 0;
}
#media all and (max-width: 1200px) {
/* start of small desktop */
.state-indicator {
z-index: 1;
}
}
/* end of desktop styles */
#media screen and (max-width: 991px) {
/* start of large tablet styles */
.state-indicator {
z-index: 2;
}
}
#media screen and (max-width: 767px) {
/* start of medium tablet styles */
.state-indicator {
z-index: 3;
}
}
#media screen and (max-width: 479px) {
/* start of phone styles */
.state-indicator {
z-index: 4;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
z-index only works on positioned elements, if you check what the actual value is it is auto and states[parseInt('auto')] is undefined
Css adjustment that fixes immediate issue:
.state-indicator {
z-index: 0;
position:relative;
}
Since you are using jQuery here's a slightly simpler version that also removes the element once the needed value is obtained
$(function() {
function getDeviceState() {
var $indicator = $('<div>', {'class': 'state-indicator'});
$('body').append($indicator);
var index = $indicator.css('z-index');
// got the value, so remove the test element
$indicator.remove();
// technically js property names can not be numeric, and will get cast to string but not all browsers will
var states = {
'0': 'desktop',
'1': 'small-desktop',
'2': 'large-tablet',
'3': 'medium-tablet',
'4': 'phone'
};
return states[index];
}
console.log(getDeviceState());
});
DEMO
The problem is z-indexwhich is auto can not be parsed to a number. The resolution of this code is to find NaN property of states object and the right answer is undefined.
So, right question is why does window.getComputedStyle(indicator).getPropertyValue('z-index') returns auto and how to make it works.
The main problem is to find right media-query resolution from whithin JS.
There is a lot of good example how to combine JS and media query work. Try this one:
http://theme.co/blog/cubit-a-more-flexible-media-query/
http://thenewcode.com/948/Triggering-JavaScript-Actions-With-CSS-Media-Queries
You can improve this code with ideas inside links I gave you.
On my template, I have 2 divs. one for table view(laptop) and one for list view(mobile view).
In my .ts file, I want to get the window size so that based on this size, I can choose which div i want to call using ngIf.
In the constructor of the .ts file, I have:
let windowSize: number;
this.windowSize = innerWidth + innerHeight;
window.addEventListener("resize", function() {
this.windowSize = innerWidth + innerHeight";
});
But when i console.log() this.windowSize, I dont get the change when the window is resized. What am i missing?
This can be set with simple css:
#media (min-width: 500px) and (max-width: 700px) {
.div1 {
display: none;
}
#media (min-width: 701px) and (max-width: 900px) {
.div2 {
display: none;
}
Resolved this issue by using NgZone. Injected NgZone in my constructor and used it as:
window.onresize = (e) =>
{
this.ngZone.run(() => {
this.width = window.innerWidth;
this.height = window.innerHeight;
});
};
By doing this, I was able to check for the change in window in my components. I couldnt use media queries since I had to execute a funtion inside my .ts file based on window size change.
How can I resize of a image base on screen size. Example:
I have a tag (width:1349, height: 449) and a image in div (width:78, height:78). When display image in div I fix for width of image is 60 and height is 60. I saw in mobile screen then the size of image still keep state so now I want to image display automatic resize base on screen example: in iPhone 4 the image have size (20x20) or percent of it in the screen. How can I use the formular for calculate it? This is my code jquery for calculate it.
var mw = $("#c").width();
var mh = $("#c").height();
console.log();
var img = new Image();
img.src = './img/photo-circle.png';
var wdImg = img.width;
var hiImg = img.height;
var ratioImg = wdImg/hiImg;
var ratioDiv = mw/mh;
if (ratioDiv > 1) {
var newwd = wdImg*(mh/hiImg);
alert(newwd);
} ;
You should be using percentages to achieve dynamic resizing of your elements. Then, as long as the parents are also dynamically resizing, their children will as well. For example, width: 30%; instead of width: 100px;
use the css unit vh and vw
each unit is worth 1% of the screen size
http://caniuse.com/#feat=viewport-units
example:
.item {
height: 20vw;
width: 20vw;
}
If the screen width is 100pixels, .item would be 20px by 20px
Simply you can use a bootstrap class called "img-responsive" at your img tag .
That's all , It will be responsive on any screen.