Make first image instant loading others lazy loading - javascript

Loop wrap class contains articles items on list/tag/pagination pages. What is js script to make first article image in a loop not lazy load and the next articles items lazy loading, so mobile screen have first image loaded instantly?
Maybe there is a script to add loading=lazy attribute to the 2nd and next image items in the list?
It must be js script.
<div class="loop-wrap">
<article class="post-card">
<div class="featured-image">
<img srcset="/home-office-gbd591828c_hu0f5a458a9401493855cf19b7f0eb18b5_233090_300x0_resize_q75_box.jpg 300w,
/home-office-gbd591828c_resize_q75_box.jpg 600w,
/home-office-gbd591828c_resize_q75_box.jpg 1200w" sizes="(max-width:480px) 300px, (max-width:768px) 600px, 1200px" src="/home-office-gbd591828c.jpg" loading="lazy" alt="Title">
</div>
<div class="about-post">
... redacted
</div>
</article>
</div>

It is not possible to manipulate the attributes before the DOM loaded.
According to:
https://web.dev/
All images that are above the fold—that is, immediately viewable without scrolling—load normally.
Make sure your first image is within this area.

Related

How to load dynamically the content of a Modal (Bootstrap 4)

I'm setting up a web site rich of images.
I've designed it as a landing page: all content has to be on the main HTML page, without flow in others, actually there is the only index.html.
This will be the official website of a Theater, the images are all related to their shows.
To estimate the number of images:
40 shows an almost 40 pics per show (About 600kb per Image)
Almost 1gb of pictures in the same page!
Every show is represented with an image and when you click the Show image a Modal is opened showing the related pics in a grid and information about it.
I'm using Bootstrap 4, Jquery and CSS.
The problem is: if I add all the modals (with the pics in it) to HTML page my website get very lazy and doesn't ** load properly**.
I'm searching a way to load dynamically the pics every time you click on the show, avoiding to load the Dom with ALL the pictures from the first moment.
I've tried with Jquery injection, but is very hard to handle when the modal is open and when modal is closed and I don't think that is a proper and strict way to code.
I was thinking about a PHP server manipulation of images.
Php elaborate and minimize the images to make thumbnail so when images are seen in a grid they are not in the full size, and only when images are clicked they shown in full size (with lightbox.js).
But I'm a complete noob with PHP, and I didn't find an easy tutorial.
I'm opened to any solution you think I can implement, mostly to those who care about SEO optimization and faster loading time for client!
<!-- MODAL EXAMPLE -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog modal-full " data-dismiss="modal">
<div class="modal-content mx-auto">
<div class="modal-body">
<div class="column mx-auto">
<div class="sidebar-box">
<h2 class="title">SHOW TITLE</h2>
<h2 class="subtitle"> SHOW SUBTITLE</h2>
<p class="middle">MIDDLE INFORMATION</p>
<p class="description">SHOW DESCRIPTION</p>
</div>
</div>
<div class="column mx-auto">
<!-- THERE WILL BE ALL THE IMAGES IN A GRID-->
<div class="row justify-content-center">
<a href="stages/alesi/alesi1.JPG" data-title="Fotografia ©" data-lightbox="alesi">
<img src="stages/alesi/alesi1.JPG" alt="" />
</a>
<a href="stages/alesi/alesi2.JPG" data-title="Fotografia ©" data-lightbox="alesi">
<img src="stages/alesi/alesi2.JPG" alt="" />
</a>
<a href="stages/alesi/alesi3.JPG" data-title="Fotografia ©" data-lightbox="alesi">
<img src="stages/alesi/alesi3.JPG" alt="" />
</a>
</div>
</div>
</div>
</div>
</div>
</div>
Thank you very much to all stack overflow community!
One way to do it is with AJAX, yeah, you can have the content of each modal into a different HTML/PHP file, and on click on the modal to make an AJAX request, and putting the specific modal content(html file) into the page.
So, basically, you will have the whole <div class="modal-body"> div in a different HTML file, and on modal click you will have something like that
$("the_modal").click(function(){
$.ajax({url: "modal1.html", success: function(result){
$("#myModal modal-content").append(result);
}});
});
Of course, you can put data attributes on the modal and use them in the AJAX, so it will work for all the modal across the website.
The other thing that will help a lot is optimizing the images, reducing the size, the quality.
If your main problem is the amount of images that will have to be loaded delaying your page so I suggest that you try to implement images lazy-loading. This is going to enhance the performance of your website since your images will load only when they are shown in the viewport.
There is a jQuery plugin you can use for that: jQuery.Lazy()
You can use this link to refer how to load dynamic data in a single bootstrap modal.
https://getbootstrap.com/docs/4.3/components/modal/#varying-modal-content
If you have the show data in database or JSON file, you can then pass the id of the show which is clicked in the data attribute as given in above example.
Then using modal event show.bs.modal, you can fire an ajax call, which will populate the required data in the .modal-body and on close you can clear the data from the modal.
I would advise against loading 40pics x 600k by default. You need to be thinking about mobile users.
I would use a gallery script (I recommend Photo Swipe) and a request to a server-side script returning a json that will be used to create the gallery only on demand.
Check this page: https://photoswipe.com/documentation/custom-html-in-slides.html

How should I not load the images with broken link?

