jquery trigger('click') works only once - javascript

I'm trying to customize a jQuery lightbox plugin called LightGallery to achieve the following result:
1- Make the script fetch all images from a folder, using index increment as an image path;
2- Make the Lightbox open after clicking another element.
The problem is:
The plugin opens the lightbox one time only!.
I'm using trigger('click') to fires it for the first time, but after closing it and trying to click to repeat it again it does NOT work.
the plugin looks destroyed and it opens one image only!
I want it to opens the lightbox every time I click the targetted elements.
Here's my attempts: ( Pen here )
$(document).ready(function() {
var $lg = $('#lightgallery');
function fetchFolderImages() {
var checkImages, endCheckImages;
var img;
var imgArray = new Array();
var i = 1;
var myInterval = setInterval(loadImage, 1);
if ($lg.children().length > 0) {
checkImages = false;
endCheckImages = true;
} else {
checkImages = true;
endCheckImages = false;
}
function loadImage() {
if (checkImages) {
checkImages = false;
img = new Image();
img.src = 'http://sachinchoolur.github.io/lightGallery/static/img/' + i + '.jpg';
img.onload = moreImagesExists;
img.onerror = noImagesExists;
}
if (endCheckImages) {
clearInterval(myInterval);
console.log('function [loadImage] done');
runLightGallery();
return;
}
}
function moreImagesExists() {
imgArray.push(img);
$lg.append($('<a/>', {
'href': img.src
}).html(img));
i++;
checkImages = true;
console.log('function [moreImagesExists] done');
}
function noImagesExists() {
endCheckImages = true;
console.log('function [noImagesExists] done');
}
console.log('function [fetchFolderImages] done');
}
function runLightGallery() {
if ($lg.lightGallery()) {
//alert('working');
} else {
//alert('destroyed');
$lg.lightGallery({
thumbnail: true
});
}
//trigger click event on image to open the lightbox
$lg.children('a').trigger('click');
//empty method, thought we may can use
$lg.on('onAfterOpen.lg', function(event) {
//maybe we can use this method?
});
$lg.on('onCloseAfter.lg', function(event) {
$lg.children().remove();
$lg.toggle();
//$lg.lightGallery().destroy(true);
});
console.log('function [runLightGallery] done');
}
$('.gallery-item').each(function() {
$(this).on('click', function() {
$lg.toggle();
fetchFolderImages();
});
});
});
<!DOCTYPE html>
<html>
<head>
<link type="text/css" rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/lightgallery/1.2.16/css/lightgallery.css" />
</head>
<body>
<div class="gallery">
<div class="gallery-item">Gallery Item 1</div>
<div class="gallery-item">Gallery Item 2</div>
<div class="gallery-item">Gallery Item 3</div>
</div>
<div id="lightgallery" style="display: none; border: 5px solid red"></div>
<!--============== scripts ==============-->
<!-- jQuery -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.js"></script>
<!-- jQuery mouse wheel -->
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery-mousewheel/3.1.13/jquery.mousewheel.js"></script>
<!-- lightGallery : a lightbox jQuery plugin -->
<script src="//cdnjs.cloudflare.com/ajax/libs/lightgallery/1.2.16/js/lightgallery.js"></script>
<!-- lightGallery plugin for thumbnails -->
<script src="//cdnjs.cloudflare.com/ajax/libs/lightgallery/1.2.16/js/lg-thumbnail.js"></script>
</body>
</html>

