css - change an image frequently with less server requests - javascript

I have a in html. Its content is described in css.
With different functions the classname of the div is changed to imageholder1,2 etc.
.imageholder1 { content: url('image1.png')}
.imageholder2 { content: url('image2.png')}
But I think this causes multiple server requests , each time the classname is changed.
Is there a way to reduce the server requests to the image file.
I would like a way to store the image into a variable and then point it from css code. Is it possible?
I also tried to use a css image sprite but I need to need a more flexible way.

If you put all your images in a hidden (display none) div, they'll load all at once. The browser should cache them, so then each time it changes, it pulls from the client system.
<div style="display: none;">
<img src="image1.jpg">
<img src="image2.jpg">
<img src="image3.jpg">
</div>

Preload the images and it will cache the images and only request each image once (it will also allow for smoother transitions between the images because subsequent images will already be downloaded). This will limit your http requests to one request per image (the minimum you can achieve without sprite sheets).
Here is a really nice jQuery solution (that doesn't add hidden elements to the DOM) but really any preloading scheme should work:
$.preloadImages = function() {
for (var i = 0; i < arguments.length; i++) {
$("<img />").attr("src", arguments[i]);
}
}
$.preloadImages("hoverimage1.jpg","hoverimage2.jpg");
Reference

According to me, if we load multiple images on a page it is going to have multiple requests.
Instead of this simply use a sprite combining all the images.
This will cause to fetch a single image from server.
Then define css properties for background for classes such that they will have different position values of the sprite used causing to show required image.
.imageholder1 {
background: url(/path/to/sprite.png) -60px -120px no-repeat;
}
.imageholder2 {
background: url(/path/to/sprite.png) -20px -120px no-repeat;
}

Related

How to cancel a background image from loading

How can you cancel the loading of an image defined by a background-image attribute?
There a few questions that show how to cancel the loading of an <img> tag by setting the src to '' or to a different image (such as this one, answered by Luca Fagioli). But this does not work for background images.
Luca provided a jsfiddle ( jsfiddle.net/nw34gLgt/ ) to demonstrate the <img src="" /> approach to canceling an image load.
But modifying that jsfiddle to use background-image instead clearly shows that the image continues loading, even if:
you do background-image: none (as suggested here)
or background-image: url("web.site/other_image.jpg")
or background-image: url('').
In fact, in my testing on Firefox 54, the background image continues loading even if you do window.stop() or close the tab.
So, is there any way at all to stop loading a background image once it starts?
My use-case for this is client-side, so I can't change the site to not use background images. I am viewing a gallery of many thumbnail images, but the thumbnails are much larger than they need to be. Smaller versions are available so I wanted to replace the large thumbnails with the smaller versions via Greasemonkey to ease the network load on my poor, slow connection. Each entry in the gallery is a <div> with a background-image inside an <a> linking to the full-size image. (using Fotorama).
If you need to target inline styles on the elements, then I think you can run a script near the bottom of the page to do that.
Testing this locally, the original images do not show as loading in the network tab.
var allDivs = document.getElementsByTagName('DIV');
for (var i = 0; i < allDivs.length; i++) {
// check for inline style
var inlineStyle = allDivs[i].getAttribute('style');
// check if background-image is applied inline
if (inlineStyle && inlineStyle.indexOf('background-image') != 1 ) {
allDivs[i].style.backgroundImage = 'url("newImg.jpg")'; // assign new value?
}
}
That is going to grab every div, so hopefully these elements have a class you can use to query first. Then you have a smaller collection to run the above on.
Classes, not inline styles:
If you could target classes, it would look a bit cleaner. You could create a new class and use it.
var els = document.querySelectorAll('.bg-img');
for (var i = 0; i < els.length; i++) {
els[i].classList.remove('bg-img');
els[i].classList.add('no-bg-img');
}

Improve image load time

I have a few img tags whose src is changed onmouseover. This takes an inordinate amount of time to load. How can I improve the load time? The images are basically just different icons.
You can do a few things.
1) CSS Sprites is probably the preferred method.
2) You can load the images in a div and set that div to display none, making it so the images are already loaded so on mouseover they'll be there instantly.
Also here's a link on how to PreLoad images with CSS
There are a few ways to do it, the ideal solution in your case would be to use CSS sprites considering they're icons. However, depending on the situation sometimes sprites aren't ideal.
Here's one solution using JavaScript to preload images:
var images = new Array();
function preload() {
for (i = 0; i < preload.arguments.length; i++) {
images[i] = new Image();
images[i].src = preload.arguments[i];
}
}
preload(
'http://image-1.jpg',
'http://image-2.jpg',
'http://image-3.jpg'
);
What you're trying to do is achieve a rollover. It is strange that you'd experience a very long delay in this process. Usually, if the images aren't stored in some remote location, they're pretty fast.
Look at this article for some guidance
Other things you could try:
- sprites in css
- you could use two overlapping divs and hide one and unhide the other and vice versa

