I came upon a script for resizing images dynamically for fitting a specific width here. I modified it for my own web app and it works great part of the time, but for some reason the function will sometimes randomly not trigger the if statement when the image does indeed have a larger width then I’m desiring so the image never resizes. I put in a set timeout hoping that the timeout would give the browser time to read the image. But no luck any ideas as to why it would not trigger?
Side note: this is for a mobile web app, is there something with HTML5 that I could use?
var maxWidth = 200;
var imgWidth = $('#locImg').width();
console.log(imgWidth);
setTimeout(function () {
if( imgWidth > maxWidth) {
newWidth = maxWidth;
var newHeight = $('#locImg').height() / ( $('#locImg').width() / maxWidth);
$('#locImg').height(newHeight).width(newWidth);
console.log($('#locImg').width());
$('#loc').css('visibility','visible');
}
else {
$('#loc').css('visibility','visible');
}
},750);
You could use something like this to ensure the image is fully loaded:
var maxWidth = 200;
var imgWidth = $('#locImg').width();
var image = new Image();
image.src = $('#locImg').attr("src");
image.onload = (function () {
if( imgWidth > maxWidth) {
newWidth = maxWidth;
var newHeight = $('#locImg').height() / ( $('#locImg').width() / maxWidth);
$('#locImg').height(newHeight).width(newWidth);
console.log($('#locImg').width());
$('#loc').css('visibility','visible');
}
else {
$('#loc').css('visibility','visible');
}
});
this way it only starts the resize after the image has fully loaded.
Related
I ve given up finding a crossbrowser image solution which makes me happy.
I now want to make it the "mobile first" way of the cost of bandwith for destkops.
The plan: Ship mobile sized images to all clients.
Then i am able to get the viewport size of the browser which works fine.
My CSS is switching as the follows: <= 1000 px mobile view >=1001 desktop view.
But then: I thought i would save images in the same paths with different file extensions. Lets say i would save them as the follows
/img/myimage-mobile.jpg
/img/myimage-normal.jpg
/img/myimage-highres.jpg
initial load would look like
<img src="img/myimage-mobile.jpg" alt="#" />
Now my question: How can i get all img tags and change the extension of the src attribute? When detecting a viewport width >=1001 i want to replace all "-mobile.jpg" with "-normal.jpg" and larger ~1400 with "myimage-highres.jpg".
Thats what i got so far:
var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0)
var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0)
getting the viewport size and then i found this which is getting the entire src attribute:
var images = document.getElementsByTagName('img');
var srcList = [];
for(var i = 0; i < images.length; i++)
{
srcList.push(images[i].src);
srcList.push(images[i].src);
}
I don't think this is the best method but it does change the image paths but this will also work on window resize. If other developers want to edit this to clean it up or improve something then feel free to do so.
Would it not be better to detect the users device rather than using the browser height/width?
var defaultimg="normal";
function _Imgs(){
var imgsize;
var Pw=document.documentElement.clientWidth;
var Ph=document.documentElement.clientHeight;
if(Pw<800||Ph<300){ // Change this to Set width for mobiles
imgsize="mobile";
}else{
imgsize="normal";
}
var MyImgs=document.getElementsByTagName("IMG");
for(var i=0; i<MyImgs.length; i++) {
MyImgs[i].setAttribute("src",MyImgs[i].src.replace(defaultimg, imgsize));
}
//Change variable value to allow toggle on window resize
defaultimg=imgsize;
}
window.onload=_Imgs;
window.onresize=_Imgs;
With Jquery you can do it like this
$('img').each(function(){
var fix = $(this).attr('src').replace('mobile', 'normal');
$(this).attr('src', fix);
})
To detect the viewport size you can do this:
var height = window.innerHeight;
var width = window.innerWidth;
Then just make a function wrapping it all together:
window.onload = function(){
var height = window.innerHeight;
var width = window.innerWidth;
if(height < 1000 && width < 400){
$('img').each(function(){
var fix = $(this).attr('src').replace('mobile', 'normal');
$(this).attr('src', fix);
})
}
}
or with pure javascript:
window.onload = function(){
var height = window.innerHeight;
var width = window.innerWidth;
if(height < 1000 && width < 400){
var imgs = document.getElementsByTagName('img');
for(i=0;i<imgs.length;i++){
var fix = imgs[i].src.replace('mobile', 'normal');
imgs.src = fix;
}
}
}
I am wondering how I can use Javascript to get a windows size and then set (really clear) an HTML ID with it.
I am currently working on a site that has a "default" navigation ID of "access" which I want to blank out if the windows size is less than 800 px wide.
This is the page I am working on and if the ID is cleared I can then setup the mobile navigation to work with bootstrap.
`window.onload = function() {
var w = window.innerWidth;
if(w < 800) {
document.getElementById('access').removeAttribute('id');
}
}
window.onload = function() {
var w = window.innerWidth;
if(w < 800) {
document.getElementById('access').removeAttribute('id');
}
}
window.onresize = function() {
var w = window.innerWidth;
if(w < 800) {
document.getElementById('access').removeAttribute('id');
}
}
Use
var w = window.innerWidth;
to get the width of the page.
and then,
window.onload = function() {
if(w < 800) {
document.getElementById('access').removeAttribute('id');
}
}
You probably want to add this functionality in resize too.
EDIT: put the code in window.onload
Based on the comment,
window.onload = function() {
var accessElem = document.getElementById('access');
var updateAccess = function() {
var w = window.innerWidth;
if(w < 800) {
accessElem.removeAttribute('id');
}
else {
accessElem.setAttribute('id', 'access');
}
};
window.onresize = updateAccess; // call updateAccess on resize
updateAccess(); // call once on load to set it.
};
Also, in my opinion, adding/removing id is not a great idea.
I have a fullscreen slideshow page, but the slides don't take up 100% of the background. Instead, they base size off of the browser. I want the slides to take 100% of the background. I THINK I narrowed it down to one function, but I'm not sure and not good with JavaScript yet. Here's the function:
// calculate image size, top and left position
jQuery.fn.superbgCalcSize = function(imgw, imgh) {
var options = $.extend($.fn.superbgimage.defaults, $.fn.superbgimage.options);
// get browser dimensions
var browserwidth = $(window).width();
var browserheight = $(window).height();
// use container dimensions when inlinemode is on
if (options.inlineMode === 1) {
browserwidth = $('#' + options.id).width();
browserheight = $('#' + options.id).height();
}
// calculate ratio
var ratio = imgh / imgw;
// calculate new size
var newheight = 0; var newwidth = 0;
if ((browserheight / browserwidth) > ratio) {
newheight = browserheight;
newwidth = Math.round(browserheight / ratio);
} else {
newheight = Math.round(browserwidth * ratio);
newwidth = browserwidth;
}
// calculate new left and top position
var newleft = Math.round((browserwidth - newwidth) / 2);
var newtop = Math.round((browserheight - newheight) / 2);
var rcarr = [newwidth, newheight, newleft, newtop];
return rcarr;
};
Let me know if there needs to be more code or even to link to the entire document, as I said I'm not at all experienced with JS and don't know where the problem resides.
*I've tried doing it with CSS, but I get a bug where as it's transitioning to the next image it bleeps the first image's actual size just before displaying the next and it's rather unsleek. Fixing this would also solve my question.
I have multiple sections showing different backgrounds, each section has a basic parallax background image. As the backgrounds vary in height, I cannot seem to work out how to stop the background image position once the image bottom is reached.
Background position change begins if the section offset().top is equal to or greater than $(window).scrollTop().
It would seem that the btmOffset is incorrect but I can't see why.
Any help greatly appreciated.
Live example
http://demo.dwweb.co.uk
What I have so far
$window = $(window);
var winWid = $window.width();
$('.portfolioSection').each(function(){
var $bgobj = $(this);
var speed = 2.4;
var bg = $(this).css('background-image').replace('url("','').replace('")','');
var tmpImg = new Image();
tmpImg.src = bg;
var orgW = tmpImg.width;
var orgH = tmpImg.height;
var imgResizedRatio = winWid/orgW;
var resizedH = orgH * imgResizedRatio;
var btmOffset = (resizedH - $(this).height()) + $bgobj.offset().top;
$(window).scroll(function() {
if($(window).scrollTop() > $bgobj.offset().top && $(window).scrollTop() < btmOffset){
var yPos = -(($window.scrollTop()-$bgobj.offset().top) / speed);
var coords = '0 '+ yPos + 'px';
$bgobj.css({ backgroundPosition: coords });
} else if($(window).scrollTop() < $bgobj.offset().top) {
$bgobj.css({ backgroundPosition: '0 0' });
} else {
$bgobj.css({ backgroundPosition: '0 '+resizedH+'px' });
}
});
});
orgH and orgW will be 0 on execution, since you are creating a new Image asynchronously, while executing your code synchronously:
var tmpImg = new Image();
tmpImg.src = bg;
//...
This means, you would have to use the onload event (and maybe cover the onerror event too), like this:
tmpImg.onload = function(ev) {
var orgW = tmpImg.width;
var orgH = tmpImg.height;
//and the rest of your code...
}
This is very inefficient, since you are loading all these (big) images again.
I would add data-attributes to each .portfolioSection, like data-bgmaxscroll="1000" (which is the height of the image).
This would be a bit more hardcoded, but i think it's the easiest and the most performant way.
im trying to get some images to resize automatically when a window resizes.
I have this working with the code below, however I would like to have a little more control over the image such as being able to set a min-height, any ideas??
also maybe wrap the images in a div so there is a little more control? Im not to good with js so any help or explanations would help
$(function() {
var $img = $(".l");
var ratio;
var offsetX = $img.offset().left;
var offsetY = $img.offset().top;
$(window).load(function () {
ratio = $img.width() / $img.height();
$(this).resize();
});
$(window).resize(function () {
var viewportWidth = window.innerWidth || document.documentElement.clientWidth;
var viewportHeight = window.innerHeight || document.documentElement.clientHeight;
var availWidth = viewportWidth - offsetX - 70;
var availHeight = viewportHeight - offsetY - 70;
if (availWidth / availHeight > ratio) {
$img.height(availHeight);
$img.width(availHeight * ratio);
}
else {
$img.width(availWidth);
$img.height(availWidth / ratio);
}
});
});
Just use CSS:
img { width: 100%; }
You can then apply height or min-height as you need.
To see it working, resize the window of this fiddle:
Example fiddle