jquery remove images from page before they get loaded - javascript

My problem is simmilar to this but I can't do it server side, since I only want to remove the images if the browser width is less than 850px.
I am currently using this:
$(function () {
if($(document).width() < 850) {
$('.thumb').remove();
}
});
The images get removed, but as you can see here, the browser loads them anyway.
Do anyone have a solution for this?
Thanks
Solution (it works now!:
Instead of always loading the images, never load them, unless the browser is greater than 850
HTML:
<?php
if(file_exists($sites[$i].'/thumb.png')) { ?>
<img class="thumb" data="/experiments/<?=$sites[$i]?>/thumb.png" />
<?php
}
?>
JS:
$('.thumb').each(function(index, element) {
$(this).attr('src', $(this).attr('data'));
});

I think you have to turn it the other way around: Meaning that you'll only load images if the doc. width is wider then 850. As far as I know the images will be requested / loaded before the script runs if they're "hard coded" in the HTML document.

Of course.
Remove() first loads them, then removes them from the DOM.
The only way to remove them so that the browser never loads them is with a server-side language. In the server side language, you could detect if the picture is on the page and if it is, you could remove them. And therefore the image is never sent to the browser.
As for your case, "if($(document).width() < 850)" is used, so you can't do all of it server side.
Why don't you just interchange between server-side and browser-side? Like PHP and JavaScript?
For example, you could, with JavaScript detect if the document width is less then 850. If it is, it loads an iframe with the parameter (remove=true). The iframe page would have all the .thumb and images and all the content, and you could use PHP on the page to detect if the "remove=true" parameter was present (use $_GET[remove]). If it was, it would not display the .thumb and never send it to the browser.

KG Christensen's and your idea of setting the image's src attribute is good.
Another idea which could work is to have the images with a display: none; style, and change it to display: inline; only if your condition is met. The browsers shouldn't load the images if they're hidden.
Something along the lines of:
<style type="text/css">
.thumb {
display: none;
}
</style>
<script type="text/javascript">
$(document).ready(function() {
if ($(document).width() >= 850)
$('.thumb').show();
});
</script>

Related

How to prevent images from reloading when leaving "display: none"

I am writing an Ember.js web-application, designed to be the user interface of an automation system, that polls data from the LAN server every two seconds in order to have on display always the "live" process data.
This application is accessible from a wirless hotspot, to allow registered users to browse it, so potentially any device (tablets, smartphones, laptops...) could be the actual client.
On some pages, there are icons that change according to some conditions, and to implement this effect I declared several img tags, and I make the ones I dont need invisible by styling it with CSS display: none.
In HTML:
<img class="icon-active" src="/images/icon1.jpg" />
<img class="icon-inactive" src="/images/icon2.jpg" />
In Javascript, every two seconds:
var visibleElement = null;
var invisibleElement = null;
if( this.get("whatever").active == true )
{
visibleElement = this.element.getElementsByClassName("icon-active")[0];
invisibleElement = this.element.getElementsByClassName("icon-inactive")[0];
}
else
{
visibleElement = this.element.getElementsByClassName("icon-inactive")[0];
invisibleElement = this.element.getElementsByClassName("icon-active")[0];
}
visibleElement.style.display = null;
invisibleElement.style.display = "none";
Everything works fine, on laptops and tablets, but on some smarthphones, the images are loaded every time I set visibleElement.style.display = null;, it means, every two seconds, the visible icon is GETted again and again from server.
I dont want it to happen at first to reduce data traffic, that is not a problem at all, but I don't like fetching resources even if not required, second, the image reload generates an annoying flicker effect, that is really unlookable.
How can I force every client to cache images as tablets and laptops do?
----- more info -----
Thanks everyone for your support! Here you have some news:
I tried as suggested to comment-out all the javascript code that works on style.display and modify the HTML (template) as follows:
{{#if whatever.active}}
<img class="icon-active" src="/images/icon1.jpg" />
{{else}}
<img class="icon-inactive" src="/images/icon2.jpg" />
{{/if}}
and I got the same result. So I tried to roll back the HTML and leave the javascript commented, in such way I should have always all the icons visible, and surprise... they are all flickering and being requested every two seconds...
I guess the issue is due to the fact that some (maybe not up-to-date?) smartphone browsers are redrawing completely the images as the ember-views bound data gets updated. I will investigate more on which browser/version has this problem and make sure all of the testing devices use the last version of their browsers - since ember uses the latest javascript features, better cut-out old fashioned clients.
The code used to refresh data every two seconds follows, please notify if you see anything uncommon:
import Ember from 'ember';
export default Ember.Route.extend({
model() {
// record generation code here...
},
afterModel()
{
Ember.run.later(this, function()
{
this.refresh();
}
, 2000);
}
});
----- solution -----
With new up-to-date browsers is not happening, so, this behavior exists only "in the past"... For sake of completeness I should find a solution to make it work properly also on "old" browsers, but I don't have time to spend on this.
If anyone of you figures out a 360 degrees solution an answer is still appreciated.
As I see those icons are static. So my suggestion is to use css:
1) Use spans(or divs) instead if images
2) Add icon as background image
html:
<p><span>active parameter</span><span class="icon active"></span></p>
<p><span>inactive parameter</span><span class="icon inactive"></span></p>
css:
.item
width: 16px //icon dimensions
height: 16px
// you may also add display: inline same as for images and so on
.active
background-image: url('/images/icon1.jpg')
.inactive
background-image: url('/images/icon2.jpg')
Benefit: Images will be loaded once by css engine along with styles.
PS: You can get rid of inactive class if your icon is inactive by default:
html:
<p><span>active parameter</span><span class="icon active"></span></p>
<p><span>inactive parameter</span><span class="icon"></span></p>
css:
.item
width: 16px //icon dimensions
height: 16px
background-image: url('/images/icon2.jpg')
// you may also add display: inline same as for images and so on
.active
background-image: url('/images/icon1.jpg')
PPS: It's really easy to manage classes with Ember by using classNameBindings
You need to set the image display to none.
Set the display to either inline-block or block for visible and none for not visible.
Preferably use css classes, since you are doing it with javascript. It might delay the action of hiding the images while the page loads.
You can use css classes like
.active{
display:block;
}
.inactive{
display:none;
}
Use these classes to add or toggle for a specific img element.
Still there will requests to server for images because you are only hiding the images through styles.
Display MDN

How to prevent partially loaded images from displaying?

If you have, let's say, 3MB image in img tag, it will take a few seconds to load. When the image is loading, browser is sort of "printing" it - it shows the top part first, then middle and then bottom. How do I prevent this from happening?
I'd rather have the image hidden and after second or two shown - when it is fully loaded.
One way would be to give them a class that gives them opacity: 0 so they don't show:
<img src="/path/to/image" class="loading">
And in CSS:
.loading {
opacity: 0;
}
In head, we override that if JavaScript is disabled (so we're not unfriendly to non-JavaScript visitors):
<noscript>
<style>
.loading {
opacity: 1;
}
</style>
</noscript>
...and then in code at the bottom of your page, find all your images and remove the class when they've loaded, and...(see comments):
(function() {
// Get an array of the images
var images = Array.prototype.slice.call(document.querySelectorAll("img.loading"));
// Hook their load and error events, even though they may have already fired
images.forEach(function(image) {
image.addEventListener("load", imageDone.bind(null, image));
image.addEventListener("error", imageDone.bind(null, image)); // Could handle errors differently
});
// Check to see if any images are already complete
checkImages();
function imageDone(img) {
img.classList.loading("remove");
images = images.filter(function(entry) { entry != img });
}
function checkImages() {
images.forEach(function(image) {
if (image.complete) {
imageDone(image);
}
});
if (images.length) {
// Check back in a second
setTimeout(checkImages, 1000);
}
}
})();
That's a belt-and-braces approach. It proactively checks to see if images have finished loading, and also reactively handles the load and error event of images. In theory, we shouldn't need the setTimeout, and you might do testing without it, but...
Notice how once an image is complete, we remove the class so it's visible.
Old school:
To avoid the partial display of an image as it renders, save your large images as progressive, rather than baseline jpgs.
a progressive jpg renders as a series of scans of increasing quality
a baseline jpg renders top to bottom (what you described as “printing”).
The progressive option is considered more user friendly than both the sudden appearance of the image or the slow top to bottom rendering you dislike. The progressive file variant can even be smaller than its baseline counterpart.
For more about this read: The Return of the Progressive JPEG.
I think everyone here gave you some good answers and I just want to add in. 3MB is fairly big for a web image. Don't use something that large for an image being used for logo or layout. That's a larger amount of pixel data that you should only stick with if you are loading something that is a nice, large scale real-life image you want to preserve the quality to (or providing a download to a high-quality graphic of something). Besides the above, if you do a Google search, you find tons of solutions for loading images. Something nice I would use for larger images is a jQuery/ajax solution.

How to set full page background Image of a div that changes on page load

I tried but couldn't get it done.
I want the background of a div to cover full page according to the device width and it should change each time when page is load or refresh on same system.
I have tried many codes but none of them works for me.
Now the script that i am using is:
<script type="text/javascript">
window.onload=function(){
var thediv=document.getElementById("image");
var imgarray = new Array("../bgimages/1.png", "../bgimages/2.png", "../bgimages/3.png");
var spot =Math.floor(Math.random()* imgarry.length);
thediv.style.background="url("+imgarray[spot]+")";
}
</script>
The HTML code is as follows
<html>
<body>
<div id="image">
<div class = "container">
</div> <!--container ends-->
</div>
I want #image div background to cover full page.
This is the CSS i am using:
#image
{
width:100%;
height:100%;
background-repeat:no-repeat;
background-size:cover;
background-position:center;
}
Here is the link of the page: http://sahibfreelancer.hostzi.com/
No background image loading.
Please if i miss anything you can let me know. I hope i gave enough details. I am trying this from last one day.
Will be looking forward to your responses.
I spotted a typo :
var spot =Math.floor(Math.random()* imgarry.length);
... should be ...
var spot =Math.floor(Math.random()* imgarray.length);
... shouldn't it ? Does it work if you edit that ?
Since you have jQuery in the tags, I'm going to assume you're using jQuery.
But that being said you're not using the $ syntax in your code examples.
Here's how you can set the background with jQuery:
$('#image').css('background-image', 'url(' + imageUrl + ')');
Edit:
Looks like Ashugeo got it. Next time check the console for the output of your script, it would have been throwing an exception.
Also, if you are using jQuery, there's nicer ways to do what you're doing.
To make the image occupy the entire screen you can specify the viewport height in css like this #image {height:100vh}
Now for the javascript code everything looks fine to me if the images are in the specified url it should load them randomly. You can see a example here.
the only thing i've done is load the images over the web since i cant access them locally on fiddle. A different Image is loading every time.
As for the page load i've used a immediately invoking function which will fire when the contents are loaded but you can use onload as well.
I think its the path of your images.
I pasteD your code and change the url and it works http://jsbin.com/pozadujeca/edit?js,console,output

How to run vbscript code at certain browser width

I'm turning a clients website into a responsive site and they have lots of vbscript in the content of their home page. At mobile widths they've stripped out a lot of content which means there's lots of code that's being executed but not displayed thanks to display:none
Is there a way to run vbscript code when you hit a minimum width of 768px?
I thought about using javascript to get the screen width and store it as a cookie and use vbscript to get the cookie to obtain the screen width:
<SCRIPT LANGUAGE="javascript">
var width = screen.width;
document.cookie = 'YourDomain=ScreenWidthB='+width;
</SCRIPT>
<%Dim ScreenWidth%>
<%ScreenWidth=request.cookies("YourDomain")("ScreenWidthB")%>
but I feel there may be a better solution out there. Also the code above gives me the width of my monitor I believe, not the width of the browser
This isn't something you would do with any server side language.
You can either use Bootstrap Grid System for this, which has a built-in grid system to handle responsive sizing.
or you can simply use CSS to define your styles for elements with-in a certain viewport size, using the CSS #media tag:
Your CSS would look like this example:
div {width:100px;}
#media (min-width:768px) {
div { width: 50px; }
}
What this does is makes all div's at 100px width, but when the browser is 768px or larger it changes the div sizing to 50px, as defined with-in the #media tag.
Therefore, you can use VBScript to generate the CSS script in the page, without having to write any javascript code. But Bootstrap may be your best bet to help build a responsive design easily/seamlessly. You may want to check it out.
EDIT: Since OP has clarified not to even load the content
You can make a cookie in javascript, and read it in your VBScript to check the viewport.
You can use jQuery for this:
$(window).resize(function(e){
var w = $(this).width();
if(w>768) document.cookie = "viewport=768;";
else document.cookie = "viewport=;";
});
This will bind an event listener on any time the user resizes the window, to check it's size, and if above 768px, it will write the cookie or empty if not.
Then check for the viewport cookie using Request.Cookies("viewport")
Or better yet since you're concerned about performance, you can use Ajax to build your page when a certain viewport size is hit.
Again, you can use jQuery for this and bind to the window resize event.
contentloaded = false;
$(window).resize(function(e){
var w = $(this).width();
if(w>768 && !contentloaded) {
$.get(url,function(data){
$("div").html(data);
contentloaded = true;
});
}
});
I would use ajax to do this, since I'd want to show the content without the user having to refresh the screen as you would have to by using the cookie solution.

What is the simplest method to preload CSS without applying it?

Problem
I have made a Bootstrap 3.2.0 site with multiple different pages. Every different page has it's own, whole bodywide backgrond image. I have now gone the simplest route by making different CSS-file bodycssforthispage.css for every page. bodycssforthispage.css only contains the following code, and by then overwrites Bootstraps original body definitions:
html,body {
height:100%;
background-color: #333;
background-image: url(../img/bg-image.jpg);
background-repeat:no-repeat;
background-size:cover;
background-position:center;
background-attachment: fixed;
}
Now what I want to do here, is to preload all other site related CSS-files, so that when I go for example from index.html to page1.html, all the are needed files (CSS-file for background and images) are already preloaded to browsers cache, and the transition to the next page is smooth. It is important to notice, that I want to preload the whole CSS-file(s) and it's contents.
Solution 1: preload all images and use different .css for each page
I could preload all images needed with JavaScript by placing this simple code to the bottom of my index page:
<script type="text/javascript">
if (document.images) {
img1 = new Image();
img1.src = "img/bg1.jpg";
img2 = new Image();
img2.src = "img/bg2.jpg";
}
</script>
</body>
</html>
and then just create bgforthisandthatpage.css for each different page, only containing:
html,body {
height:100%;
background-color: #777;
background-image: url(../img/bg-imageforthispage.jpg);
background-repeat:no-repeat;
background-size:cover;
background-position:center;
background-attachment: fixed;
}
Problems using this way
This would be the simple solution, but it includes many many different .css-files. Preloading 5-10 CSS-files should be done at the bottom of the page so, that the page itself loads smoothly (just like in Bootstrap with many other scripts).
It is come to my knowledge (correct if I'm wrong) that preloading whole CSS-files (i.e via JavaScript) may cause cascade styles to overwrite each other, so that the page would then use the most bottom CSS-file(s) data (bg-image ect. in my case).
In my opinion preloading many different CSS-files just for the changing background image is not quite convenient.
Solution 2: give every html/body element it's own class with different bg-image
Giving each page it's own class like this:
<html class="contactpage-bg-image">
and then create own class for each page into the original css-file like this:
html.contactpage-bg-image {
/* styling */
}
html.indexpage-bg-image {
/* styling */
}
Problems using this way
If images are big-sized and there are a lot of them, it impacts dramatically to the index.html loading time, because it will fist load all images mentioned in .css file (as you know, the code to the .css is located at the top of the page between and tags).
Questions
What is the best way to:
a) Change the background image for different pages using some funky preload function (note that bg-image has to be in the body, because some fadeloader.js stuff in my site), and;
b) Is there any better way to do this then by making thispagesbg-image.css file for every single site and;
c) Feel free to come up with your own ideas to do this!
Solution would prefered to be done compleatly in Javascript, jQuery or some mixature with css (or what ever suits to do this task most efficiently).
After 2 hours of comprehensice Googling, I only came up with nothing. I found this Pre-loading external files (CSS, JavaScript) for other pages, but I think that this loads everything before my page is loaded.
EDIT: Temporarely fix
I have now created class for each page's <html> on mypagesCustomCSS.css (and copying it as much as needed):
html.page1ClassH, html.page1ClassHere body {
background-image:url(../img/bg-for-page1.jpg);
}
html.page2ClassHere, html.page2ClassHere body {
background-image:url(../img/bg-for-page2.jpg);
}
and then I have placed following image preload JavaScript to the bottom of my index.html just before </body> tag:
<script>
$(window).on('load', function() {
if (document.images) {
img1 = new Image();
img1.src = "img/bg-for-page1.jpg";
img2 = new Image();
img2.src = "img/bg-for-page2.jpg";
}
});
</script>
This does the trick for now! As I mentioned earlier, I am using this page through iPhone 4 and slow 3G connection, so the preloading is vital.
I am still experiencing some problems with my site, as it lag's a lot. Perhaps I should resize those super-sized images and try again. Have a try at: http://www.kolumbus.fi/~g636221/jano/index.html
Solution 2 looks good to me as you don't need to create multiple css files + will be cached on the first request. One clarification though, only the images for the css classes used on the page will be downloaded here.
So now, the only task remains is to pre-load resources for other pages user is about to browse. For this you can create a javascript file or jQuery code which downloads resources after the current page has been loaded completely.
jQuery File (Code)
var pages = ["class1", "class2", "class3"]; //Declare all pages here
window.onload = windowloaded();
function windowloaded()
{
for(i=0; i < pages.length; i++)
{
$("div#preloader").append("<div class='" + pages[i] + "'></div>"); //This will load all other resources automatically as css classes are already present on the current page.
}
}
HTML Code (Add to all pages, anywhere on page. This remains invisible and is responsible for pre loading resources for other pages.)
<div id="preloader"></div>
CSS Modification (Single CSS for all pages)
div#preloader { display : none; }
Replace this :
html.contactpage-bg-image {
/* styling */
}
with :
.contactpage-bg-image {
/* styling */
}
removing html will make the class applicable for div which is used for preloading the image.
You could place all your separate CSS backgrounds into a single CSS file that is used across your site.
Give each background a class selector. Something like:
CSS
html.backgroundOne, html.backgroundOne body {
/*styles*/
}
html.backgroundTwo, html.backgroundTwo body {
/*styles*/
}
Then give each page a corresponding class on the opening <html>:
HTML
<html class="backgroundOne">
This way your CSS is already cached ready for use.

Categories

Resources