I'm working on a feature, in which images are being rendered from the servers. I was working on aligning the images but found that there is a lot of white space. This was the reason, due to loading of images with a broken link.
HTML :
<div class="image-result" *ngIf="Display('images')">
<div class="col-sm-3" *ngFor="let item of items$|async">
<a href="{{item.link}}">
<figure>
<img class="res-img" src="{{item.link}}" onerror="this.style.display='none'">
</figure>
</a>
</div>
</div>
I have used onerror="this.style.display='none'" to solve the problem, but leaves a lot of white space when images are being loaded from the server. Is there any solution for it like to remove img tag whenever a image with a broken link has been detected ? I have gone through stackoverflow before asking question, but I'm not able to solve this problem. It would be great if someone can help me out. Thanks! :)
Instead of onerror="this.style.display='none'" to hide an image, you can use onerror="this.parentNode.removeChild(this)" to remove the image tag altogether.
If you want to remove the entire column, in your specific case you can do the following.
var colEl = this.parentNode.parentNode.parentNode;
colEl.parentNode.removeChild(colEl);
Or, in your HTML:
onerror="this.parentNode.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode.parentNode)"
You should probably move that to some JavaScript function and attach your handler by saying
element.addEventListener('error', function() { /* ... */ });
References: parentNode, removeChild, addEventListener.
If you don't care about supporting Internet Explorer, you can also use remove instead of doing the parentNode.removeChild trickery. That would be particularly useful for reducing the code length in your onerror attribute, would you choose to use it, but I don't recommend that.
A more angular-way of doing this would be:
<img src="{{item.link}}" (error)="item.brokenImage=true">
So you would have:
<div class="col-sm-3" *ngFor="let item of items$|async">
<div *ngIf="!item.brokenImage">
<a href="{{item.link}}">
<figure>
<img class="res-img" [src]="item.link" (error)="item.brokenImage=true">
</figure>
</a>
</div>
</div>
You need to listen for the error event of the image element, and assign a boolean on whether the image loaded successfully or not. Then, depending on that value angular will either show the image with the div, or remove it from the DOM.

nanoScroller.js doesn't initialize

I have a strange problem with a website where I try to embed nanoScroller.js
I've implemented the HTML structure and loaded the necessary js and css but it doesn't load the scroller. Has anyone an idea?
Website is: http://www.ehmesevents.de/portfolio If browser Window is wider than 980px
The updated docs of nanoscroller showed, that not the id of the content is needed. the class "nano-scroller" is needed. so it would look like:
<div id="about" class="nano">
<div class="nano-content">
content....
</div>
</div>

preload elements with none displaying div

i want to preload all my Elements before manipulating them with jquery and co.
i considered that i could make a div with display: none and put all elements in there which im using for my site.
<div id="preload" style="display: none">
<img src="1.png" />
<img src="bla.gif" />
<img src="another_one.png" />
<img src="cutelittlekitten.png" />
</div>
and then this to fade in my site.
$('#preload img').load(function() {
/* Site fades in all elements are preloaded */
});
is there any disadvantage to do it like that? and if, why and maybe another better solution?
edit: i would like to pre-cache the images!
Disadvantage is you're making people wait. Just lazy load your images instead - any image above the fold you use a legit src attribute, and any image below the fold, you do something like this:
<img class="lazyload" src="images/clear.gif" data-src="path/to/real/image.jpg" />
Then you could use a plugin like this or write your own to fade in images with the class 'lazyload' on scroll if they appear in the visible window region:
http://www.appelsiini.net/projects/lazyload
You could also simply lazy load all those images on window.load so they'll begin to fade in after the above-the-fold images are visible and ready.

setting content of element with jquery via text() duplicates the text

I have a one page site that displays a portfolio. Basically it consists of a a list of images that are displayed as a slideshow with sudoslider
Once a new slideshow (an image in this case) is loaded, the description of the image should be updated.
For some reason or another, the description is displayed twice, as you can see at this version which is created via wordpress. The weird thing is that I have a static version of this website that does not seem to produce this problem, while the html/javascript/css structure is exactly the same (as far as I am not overlooking something).
Relevant pieces of code:
html-list:
<section id="portfolio">
<ul id="portfolio-ontwerpen" class="noscript">
<li>
<figure><img width="800" height="569" src="http://haendehoch.nl/wp/wp-content/uploads/2013/01/klinch1.jpg" class="attachment-large wp-post-image" alt="klinch1" /></figure>
<figcaption>Klinch poster</figcaption>
</li>
<li>
<figure><img width="800" height="565" src="http://haendehoch.nl/wp/wp-content/uploads/2013/01/hh_grid.jpg" class="attachment-large wp-post-image" alt="hh_grid" /></figure>
<figcaption>Grid</figcaption>
</li>
</ul>
</section>
javascript:
var sudoSlider = $("#portfolio").sudoSlider({
afterAniFunc: $("aside figcaption").text($(this).find('figcaption').text()); },
});
$(this) in this case refers to the current slideshow (the current list-item)
sudoslider description of the afterAniFunc (basically a function that is executed after the next slide animation has been finished)
afterAniFunc:false. Same as beforeAniFunc. It's just runs after the animation (still any animation) has finished. beforeAniFunc does not execute multiple times if you use fade, but can still execute multiple times if you use continuous.
I'm not sure exactly how/why it's happening, but you seem to be selecting multiple elements with the statement:
$(this).find('figcaption').text()
Selecting only the first element is providing the correct result for me:
$(this).find('figcaption').first().text()

Categories

Resources