LightGallery needs to be destroyed and initialized again
To destroy LightGallery use this code $lg.data('lightGallery').destroy(true);
source : https://github.com/sachinchoolur/lightGallery/issues/238#issuecomment-161020492
Pen
$(document).ready(function() {
var $lg = $('#lightgallery');
function fetchFolderImages() {
var checkImages, endCheckImages;
var img;
var imgArray = new Array();
var i = 1;
var myInterval = setInterval(loadImage, 1);
if ($lg.children().length > 0) {
checkImages = false;
endCheckImages = true;
} else {
checkImages = true;
endCheckImages = false;
}
function loadImage() {
if (checkImages) {
checkImages = false;
img = new Image();
img.src = 'http://sachinchoolur.github.io/lightGallery/static/img/' + i + '.jpg';
img.onload = moreImagesExists;
img.onerror = noImagesExists;
}
if (endCheckImages) {
clearInterval(myInterval);
console.log('function [loadImage] done');
runLightGallery();
return;
}
}
function moreImagesExists() {
imgArray.push(img);
$lg.append($('<a/>', {
'href': img.src
}).html(img));
i++;
checkImages = true;
console.log('function [moreImagesExists] done');
}
function noImagesExists() {
endCheckImages = true;
console.log('function [noImagesExists] done');
}
console.log('function [fetchFolderImages] done');
}
function runLightGallery() {
if ($lg.lightGallery()) {
//alert('working');
} else {
//alert('destroyed');
$lg.lightGallery({
thumbnail: true
});
}
//trigger click event on image to open the lightbox
$lg.children('a').trigger('click');
//empty method, thought we may can use
$lg.on('onAfterOpen.lg', function(event) {
//maybe we can use this method?
});
$lg.on('onCloseAfter.lg', function(event) {
$lg.children().remove();
$lg.toggle();
$lg.data('lightGallery').destroy(true);
});
console.log('function [runLightGallery] done');
}
$('.gallery-item').each(function() {
$(this).on('click', function() {
$lg.toggle();
fetchFolderImages();
});
});
});
<html>
<head>
<link type="text/css" rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/lightgallery/1.2.16/css/lightgallery.css" />
</head>
<body>
<div class="gallery">
<div class="gallery-item">Gallery Item 1</div>
<div class="gallery-item">Gallery Item 2</div>
<div class="gallery-item">Gallery Item 3</div>
</div>
<div id="lightgallery" style="display: none; border: 5px solid red"></div>
<!--============== scripts ==============-->
<!-- jQuery -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.js"></script>
<!-- jQuery mouse wheel -->
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery-mousewheel/3.1.13/jquery.mousewheel.js"></script>
<!-- lightGallery : a lightbox jQuery plugin -->
<script src="//cdnjs.cloudflare.com/ajax/libs/lightgallery/1.2.16/js/lightgallery.js"></script>
<!-- lightGallery plugin for thumbnails -->
<script src="//cdnjs.cloudflare.com/ajax/libs/lightgallery/1.2.16/js/lg-thumbnail.js"></script>
</body>
</html>

You are not destroying LightGallary the right way.
Use this for 'onCloseAfter.lg' event:
$lg.on('onCloseAfter.lg', function(event) {
$lg.children().remove();
$lg.toggle();
//$lg.lightGallery().destroy(true);
$lg.data('lightGallery').destroy(true);
});

I quickly looked through your code and saw you are loading dynamic data
Try even delegation , https://learn.jquery.com/events/event-delegation/
The problem is that at the moment of the event binding , not all the "a" elements really existing to bind event on it
Your trigger event should be something like
$(document).on('click','#someId a:first-child',function(){
})

Related

Iterate through list of url's with start and Stop button

