Lazy Load Images Only After Bootstrap Modal has Opened - javascript

I found two similar answers here but both were unsuccessful for my situation (given my limited ability to translate them to my situation). I have a page with a lot of fairly large images and the default method of Bootstrap is to load all the modal images upon page load. The visible html renders fairly quickly (I have a spinner for that) but the additional load time for the hidden modals makes the page impractical. I want the page to load only the visible (non-modal) content to complete the page load (and clear the spinner) and then load each modal's content only when that modal is fired. I've tried every lazyload solution I could find but the images will not render in the modal (the 'data-src' placeholders render but not the 'src' images that are supposed to replace them). I only want to lazyload (or load on 'show.bs.modal') the large images of the modal, those within the 'modal-body' class. I hope this is clear enough.
Sample code:
/* Javascript placed in the head */
<script>
function lazyLoad(){
var $images = $('.lazy_load');
$images.each(function(){
var $img = $(this),
src = $img.attr('data-src');
$img
.on('load',imgLoaded($img[0]))
.attr('src',src);
});
};
$('.modal-body').on("show.bs.modal", function () {
lazyLoad();
};
</script>
/* HTML in the modal section */
<div class="portfolio-modal modal fade" id="portfolioModal1" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-content">
<div class="galleryheader">
<img src="headerimage_1.png" height="77" width="1024">
</div>
<div class="close-modal" data-dismiss="modal">
<div class="lr">
<div class="rl">
</div>
</div>
</div>
<div class="container">
<div class="row">
<div>
<div class="modal-body lazy_load">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-src="images/largeimage_1A.jpg" height="585" width="800"class="img-centered" alt=""/>
</div>
<div class="modal-body lazy_load">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-src="images/largeimage_1A.jpg" height="585" width="800"class="img-centered" alt=""/>
</div>
<div class="modal-body lazy_load">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-src="images/largeimage_1A.jpg" height="585" width="800"class="img-centered" alt=""/>
</div>
</div>
</div>
</div>
<div class="close-lower" data-dismiss="modal">
<IMG SRC="images/close.jpg" WIDTH="85" HEIGHT="32"></a>
</div>
</div>
</div>
</div>

Firstly, put the lazy_load class on the img element, not on the parent div. Secondly the jQuery you need is something like this:
$('.portfolio-modal').on("show.bs.modal", function () {
$('.lazy_load').each(function(){
var img = $(this);
img.attr('src', img.data('src'));
});
});
Notes:
Use the portfolio-modal class to identify the modal.
Use the jQuery data() method to get the image to lazily load.

Related

I want to load content into a bootstrap 4 modal using intercooler.js

I'm trying to load content into a modal using intercooler, example here:
http://jsfiddle.net/qvpy3coL/3/
I'm having no joy and wonder if this is possible, or whether the bootstrap js will conflict?
Html is:
<div id="confirm-me" class="btn btn-primary" data-toggle="modal"
data-target="#msgmodal" ic-get-from="/click" ic-target="dynamiccontent"
ic-trigger="click">
Click Me to show dynamic modal</div>
<div class="modal fade" id="msgmodal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
Below will be dynamic content</h4>
</div>
<div id="dynamiccontent">
</div>
</div>
</div>
</div>
js is:
// mockjax stuff ...
$.mockjax({
url: "/click",
responseTime: 500,
response: function (settings) {
this.responseText = "Dynamic stuff here!";
}
});
I've never used intercooler but after a quick read it turns out there should be no problem.
The only requirement with dynamic content you want in the modal is that it should be valid HTML code.
I played with the example you put in some content:
$('#dynamiccontent').html('No, it wont have any problems as long as your placing HTML')
https://jsfiddle.net/5pe6yz0w/3/

Event Delegation - event trigger with wrong class

I'm trying to create a slider with html- vanilla javascript. I'm able to open a modal, show a wide slider image and small images (thumbnails). Everything looks fine but when I click the thumbnails (which have "small_image" class) they trigger events, change image and add the same images to the thumbnails section again.
I checked the console with console.log(e.target.className) when I clicked any of the thumbnails and it shows "slider" class not "small_image" class.. Why is this happening and how can I fix this ?
Html section
<div id="photos" class="tabcontent">
<div class="tabslider">
<div>
<img src="{{image_path("posts/5-1537128615.jpg")}}" class="slider">
</div>
<div>
<img src="{{image_path("posts/6-1537128615.jpg")}}" class="slider">
</div>
<div>
<img src="{{image_path("posts/7-1537128615.jpg")}}" class="slider">
</div>
<div>
<img src="{{image_path("posts/8-1537128615.jpg")}}" class="slider">
</div>
<div id="myModal" class="modal">
<span class="close cursor">×</span>
<div class="modal-content">
<!-- wide image -->
<div class="mySlides">
<img class="show_slider" src="">
</div>
<!-- small images -->
<div class="small_images"></div>
</div>
</div>
</div>
</div>
Javascript section
document.querySelector(".tabslider").addEventListener("click", function (e) {
if (e.target.className = "slider") {
let smallImages = document.querySelector(".small_images"),
images = document.querySelectorAll(".slider"),
slider = document.querySelector(".show_slider"),
sliderDiv = document.querySelector(".mySlides"),
model = document.querySelector("#myModal");
model.style.display = "block";
images.forEach(function (image) {
let img = Elementor.create("img", {"src": image.src, "class": "small_image"}),
div = Elementor.create("div", {"class": "columnlightbox"},);
div.appendChild(img);
smallImages.appendChild(div);
});
slider.setAttribute("src", e.target.src);
sliderDiv.style.display = "block";
}
})
e.target.className = "slider"
You are setting the value here, not comparing :D

How can I write variables so I don't have to repeat myself?

I'm using an animated modal called animatedModal.js
In order to have a modal fire on click, I have to register a new ID and class every time I need a new Modal. I'm writing this as static HTML, CSS, and JavaScript.
I don't want to register 49 classes and IDs when I know there's a more DRY way of doing so. How can I write this code so it finds classes and IDs and passes them into a function?
<div class="item box student-life">
<a class="demo2" href="#animatedModal-2">
<img class="responsive-img" src="img/design-3-cards-buttons-icon-update-final-design-TILES3_07.jpg">
<div class="content-card">
<h3 class="title">This is an example of a long headline. They Happen sometimes but, I won't let them destroy my layout. Not this time.</h3>
<h5 class="title">Service Learning</h5>
<div class="icon"><img src="img/icons/student-life.png" class="responsive-img" alt=""/></div>
<button class="btn pull-right">Read More</button>
</div>
</a>
</div>
<!--DEMO02 Window-->
<div id="animatedModal-2">
<!--THIS IS IMPORTANT! to close the modal, the class name has to match the name given on the ID class="close-animatedModal" -->
<div class="close-animatedModal-2">CLOSE MODAL</div>
<div class="modal-content"> <img class="responsive-img" src="img/ART-01024.jpeg">
<h1>Content for this block</h1>
</div>
</div>
JavaScript:
$("#demo01").animatedModal({
animatedIn:'zoomIn',
animatedOut:'bounceOut',
color:'#39BEB9',
beforeOpen: function() {
var children = $(".thumb");
var index = 0;
function addClassNextChild() {
if (index == children.length) return;
children.eq(index++).show().velocity("transition.expandIn", { opacity:1, stagger: 250 });
window.setTimeout(addClassNextChild, 200);
}
addClassNextChild();
},
afterClose: function() {
$(".thumb").hide();
}
});

How Can I change bootstrap-modal width in my situation?

I use the below way to load modal content to main html:
main html:
<div class="modal modal-custom fade" id="custom-view">
</div>
.....
modal html(on a Individual html):
<div class="modal-dialog">
<div class="modal-content message_align">
<div class="modal-body" align="center">
<span class="section">Custom Info</span>
{% crispy form form.helper%}
</div>
</div>
</div>
I load the modal content to main html like this:
$(".mod-custom").click(function(ev) {
......
$("#custom-view").load(url, function() {
$("#custom-view").modal('show');
}
}
the url is to render data on modal html
In my situation,How to change the width?
I hope this link might help. Changing modal size.
https://coolestguidesontheplanet.com/bootstrap/modal.php#myModal2
If you want to change the modal-content width, you can add modal-content width when #custom-view on click
$(".mod-custom").click(function(ev) {
......
$("#custom-view").load(url, function() {
$("#custom-view").modal('show');
$('.modal-content').css({'width':'900px'});
}}
just change the class .modal-content if you want to change another class

Adding on click events to IFrame which opens a modal

I am currently developing a div that will contain up to 4 Media type divs. The media types include images, PDFs, and Youtube videos. The code I currently have running creates the divs as imgs if possible. If it is not possible(youtube videos/pdfs) it opens them as IFrames. As of now, the user is able to click on the imgs which launches a modal. However, I am unable to to get the IFrames to show the modal.Here is my code HTML - Modal
<!-- Modal -->
<div id="mediaModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">title</h4>
</div>
<div class="modal-body">
<p>here would be the description</p>
</div>
<div class="modal-media">
<p>here is the media</p>
</div>
<div class="modal-footer">
<p>here would be the credits
</div>
</div>
</div>
</div>
Here is my javascirpt
//this creates img/iframes dynamcially and throws them into a media-container div
var source = null;
//if it is not a youtube video/pdf/txt, put it in a img tag
if( null == ( media[1].match(/pdf/i) || media[1].match(/txt/i) || media[1].match(/youtube.com/) ) )
{
source = "<img data-toggle='modal' data-target='#mediaModal' id='m" + i + "'src='"+ media[1] + "'<img>";
}
else //throw it in a iframe tag
{
source = "<iframe data-toggle='modal' data-target='#mediaModal' class='modz' id='m" + i + "'src='"+ media[1] + "'></iframe>";
}
var div = $(source);
$("#media-container").append(div);
I tried adding a class to the iFrame and adding an onClick method, but it does not seem like the IFrame is picking up a click.
//opens a modal box for IFrame media.
$(".modz").on("click", function(e){
console.log("BING");
$("#mediaModal").modal('show');
});
Any help would be awesome. Thank you!
You can find your answer by folowing the step in this answer:
stackoverflow.com adding-click-event-handler-to-iframe

Categories