Loading images asynchronously when in viewport in div with overflow: scroll; - javascript

I have this structure for my content:
<div id="content" style="overflow:scroll;height:500px; width: 500px;">
<div style="width:500px;height:100px;>
<img src='http://graph.facebook.com/user1/picture?width=50&height=50'>
</div>
<div style="width:500px;height:100px;>
<img src='http://graph.facebook.com/user2/picture?width=50&height=50'>
</div>
...
<div style="width:500px;height:100px;>
<img src='http://graph.facebook.com/userN/picture?width=50&height=50'>
</div>
</div>
So basically I have a div with overflow:scroll; which contains pictures of all the Facebook user's friends. For performance reasons, I think it's better to load images when they become visible in the viewport. I've tried everything including jquery.lazyload but I think because the images are inside my div with overflow:scroll the plugin doesn't function correctly.

I used this post to elaborate the following code.
First of all change your html to get image only from the first:
<div id="content" style="overflow:scroll;height:100px; width: 100px;">
<div style="width:500px;height:100px;">
<img src='http://graph.facebook.com/user1/picture?width=50&height=50' />
</div>
<div style="width:500px;height:100px;">
<img msrc='http://graph.facebook.com/user2/picture?width=50&height=50'/>
</div>
...
<div style="width:500px;height:100px;">
<img msrc='http://graph.facebook.com/userN/picture?width=50&height=50'/>
</div>
</div>
Then use this js to trigger scroll event from #content div and check if all the image is visible:
$(function(){
var content = $("#content");
function isScrolledIntoView(elem)
{
var divViewTop = content.scrollTop();
var divViewBottom = divViewTop + content.height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return ((elemBottom <= divViewBottom) && (elemTop >= divViewTop));
}
content.scroll(function(e){
content.find("img").each(function(i,e){
if(isScrolledIntoView(e)){
$(e).attr("src",$(e).attr("msrc"));
}
});
});
});
Please don't use this in production, the code should be optimized first.
Here is a link to the jsfiddle:

If you think its because of the divs, why not remove them:
<div id="content" style="overflow:scroll;height:500px; width: 500px;">
<img height='100' width='500' src='http://graph.facebook.com/user1/picture?width=50&height=50'>
<img height='100' width='500' src='http://graph.facebook.com/user2/picture?width=50&height=50'>
...
</div>

Related

.appendChild() appends into the end of div

I was making a booklet with plugin MOLESKINE NOTEBOOK WITH JQUERY BOOKLET, and I want to dynamically add pages to it, using JS.
Though, when I try to add a page, all the stuff that needs to be on separate pages after the title one, appears on the very first page. And the strangest thing here is that after several refreshings or clearing the cache, it all stands as it should.
So, here is the code of the book:
<div class="book_wrapper">
<a id="next_page_button"></a>
<a id="prev_page_button"></a>
<div id="loading" class="loading">Загрузка книги...</div>
<div id="mybook" style="display:none;">
<div class="b-load" id="book_itself">
<div>
<img src="https://helpunicorn.pythonanywhere.com/static/logo.png" style="border-radius: 10px;">
<h1>Книга добрых дел</h1>
<br>
<div style="text-align: center;">
<h2 id="user">Пользователь #</h2>
</div>
</div>
</div>
</div>
</div>
Every div is supposed to be a separate page.
This is the code of my JS function:
<script>
$.getJSON('https://helpunicorn.pythonanywhere.com/kdd-info/aadev151', function(data) {
document.getElementById('title').innerHTML += `${data[0].username} (${data[0].name})`
document.getElementById('user').innerHTML += data[0].username
if (data.length != 1) {
for (i = 1; i < data.length; i++) {
const div = document.createElement('div');
div.innerHTML = `
<h1>${data[i].name}</h1>
<p>${data[i].info}</p>
`;
document.getElementById('book_itself').appendChild(div);
}
} else {
document.getElementById('book_itself').innerHTML += `
<div>
<h1>Упс... Эта книга пока пуста...</h1>
<p>Узнайте, как заполнить её, на сайте</p>
<br>
<a href="http://helpunicorn.ru" target="_blank" class="article">
<cufon class="cufon cufon-canvas" alt="Article" style="width: 41px; height: 16px;">
<canvas width="55" height="21" style="width: 55px; height: 21px; top: -2px; left: -4px;">
</canvas>
<cufontext>HelpUnicorn</cufontext>
</cufon>
</a>
</div>
`
}
});
</script>
So, I believe the problem is not with the code but with the plugin, because, as I mentioned earlier, it just takes a refreshing or clearing cache. But I'm wondering what's the exact problem with it
Please, watch a video for a better understanding