I have a list of URL's and i need it to run as slide show on Start and Stop Of button. Currently it is running as a slideshow with out start and stop button.
Additionally I need to design a homepage with thumbnail of all those URL's.On click of thumbnail it has to redirect to that page
<html>
<head>
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script>
$(function () {
var urls = ["URL1", "URL2", "URL3","URL4", "URL5", "URL6","URL7", "URL8", "URL9"];
var i = 0;
function loadIframe(url)
{
$('#iframe').attr('src', url);
}
setInterval(function() {
// update the index
i = (i + 1) % urls.length;
loadIframe(urls[i]);
}, 13000);
loadIframe(urls[i]);
});
</script>
</head>
<body>
<iframe id="iframe" height="100%" width="100%"></iframe>
</body>
</html>
You need to trigger the setInterval and save it, to clear it later.
var intvl = false; //Global Variable
$('#StartButton').on('click', function()
{
(!intvl) ? intvl = setInterval(...) : return;
});
$('#StopButton').on('click', function()
{
clearInterval(intvl);
intvl = false;
});
EDIT: changed to disable multiple intervals
You can achieve this by storing setInterval in a variable so that you can use clearInterval() on it. clearInterval() will allow you to stop/pause the setInterval you created.
You also don't need the $(function() {...}) component anymore as you will be the one controlling when the slider starts/stops:
var slideInterval;
var urls = ["URL1", "URL2", "URL3", "URL4", "URL5", "URL6", "URL7", "URL8", "URL9"];
var i = 0;
function loadIframe(url) {
//$('#iframe').attr('src', url);
$('#iframe').html(url);
}
function start() {
if (!slideInterval) { // If an interval is already in-use (ie if the slider is running) don't allow another slider to be made -> continue using the current one.
slideInterval = setInterval(function() {
// update the index
i = (i + 1) % urls.length;
loadIframe(urls[i]);
}, 1000);
}
}
function stop() {
if (slideInterval) { // If an interval doe exsist, we can then clear it, if it doesn't exsist then we have no interval to "clear", and so we don't run this code if one isn't in use
clearInterval(slideInterval);
slideInterval = null;
}
}
loadIframe(urls[0]);
#iframe {
border: 1px solid black;
}
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<div id="iframe" height="100%" width="100%"></div>
<button onclick="start()">Start</button>
<button onclick="stop()">Stop</button>

Detect dynamically appended images load event pure javascript [duplicate]