Preload Images faster

I'm building a website that contains divs with background images. I'm very new to JavaScript. I want to preload the images so when you go to the site you don't have to wait and view a blank box when the image is loading. I'm using this preload code, but when I go to the site the images are still loading slowly. Is there a way to make this faster?
<script>
$(document).ready( function() {
var c = new Image();
c.onload = function(){
$("#contenthome").css("background-image", "url(../Images/Homepage.png)");
}
c.src = "url(../Images/Homepage.png)";
});
</script>
This is not directly approachable but has two solutions.
This question's solution needs some understanding about server side request headers specifying caching information. I am used to appengine so I set expiry to about a month or so. Caching is all about suggesting a browser to "keep the following images with you for a while, don't take from me each time you need them". according to your server side language, it is worth spending so that you will master this important thing in browser environment.
And, you must play some trick if your user should not see a set of blank boxes while the images load. in fact, you style them invisible, and once loaded, you make them visible. since you are using jquery, you can use something like
$(window).load(
function(){ $('#showAfterLoadingComplete').show("slow").fadeIn(); }
A page of example is here
Try this:
<script>
$(function() {
var c = new Image();
$(c).load(function(){
$("#contenthome").css("background-image", "url(../Images/Homepage.png)");
$(this).attr('src','../Images/Homepage.png').show();
}).hide();
});
</script>
I would suggest employing a different method. Javascript has to wait for the page to load in order to work right, which inherently will introduce a delay.
Why not base 64 encode all your images into css classes in a dedicated css document.
You can use a site like this to convert your images:
http://webcodertools.com/imagetobase64converter
Then paste the Data URI into the background-image property in your css class.
Your eventual markup could look something like this:
<div id="contenthome">[some content]</div>
And your CSS would look something like this:
#contenthome {
background: [DATA URI] /*I didn't paste the actual URI here, as it would be quite long and unruly */
no-repeat
50% 50%;
background-size: contain;
display: inline-block;
height: auto;
width: auto;
}
You may have to play around with the height, width, background-size, and display properties to get it to show just right.
You could even take a further step and use a cache manifest to explicitly cache your css files so the load times are even faster.

Protecting an Image from downloading by Right-Click