Animated gif alternative using jQuery to animate an image sequence

I put together this very simple jQuery code to animate a sequence of images. It works perfectly. you can view it here.
But now I am trying to update the code so it could work on multiple image sequences at once as long as it has its own class that is referenced in the jQuery code. So I updated it - view below. Unfortunately my updates are not working. Can you guys help me resolve this issue? Thank you in advance!
let aniOne = $(".animation.first img");
let aniTwo = $(".animation.second img");
let currentImg = 0;
function changeImg(allImg){
$(allImg[currentImg]).fadeOut(0, function(){
if(currentImg == allImg.length -1){
currentImg = 0;
}else {
currentImg++;
}
$(allImg[currentImg]).fadeIn(0)});
}
setInterval(changeImg(aniOne), 0050);
setInterval(changeImg(aniTwo), 0050);
.animation {
width: 30%;
}
.animation img {
display: none;
}
.animation img:first-of-type {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="animation first">
<img src="http://s23.postimage.org/t57meexkb/horse_1.png">
<img src="http://s23.postimage.org/i86apnasr/horse_2.png">
<img src="http://s23.postimage.org/6kc8v3lnv/horse_3.png">
<img src="http://s23.postimage.org/w4ej1j71n/horse_4.png">
<img src="http://s23.postimage.org/ddclrdch7/horse_5.png">
<img src="http://s23.postimage.org/nbxkdulwr/horse_6.png">
<img src="http://s23.postimage.org/phrv8cpd7/horse_7.png">
<img src="http://s23.postimage.org/n1un88wob/horse_8.png">
<img src="http://s23.postimage.org/9yz0oz6gb/horse_9.png">
<img src="http://s23.postimage.org/6gn0sl5kb/horse_10.png">
<img src="http://s23.postimage.org/vnxwsu8ob/horse_11.png">
<img src="http://s23.postimage.org/bhuetyd0r/horse_12.png">
<img src="http://s23.postimage.org/imc82zka3/horse_13.png">
<img src="http://s23.postimage.org/auvi4fg4r/horse_14.png">
</div>
<div class="animation second">
<img src="https://i.imgur.com/5QGZklx.png">
<img src="https://i.imgur.com/5QGZklx.png">
<img src="https://i.imgur.com/i1oLaES.png">
</div>
As Chris G stated above:
The working code uses setInterval(changeImg, 50) which will work fine. The problem with your current attempt is setInterval(changeImg(aniOne), 50) which evaluates to a call to changeImg(aniOne), then a call to setInterval(undefined, 50) (since changeImg doesn't return anything). If you want this to work, you need to make changeImg into a function that returns a function. – Chris G
After we add these problems, we then have the issue of both animations sharing the currentImg variable, so instead I made two different variables and passed them along with the images. You can handle this many different ways.
let aniOne = $(".animation.first img");
let aniTwo = $(".animation.second img");
let num1 = 0;
let num2 = 0;
function changeImg(allImg, num){
function main(){
$(allImg[num]).fadeOut(0, function(){
if(num == allImg.length -1){
num = 0;
}else {
num++;
}
$(allImg[num]).fadeIn(0)});
}
return main;
}
setInterval(changeImg(aniOne, num1), 0050);
setInterval(changeImg(aniTwo, num2), 0050);
.animation {
width: 30%;
}
.animation img {
display: none;
}
.animation img:first-of-type {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="animation first">
<img src="http://s23.postimage.org/t57meexkb/horse_1.png">
<img src="http://s23.postimage.org/i86apnasr/horse_2.png">
<img src="http://s23.postimage.org/6kc8v3lnv/horse_3.png">
<img src="http://s23.postimage.org/w4ej1j71n/horse_4.png">
<img src="http://s23.postimage.org/ddclrdch7/horse_5.png">
<img src="http://s23.postimage.org/nbxkdulwr/horse_6.png">
<img src="http://s23.postimage.org/phrv8cpd7/horse_7.png">
<img src="http://s23.postimage.org/n1un88wob/horse_8.png">
<img src="http://s23.postimage.org/9yz0oz6gb/horse_9.png">
<img src="http://s23.postimage.org/6gn0sl5kb/horse_10.png">
<img src="http://s23.postimage.org/vnxwsu8ob/horse_11.png">
<img src="http://s23.postimage.org/bhuetyd0r/horse_12.png">
<img src="http://s23.postimage.org/imc82zka3/horse_13.png">
<img src="http://s23.postimage.org/auvi4fg4r/horse_14.png">
</div>
<div class="animation second">
<img src="https://i.imgur.com/5QGZklx.png">
<img src="https://i.imgur.com/5QGZklx.png">
<img src="https://i.imgur.com/i1oLaES.png">
</div>

re-sizing iframe inside div with js

Trying to figure out a way to to re-size the iframe inside the class="col-md-4 col-sm-12".
I tried resizing all inside that class but attempt failed.
var xx = document.querySelectorAll("#homePage > div:nth-child(2) > div.col-md-4.col-sm-12 > div");
for (var i = 0; i < xx.length; i++) {
xx[i].style.width="450px";
}
HTMl:
<div class="col-md-4 col-sm-12">
<div class="ms-webpart-zone ms-fullWidth">
<div id="MSOZoneCell_WebPartctl00_ctl42_g_ee6207c9_12ab_4c71_aa01_3d615b36437c" class="s4-wpcell-plain ms-webpartzone-cell ms-webpart-cell-vertical ms-fullWidth ">
<div class="ms-webpart-chrome ms-webpart-chrome-vertical " style="width:320px">
<div class="ms-webpart-chrome-title" id="WebPartctl00_ctl42_g_ee6207c9_12ab_4c71_aa01_3d615b36437c_ChromeTitle" style="width:320px;">
<span title=" This is a basic app part with custom properties." id="WebPartTitlectl00_ctl42_g_ee6207c9_12ab_4c71_aa01_3d615b36437c" class="js-webpart-titleCell"><h2 class="ms-webpart-titleText" style="overflow:hidden;text-overflow:ellipsis;text-align:justify;"><a accesskey="W" href="###"><nobr><span>/span><span id="WebPartCaptionctl00_ctl42_g_ee6207c9_12ab_4c71_aa01_3d615b36437c"></span></nobr></a></h2></span>
</div><div webpartid="ee6207c9-12ab-4c71-aa01-3d615b36437c" haspers="false" id="WebPartctl00_ctl42_g_ee6207c9_12ab_4c71_aa01_3d615b36437c" class="ms-WPBody ms-WPBorder noindex ms-wpContentDivSpace " allowdelete="false" allowexport="false" style="width:320px;height:210px;"><div id="ctl00_ctl42_g_ee6207c9_12ab_4c71_aa01_3d615b36437c" style="width: 450px;">
<iframe src="###" id="g_49a1549f_f388_4175_836c_c54ba7e29505" frameborder="0" width="320px" height="210px"></iframe>
</div></div>
</div>
</div>
</div>
</div>
"div.col-md-4.col-sm-12 > div"
This will only give you the very first div in the class.
What you can do is to query both divs and the iframe which then can be traversed.
var xx = document.querySelectorAll("div.col-md-4.col-sm-12 div, div.col-md-4.col-sm-12 iframe");
for (var i = 0; i < xx.length; i++) {
xx[i].style.width="450px";
}
If you just want the iframe to extend to it's parent's width and height then just set the iframe's width and height to 100% in CSS.
iframe{
width: 100%;
height: 100%;
}

Align div correctly on viewport when scrolling

I'm doing a parallax website wherein when the user scrolls the sliders will slide from the left and align within the viewport. The issue is that I have scroll the mousewheel many times in order for the slide to align. Is there a way to make the slide align within the viewport with just one scroll.
Here is my work in progress. I'm using skrollr(http://prinzhorn.github.io/skrollr/) for my parallax designs
http://creativekidsstudio.com/ck/
HTML
<section class="slide slide_1">
<div class="slide_content" >
<h2>You see a blank canvas,<br/> we see potential</h2>
<img src="<?php bloginfo('template_url'); ?>/images/canvas.png" alt="Canvas" />
</div>
</section>
<section data-0="transform:translateX(100%); " data-1500="transform:translateX(0%) " class="slide slide_2">
<div class="slide_content" >
<h2>You see a brush,<br/> we see a dream</h2>
<img src="<?php bloginfo('template_url'); ?>/images/brush.png" alt="brush" />
</div>
</section>
<section data-1500="transform:translateX(100%); " data-2500="transform:translateX(0%)" class="slide slide_3">
<div class="slide_content" >
<h2>You see a ball of clay,<br/> we see a world of creativity</h2>
<img src="<?php bloginfo('template_url'); ?>/images/clay.png" alt="clay" />
</div>
</section>
<section data-2500="transform:translateX(100%); " data-3500="transform:translateX(0%)" class="slide slide_4">
<div class="slide_content">
<h1>Every child is a creative kid.</h1>
<img src="<?php bloginfo('template_url'); ?>/images/kid.png" alt="kid" />
</div>
</section>
CSS
.slide{width:100%; height:100%; position:fixed}
.slide_1{background-image:url('images/patternfinal1.jpg'); z-index:1}
.slide_2{background-image:url('images/patternfinal2.jpg'); z-index:2}
.slide_3{background-image:url('images/patternfinal3.jpg'); z-index:3}
.slide_4{background-image:url('images/patternfinal4.jpg'); z-index:4}
.creative_content{ z-index: 10; position: relative; background-color: white; padding:20px 0; top:5%}
.slide_content{
text-align:center;
height:100%;
position:absolute;
top:15%;
margin:0 auto;
left:0;
right:0;
z-index:1;
font-family: 'anarchisticno_leaders..', sans-serif;
font-size:70px;
color:#333
}
.slide_1 img,
.slide_2 ing,
.slide_3 img,
.slide_4 img{display:block; margin:0 auto}
Here is the javascript that i have implemented but the problem is it seems to stop midway when i scroll.
JAVASCRIPT
<script>
var tempScrollTop = 0;
var currentScrollTop = 0;
var scrollHeight = $(window).height();
var newHeight = 0;
function scrollIt() {
$(window).off('scroll', scrollIt);
currentScrollTop = $(window).scrollTop();
if (tempScrollTop < currentScrollTop) {
newHeight = newHeight + scrollHeight;
$('html').animate({scrollTop: newHeight}, 500, function(){
var setScroll = setTimeout(function(){
console.log('Animation Complete');
tempScrollTop = $(window).scrollTop();
$(window).on('scroll', scrollIt);
}, 10);
});
} else if (tempScrollTop > currentScrollTop){
newHeight = newHeight - scrollHeight;
$('html').animate({scrollTop: newHeight}, 500, function(){
var setScroll = setTimeout(function(){
console.log('Animation Complete');
tempScrollTop = $(window).scrollTop();
$(window).on('scroll', scrollIt);
}, 10);
});
}
}
$(window).on('scroll', scrollIt);
</script>
Im not sure if you mean you want them to transform faster, or if you want them to stay on screen while you scroll longer.
Option 1: transform faster:
Currently you have your data- attributes for skrollr set to scroll your slide from 100->0% over 1000px. Currently you have:
<section data-1500="transform:translateX(100%); " data-2500="transform:translateX(0%)">
If you'd like it to tansform faster, you just need to changes these numbers to accommodate the speed at which you'd like it to transform. Example:
<section data-1500="transform:translateX(100%); " data-1600="transform:translateX(0%)">
Option 2: stay on screen longer:
If you want them to stay on screen longer you just need to increase the distance between the finish of one slide's transform and the beginning of the next. Currently you have:
<section data-1500="transform:translateX(100%); " data-2500="transform:translateX(0%)">
</section>
<section data-2500="transform:translateX(100%); " data-3500="transform:translateX(0%)">
</section>
If you'd like them to stay on screen longer try something like this:
<section data-1500="transform:translateX(100%); " data-2500="transform:translateX(0%)">
</section>
<section data-3500="transform:translateX(100%); " data-4500="transform:translateX(0%)">
</section>
Hope this helps

How do I create a JQuery content slider that uses 4 images to navigate rather than text?

I have for images with a number on it. Those numbers are 1-4. I want to place them numerically and when the user clicks on 1, i want them to go to slide 1 and if they click on 2, then slide 2. This also needs to have a sliding effect.
I am using this particular javascript code below for left and right options but i am not sure if I can re-use this for my purpose:
HTML would be something like:
<img src="#" class="image_one">
<img src="#" class="image_two">
<img src="#" class="image_three">
<img src="#" class="image_four">
<div class="content_for_image_One" id="slide1">
You see this when you click on image 1
</div>
<div class="content_for_image_two" id="slide2">
You see this when you click on image 2
</div>
<div class="content_for_image_three" id="slide3">
You see this when you click on image 3
</div>
<div class="content_for_image_four" id="slide4">
You see this when you click on image 4
</div>
<script type="text/javascript">
$(document).ready(function () {
var $sliderMask = $('#slider_mask');
var $slideContainer = $('#slide_container');
var $slides = $slideContainer.find('.slide');
var slideCount = $slides.length;
var slideWidth = $sliderMask.width();
$slideContainer.width(slideCount * slideWidth);
$slides.width(slideWidth);
var currentSlide = 0;
function animate() {
$slideContainer.stop().animate({ marginLeft: -(currentSlide * slideWidth) + 'px' }, 'slow');
}
$('#left_button').on('click', function () {
currentSlide = (currentSlide - 1 + slideCount) % slideCount;
animate();
});
$('#right_button').on('click', function () {
currentSlide = (currentSlide + 1) % slideCount;
animate();
});
$('#click_left').on('click', function () {
currentSlide = (currentSlide - 1 + slideCount) % slideCount;
animate();
});
$('#click_right').on('click', function () {
currentSlide = (currentSlide + 1) % slideCount;
animate();
});
});
</script>
Your provided html does not fit to your code, but let's assume you have the following html:
<div id="slidesWrapper">
<div id="slidesContainer">
<div class="slide"><!-- your html --></div>
<div class="slide"><!-- your html --></div>
<div class="slide"><!-- your html --></div>
<div class="slide"><!-- your html --></div>
</div>
</div>
<div id="thumbnails">
<img src="#" class="thumb" />
<img src="#" class="thumb" />
<img src="#" class="thumb" />
<img src="#" class="thumb" />
</div>
with the following css:
#slidesWrapper {
width: 1000px;
height: 400px;
overflow: hidden;
position: relative;
}
#slidesContainer {
width: auto;
position: aboslute;
}
.slide {
float: left;
height: 400px;
}
you could use something like:
(function($){
$(function() {
var wrapper = $('#slidesWrapper'),
container = $('#slidesContainer'),
slides = container.children(),
thumbs = $('#thumbnails').children();
container.css('left', '0');
thumbs.click(function() {
var index = $('thumbnails').children().index(this);
container.stop().animate({
left: '-' + slides.eq(index).position().left + 'px'
}, 1000);
});
});
})(jQuery);
its not tested though and I dont quite get what you want. This example fits if you have a wrapper with slides in it and only one can be visible, fixed width and height
function next()
{
var mar=$("#img_ul").css("margin-left");
var nm=mar.replace("px","");
if(nm==0)
{
$("ul").animate({"marginLeft":"-500px"},"slow");
}
else if(nm>0 || nm!=-2000)
{
nm=nm-500;
$("ul").animate({"marginLeft":nm+"px"},"slow");
}
else if(nm==-2000)
{
$("ul").animate({"marginLeft":"0px"},"slow");
}
}
function previous()
{
var mar=$("#img_ul").css("margin-left");
var nm=mar.replace("px","");
if(nm==0)
{
$("ul").animate({"marginLeft":"-2000px"},"slow");
}
else
{
nm=+nm + +500;
$("ul").animate({"marginLeft":nm+"px"},"slow");
}
}
</script>
</head>
<body>
<div id="slide_wrapper">
<ul id="img_ul">
<li>
<q>
Learn everything you can, anytime you can, from anyone you can there will always come a time when you will be grateful
you did.
</q>
</li>
<li>
<q>
Make it simple. Make it memorable. Make it inviting to look at. Make it fun to read.
</q>
</li>
<li>
<q>
If plan A fails, remember there are 25 more letters.
</q>
</li>
<li>
<q>
Do not go where the path may lead, go instead where there is no path and leave a trail.
</q>
</li>
<li>
<q>
A journey of a thousand miles must begin with a single step.
</q>
</li>
</ul>
</div>
<input type="button" id="previous" value="Previous" onclick="previous();">
<input type="button" id="next" value="Next" onclick="next();">
code from TalkersCode complete tutorial here http://talkerscode.com/webtricks/content-slider-using-jquery-and-css.php

Categories

Resources