Say, user opens a page, clicks on a button, and popup with images appears. How do I detect when all of the images have been loaded? I can't use window.onload here, since the page had already been loaded with all the assets. To make it clear, I want to find out final extents of the popup.
Popup is added to DOM like so:
var popup = document.createElement('div');
popup.innerHTML = '...';
document.body.appendChild(popup);
Simply:
var image = document.getElementById('image');
image.onload = function () {
alert ("The image has loaded!");
};
setTimeout(function(){
image.src = "http://lorempixel.com/500/500";
}, 5000);
<img id="image" src="">
See https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onload and Javascript callback for knowing when an image is loaded for more.
Based on this answer. Hopefully that is enough.
var cons = document.querySelector('#console');
var popup = document.createElement('div');
popup.className = 'popup';
popup.innerHTML = _.range(10).map(function(i) {
return '<img src="http://via.placeholder.com/50/50">';
}).join('');
document.body.insertBefore(popup, cons);
waitForImages(popup).then(function() {
d('loaded');
})
function d(s) {
var text = document.createTextNode(s);
cons.appendChild(text);
var br = document.createElement('br');
cons.appendChild(br);
}
function waitForImages(el) {
var images = document.querySelectorAll('img');
return Promise.all(_.compact(_.map(images, function(img) {
if (img.complete) {
d('img.complete');
return;
} else
return new Promise(function(resolve, reject) {
img.addEventListener('load', function() {
d('onload event');
resolve();
});
});
})));
}
.popup {
overflow: hidden;
}
img {
float: left;
margin: 0 5px 5px 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/3.5.0/bluebird.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<div id="console">
</div>

ReferenceError: jQuery is not defined in self invoking function

I've tried all the solutions from other Stackoverflow topics, but I can't my jQuery file to work.
I use a Wampserver to test my code and I test inside of multiple browsers (Firefox, Chrome, Opera). Same problem every time.
HTML
<script src="js/scripts.js"></script>
<script src="js/jquery-3.2.1.min.js"></script>
I've put these lines before my closing <\body> tag
scripts.js`
(function($) {
'use strict';
// holds current image shown
var $currNr = 0;
var links, images;
/**
* Function to prevent closures; adds click event handler to links
*/
var addEvents = function(nr) {
// add click event to link
$(links[nr]).on('click', function(e) {
showImage(nr);
e.preventDefault();
});
};
/**
* Function to show an image
*/
var showImage = function(nr) {
// find image
var $img = $(images[nr]);
if (!$img) return;
// find big image
var $photoBig = $('#photoBig');
// change
$photoBig.attr('src', $img.attr('data-src-l'));
$photoBig.attr('alt', $img.attr('alt'));
// remember current image number
$currNr = nr;
};
/**
* Function to show the next image
*/
var showNextImage = function() {
if ($currNr != (links.length - 1)) {
showImage($currNr + 1);
} else {
showImage(0);
}
};
/**
* Function to show the previous image
*/
var showPrevImage = function() {
if ($currNr != 0) {
showImage($currNr - 1);
} else {
showImage(links.length - 1);
}
};
// start scripts
$(window).on('load', function() {
// find images and links
links = $('#thumbsmenu li>a');
images = $('#thumbsmenu li>a img');
// add link events
$(links).each(function(nr) {
$(this).on('click', function(e) {
showImage(nr);
e.preventBubble();
});
});
// controls
$('#lnkFirst').on('click', function(e) {
showImage(0);
e.preventDefault();
});
$('#lnkPrev').on('click', function(e) {
showPrevImage();
e.preventDefault();
});
$('#lnkNext').on('click', function(e) {
showNextImage();
e.preventDefault();
});
$('#lnkLast').on('click', function(e) {
showImage(images.length - 1);
e.preventDefault();
});
// keyboard
$(document).on('keydown', function(e) {
var $code = (e.keyCode ? e.keyCode : e.which);
switch (event.keyCode) {
case 37: showPrevImage(); e.preventDefault(); break;
case 39: showNextImage(); e.preventDefault(); break;
}
});
// play
var $timer;
$('#btnPlay').on('click', function(e) {
if (!$(this).prop('playing')) {
$(this).val('stop');
$(this).prop('playing', true);
$currNr = 0;
$timer = setInterval(showNextImage, 1000);
} else {
$(this).val('start');
$(this).prop('playing', false);
clearInterval($timer);
}
});
});})(jQuery);`
I use a self-invoking function and use it as parameter but I get a:
ReferenceError: jQuery is not defined
Normally this code should work, that was how I was taught back then. Anyone an idea what could be the real issue here?
You are loading scripts.js before jQuery
Change the following code:
<script src="js/scripts.js"></script>
<script src="js/jquery-3.2.1.min.js"></script>
To:
<script src="js/jquery-3.2.1.min.js"></script>
<script src="js/scripts.js"></script>
Your script load ordering is wrong. Load jQuery first, then use it.
As other people suggested your order is wrong. In order for you to use JQuery in other script files it needs to be fully loaded. Change your HTML like so:
<script src="js/jquery-3.2.1.min.js"></script>
<script src="js/scripts.js"></script>

Detect when images added to DOM have been loaded

Say, user opens a page, clicks on a button, and popup with images appears. How do I detect when all of the images have been loaded? I can't use window.onload here, since the page had already been loaded with all the assets. To make it clear, I want to find out final extents of the popup.
Popup is added to DOM like so:
var popup = document.createElement('div');
popup.innerHTML = '...';
document.body.appendChild(popup);
Simply:
var image = document.getElementById('image');
image.onload = function () {
alert ("The image has loaded!");
};
setTimeout(function(){
image.src = "http://lorempixel.com/500/500";
}, 5000);
<img id="image" src="">
See https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onload and Javascript callback for knowing when an image is loaded for more.
Based on this answer. Hopefully that is enough.
var cons = document.querySelector('#console');
var popup = document.createElement('div');
popup.className = 'popup';
popup.innerHTML = _.range(10).map(function(i) {
return '<img src="http://via.placeholder.com/50/50">';
}).join('');
document.body.insertBefore(popup, cons);
waitForImages(popup).then(function() {
d('loaded');
})
function d(s) {
var text = document.createTextNode(s);
cons.appendChild(text);
var br = document.createElement('br');
cons.appendChild(br);
}
function waitForImages(el) {
var images = document.querySelectorAll('img');
return Promise.all(_.compact(_.map(images, function(img) {
if (img.complete) {
d('img.complete');
return;
} else
return new Promise(function(resolve, reject) {
img.addEventListener('load', function() {
d('onload event');
resolve();
});
});
})));
}
.popup {
overflow: hidden;
}
img {
float: left;
margin: 0 5px 5px 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/3.5.0/bluebird.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<div id="console">
</div>

Can't drop image from desktop with html5

I'm newbie in html 5, and i'm trying some code for drop image from desktop, but my code doesn't work. This is my code:
script>
function OnDropTextarea(event) {
if (event.dataTransfer) {
if (event.dataTransfer.files) {
var leftbox = document.getElementById("leftbox");
for (var i = 0; i < event.dataTransfer.files.length; i++) {
var file = event.dataTransfer.files[i];
leftbox.innerHTML += file;
}
} else {
alert("Your browser does not support the files property.");
}
} else {
alert("Your browser does not support the dataTransfer property.");
}
if (event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
return false;
}
</script>
<section id="leftbox" ondrop="return OnDropTextarea (event);"></section>
So, please! help me
I try new code, but i can only drag and drop box in other box, not from desktop.
Another code:
<script>
function doFirst() {
mypic = document.getElementById('pic');
mypic.addEventListener("dragstart", startDrag, false);
leftbox = document.getElementById('leftbox');
leftbox.addEventListener("dragenter", function(e) {
e.preventDefault()
}, false);
leftbox.addEventListener("dragover", function(e) {
e.preventDefault()
}, false);
leftbox.addEventListener("drop", dropped, false);
}
function startDrag(e) {
var code = '<img src="/assets/Koala.jpg">';
e.dataTransfer.setData('Text', code);
}
function dropped(e) {
e.preventDefault();
leftbox.innerHTML = e.dataTransfer.getData('Text');
}
window.addEventListener("load", doFirst, false);
</script>
<section id="leftbox">
</section>
<section id="rightbox">
<img src="/assets/Koala.jpg" id="pic"/>
</section>
You need to override dragover and dragenter and prevent the default action in order for an element to qualify as a valid drop target. MDN
EDIT: The drop should work now, I think (the only difference between your code in mine seems to be the fact that I also do e.dataTransfer.dropEffect = "copy" in my dragover and dragenter handlers). I wish people were more explicit with "doesn't work" - is the drop happening, but you're not getting the file contents?
If that is the case, the issue might be the fact that you are treating a File object as if it was a string. So instead of this,
leftbox.innerHTML += file;
try this:
var reader = new FileReader();
reader.onload = function(e) { leftbox.innerHTML += e.target.result; };
reader.readAsText(file);
ondrop="return OnDropTextarea (event);"
Should be:
ondrop="OnDropTextarea()"
May be this is useful for you,but you have to use the jquery library
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Upload images with Jquery</title>
<script src="jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var obj = $("#dragandrophandler");
obj.on('dragenter', function (e)
{
e.stopPropagation();
e.preventDefault();
//$(this).css('border', '2px solid #0B85A1');
});
obj.on('dragover', function (e)
{
e.stopPropagation();
e.preventDefault();
});
obj.on('drop', function (e)
{ //alert('');
e.preventDefault();
/*$(this).css('border', '2px dotted #0B85A1');*/
var files = e.originalEvent.dataTransfer.files;
var data = new FormData();
var i=0,l=files.length;
for (i = 0; i < l; i++) {
data.append('file' + i, files[i]);
}
$.ajax({
url: 'load.php',
type: 'POST',
contentType: false,
data: data,
processData: false,
cache: false
}).done(function(msg) {
});
});
$(document).on('dragenter', function (e)
{
e.stopPropagation();
e.preventDefault();
});
$(document).on('dragover', function (e)
{
e.stopPropagation();
e.preventDefault();
//obj.css('border', '2px dotted #0B85A1');
});
$(document).on('drop', function (e)
{
e.stopPropagation();
e.preventDefault();
});
});
</script>
<style type="text/css">
#dragandrophandler {
border: 2px dashed #ccc;
width: 300px;
height: 200px;
}
</style>
</head>
<body>
<div id="dragandrophandler">
Drop files here
</div>
<div id="meta"></div>
</body>
</html>

Categories

Resources