EDIT: In response to many comments I do know that there is no sure fire way to fully protect an image from being downloaded. This method is to prevent the casual user from downloading by simple right click. The best way probably would be simply copyrighting your images and if you are very concerned would be using a service like Digimarc to digitally watermark your image. Now to the question:
I came across a site that is using a GIF overlay over their actual image so it protects the image from users right clicking and downloading the image (though you can still grab the actual image from within the code). The code they use to do this is:
<div><img src="-Transparent GIF File-" alt="" width="530" height="558"
border="0" original="-Actual Image Displayed-" /></div>
My question is the original tag is not a real tag and is used and translated by Javascript of some sort. I would like to replicate this on my site. Can someone help me find this script?
This is pointless. If a browser displays an image, it can be taken. Any attempt to prevent that is merely site overhead that can very easily be circumvented.
You're best protection is to put a copyright notice on the images themselves.
In any event, if you really want to swap the original attribute you can...
$(function() {
var o = $('img').attr('original');
$('img').attr('src', o);
});
Demo here
but... that doesn't do anything to prevent the user selecting and saving the image tied tot eh original attribute.
A simpler solution for what you're trying to accomplish is to add all of these attributes to the img tag:
ondrag="return false"
ondragstart="return false"
oncontextmenu="return false"
galleryimg="no"
onmousedown="return false"
Also, to optionally make the image print smaller, add this to the img tag:
class="imgPrint"
And include this related CSS:
#media print
{
.imgPrint
{
width: 40%;
}
}
You can do this without original tag also :
http://rainbow.arch.scriptmania.com/scripts/no_right_click.html
see this link.
I think this is what u want, this link may help you.
This is my implementation for a light protection of images.
It will create a transparent cover DOM element over the image (or text). If you disable javascript the image will be hidden and if you remove the cover the image will be hidden on mouse over. Also right click on images is disabled.
You can always printscreen, grab from the downloaded resources, etc, etc. This will only filter the most basic ways of download. But for a more convenient protection you have to hide the image path and render to a canvas object.
You can improve this, but there is always a method to get the image.
Tested on major browsers and working!
HTML
<div class="covered">
<img src="image.jpg" alt="" />
</div>
JAVASCRIPT + JQUERY
$('.covered').each( function () {
$(this).append('<cover></cover>');
$(this).mousedown(function(e){
if( e.button == 2 ) {
e.preventDefault();
return false;
}
return true;
});
$('img', this).css('display', 'block');
$(this).hover(function(){
var el = $('cover', this);
if (el.length <= 0) {
$(this).html('');
}
});
});
CSS
cover
{
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.covered
{
position: relative;
}
.covered img
{
display: none;
}

How to load images dynamically (or lazily) when users scrolls them into view

I've noticed this in numerous "modern" websites (e.g. facebook and google image search) where the images below the fold load only when user scrolls down the page enough to bring them inside the visible viewport region (upon view source, the page shows X number of <img> tags but they are not fetched from the server straight away). What is this technique called, how does it work and in how many browsers does it work. And is there a jQuery plugin that can achieve this behavior with minimum coding.
Edit
Bonus: can someone explain if there is a "onScrolledIntoView" or similar event for HTML elements. If not, how do these plugins work?
Some of the answers here are for infinite page. What Salman is asking is lazy loading of images.
Plugin
Demo
EDIT: How do these plugins work?
This is a simplified explanation:
Find window size and find the position of all images and their sizes
If the image is not within the window size, replace it with a placeholder of same size
When user scrolls down, and position of image < scroll + window height, the image is loaded
I came up with my own basic method which seems to work fine (so far). There's probably a dozen things some of the popular scripts address that I haven't thought of.
Note - This solution is fast and easy to implement but of course not great for performance. Definitely look into the new Intersection Observer as mentioned by Apoorv and explained by developers.google if performance is an issue.
The JQuery
$(window).scroll(function() {
$.each($('img'), function() {
if ( $(this).attr('data-src') && $(this).offset().top < ($(window).scrollTop() + $(window).height() + 100) ) {
var source = $(this).data('src');
$(this).attr('src', source);
$(this).removeAttr('data-src');
}
})
})
Sample html code
<div>
<img src="" data-src="pathtoyour/image1.jpg">
<img src="" data-src="pathtoyour/image2.jpg">
<img src="" data-src="pathtoyour/image3.jpg">
</div>
Explained
When the page is scrolled each image on the page is checked..
$(this).attr('data-src') - if the image has the attribute data-src
and how far those images are from the bottom of the window..
$(this).offset().top < ($(window).scrollTop() + $(window).height() + 100)
adjust the + 100 to whatever you like (- 100 for example)
var source = $(this).data('src'); - gets the value of data-src= aka the image url
$(this).attr('src', source); - puts that value into the src=
$(this).removeAttr('data-src'); - removes the data-src attribute (so your browser doesn't waste resources messing with the images that have already loaded)
Adding To Existing Code
To convert your html, in an editor just search and replace src=" with src="" data-src="
(Edit: replaced broken links with archived copies)
Dave Artz of AOL gave a great talk on optimization at jQuery Conference Boston last year. AOL uses a tool called Sonar for on-demand loading based on scroll position. Check the code for the particulars of how it compares scrollTop (and others) to the element offset to detect if part or all of the element is visible.
jQuery Sonar
Dave talks about Sonar in these slides. Sonar starts on slide 46, while the overall "load on demand" discussion starts on slide 33.
There is a pretty nice infinite scroll plugin here
I've never programmed one myself, but I would imagine this is how it works.
An event is bound to the the window scrolling
$(window).scroll(myInfinteScrollFunction);
The called function checks if scroll top is greater than the window size
function myInfiniteScrollFunction() {
if($(window).scrollTop() == $(window).height())
makeAjaxRequest();
}
An AJAX request is made, specifying which result # to start at, how many to grab, and any other parameters necessary for the data pull.
$.ajax({
type: "POST",
url: "myAjaxFile.php",
data: {"resultNum": 30, "numPerPage": 50, "query": "interesting%20icons" },
success: myInfiniteLoadFunction(msg)
});
The ajax returns some (most-likely JSON formatted) content, and passes them into the loadnig function.
Hope that makes sense.
You can now use loading="lazy" on the images as well as iframes so that it defers the loading until the user scrolls to that element.
<img src="http://placeimg.com/640/360/any" loading="lazy" />
As quoted in MDN:
Loading attribute The loading attribute on an element (or the
loading attribute on an ) can be used to instruct the browser
to defer loading of images/iframes that are off-screen until the user
scrolls near them.
Can I use?
You can use on all modern browsers for the images, but iframes are experimental as of now.
#import url('https://fonts.googleapis.com/css2?family=Oswald&display=swap');
.scroll-down {
height: 100vh;
background: #037ef3;
display: grid;
place-items: center;
color: #fff;
font-family: "Oswald";
font-size: 2em;
}
.image {
padding: 2em;
display: grid;
place-items: center;
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
}
<div class="scroll-down">
Let me take this space so that you can scroll down
</div>
<div class="image">
<img src="http://placeimg.com/640/360/any" loading="lazy" /> <!-- The only important part -->
</div>
Tip:
As you can see in the demo, it creates layout shift which will create a bad UX while scrolling. So try to use placeholders. Something similar like this: NextJS Placeholder
Lazy loading images by attaching listener to scroll events or by making use of setInterval is highly non-performant as each call to getBoundingClientRect() forces the browser to re-layout the entire page and will introduce considerable jank to your website.
Use Lozad.js (just 569 bytes with no dependencies), which uses IntersectionObserver to lazy load images performantly.
The Swiss Army knife of image lazy loading is YUI's ImageLoader.
Because there is more to this problem than simply watching the scroll position.
This Link work for me demo
1.Load the jQuery loadScroll plugin after jQuery library, but before the closing body tag.
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script><script src="jQuery.loadScroll.js"></script>
2.Add the images into your webpage using Html5 data-src attribute. You can also insert placeholders using the regular img's src attribute.
<img data-src="1.jpg" src="Placeholder.jpg" alt="Image Alt"><img data-src="2.jpg" src="Placeholder.jpg" alt="Image Alt"><img data-src="3.jpg" src="Placeholder.jpg" alt="Image Alt">
3.Call the plugin on the img tags and specify the duration of the
fadeIn effect as your images are come into view
$('img').loadScroll(500); // in ms
Im using jQuery Lazy. It took me about 10 minutes to test out and an hour or two to add to most of the image links on one of my websites (CollegeCarePackages.com). I have NO (none/zero) relationship of any kind to the dev, but it saved me a lot of time and basically helped improve our bounce rate for mobile users and I appreciate it.

Categories