How to implement an onclick function to an array of divs - javascript

I'm using the Flickr API and I want to create a onlick popup div for each image which shows the image in a larger form like this http://fancybox.net/.
How can I implement this so that the onclick function will be applied to each div in the div container?
The project: http://jsfiddle.net/phippsy20/rtzp8/
jQuery: so this statement makes the divs
for (var i = 0; i < 210; i++) {
$('<div />').attr('id', 'photo-' + i).addClass('photo').appendTo('#photo-container');
}
This function loads the picture from flickr as the background image:
$.each(data.photos.photo, function(i, photo) {
var imgURL = 'http://farm' + photo.farm + '.staticflickr.com/' + photo.server + '/' + photo.id + '_' + photo.secret + '_n.jpg';
console.log(imgURL);
// Pre-cache image
$('<img />').attr({'src': imgURL, 'data-image-num': i}).load(function() {
console.log('image loaded');
var imageDataNum = $(this).attr('data-image-num');
$('#photo-' + imageDataNum).css('background-image', 'url(' + imgURL + ')').removeClass('fade-out').addClass('fade-in');
})

Ok, if i understand your question, this may help you:
$("#heading-name div").each(function(i){
$(this).attr("onclick","popup("+i+")");
});
Demo working: http://jsfiddle.net/k2h8p/1/ (test the code locally in your computer)

Related

What's causing Intersection Observer API to respond differently when replacing synchronous logic with asynchronous logic?

Context
I've used the "Intersection Observer API" to build an infinite scroll image gallery. Basically this API allows me to load more items when a certain dummy DOM element enters the viewport.
Prototype
Currently the prototype is implemented for an “iPhone X” (375x812) mobile device only. See: http://urbexco-acceptance.droppages.com/min_rep_ex_working (use Chrome DevTools 'inspect' device toolbar to select the right resolution). The image gallery is generated based on 57 items in the "database". When scrolling down, first 15 elements are loaded, then 15 more elements are loaded, then another 15 elements are loaded into the DOM, then another 10 elements are loaded, and finally 2 elements are loaded. When there are still more than 15 items left to be loaded, they are added using the following logic:
function addItems(n){
// Append new items to .items-wrapper
var items = document.querySelector('.items-wrapper');
for (var i = 0; i < n; i++) {
var url = 'https://img01.ztat.net/article/spp-media-p1/09742e38c25b3e1d9716e02f8e76e87d/89fc0bda6a2c446a8e9e0d8adbc9a4fe.jpg';
width = 170.5;
height = 246;
var newDiv = document.createElement('div');
newDiv.classList.add('item');
items.appendChild(newDiv);
newDiv.innerHTML = "<img src=" + '"' + url + '"' + "width=" + '"' + width + '"' + "height=" + height + "/>";
}
}
Minimal Working Example (no mobile view possible)
https://jsfiddle.net/9jqgzymo/
Objective
Since image width and height are currently hardcoded, I am now trying to assign width and height dynamically based on the image url. I try to achieve this using the getMeta() function:
function addItems(n){
// Append new items to .items-wrapper
var items = document.querySelector('.items-wrapper');
for (var i = 0; i < n; i++) {
var url = 'https://img01.ztat.net/article/spp-media-p1/09742e38c25b3e1d9716e02f8e76e87d/89fc0bda6a2c446a8e9e0d8adbc9a4fe.jpg';
getMeta(url);
}
}
function getMeta(url){
var img = new Image();
img.onload = function(){
res = calculateAspectRatioFit(this.width, this.height, 170.5, 246)
var newDiv = document.createElement('div');
newDiv.classList.add('item');
var items = document.querySelector('.items-wrapper');
items.appendChild(newDiv);
newDiv.innerHTML = "<img src=" + '"' + url + '"' + "width=" + '"' + res.width + '"' + "height=" + res.height + "/>";
};
img.src = url;
}
function calculateAspectRatioFit(srcWidth, srcHeight, maxWidth, maxHeight) {
var ratio = Math.min(maxWidth / srcWidth, maxHeight / srcHeight);
return { width: srcWidth*ratio, height: srcHeight*ratio };
}
Challenge
When implementing it this way, I see that - on initiation - already 30 items from the "database" where added to the DOM. Sometimes even all of them? Currently the non-working prototype is implemented for an “iPhone X” (375x812) mobile device only. See: http://urbexco-acceptance.droppages.com/min_rep_ex_not_working (use Chrome DevTools 'inspect' device toolbar to select the right resolution). For a minimal working example, see: https://jsfiddle.net/k3p20qno/
Key question
What is the reason that with my new implementation, on initiation, already 30 or more items are added to the DOM? How can I fix it?
Well the problem lies in here :
function getMeta(url){
var img = new Image();
img.onload = function(){
res = calculateAspectRatioFit(this.width, this.height, 170.5, 246)
var newDiv = document.createElement('div');
newDiv.classList.add('item');
var items = document.querySelector('.items-wrapper');
items.appendChild(newDiv);
newDiv.innerHTML = "<img src=" + '"' + url + '"' + "width=" + '"' + res.width + '"' + "height=" + res.height + "/>";
};
img.src = url;
}
Above code does an async operation with onload event. So it doesn't wait to image to be loaded.
If you turn this into a function that returns a promise you will get the result that you expect. And you should await where you call the function. That way when you add the intersection element it will add it as the last element of the items wrapper. If you don't await it will be added as the first element because the loading of the images will be async and will happen later.
function getMeta(url){
var img = new Image();
const p = new Promise(resolve =>{
img.onload = function(){
console.log( this.width+' '+ this.height );
res = calculateAspectRatioFit(this.width, this.height, 170.5, 246)
var newDiv = document.createElement('div');
newDiv.classList.add('item');
var items = document.querySelector('.items-wrapper');
items.appendChild(newDiv);
newDiv.innerHTML = "<img src=" + '"' + url + '"' + "width=" + '"' + res.width + '"' + "height=" + res.height + "/>";
resolve()
};
})
img.src = url;
return p;
}
Fiddle
Edit: Put the resolve() in the right position which is inside the load function

how to print multiple barcode images using jquery

I have generated multiple barcodes using this code:
function getCode() {
var multipleCodes = document.getElementById('codeArea').value;
var eachLine = multipleCodes.split('\n');
console.log("eachLine = " + eachLine);
for (var i = 0; i < eachLine.length; i++) {
console.log("Inside loop: " + eachLine[i]);
var div = document.createElement('iframe');
div.innerHTML = "";
div.setAttribute('id', 'iFrameID' + i);
document.body.appendChild(div);
document.getElementById('iFrameID' + i).src = 'barCodeGenerator/generateBarCode.php?q=' + eachLine[i];
}
and trying to print it by using this method:
function printDiv(divName) {
var strName = document.getElementById("codeArea").value;
var imageId = document.getElementsByClassName('decoded');
var imagObject = new Image();
imagObject = imageId;
var originalImage = '<img id="imageViewer" src="' + imageSrc + '" style="padding-top: 20px" alt="' + imageSrc + '" />';
popup = window.open('', 'popup', 'toolbar=no,menubar=no,width=700,height=650');
popup.document.open();
popup.document.write("<html><head></head><body onload='print()'>");
popup.document.write(originalImage);
popup.document.write("</body></html>");
window.close('popup');
popup.document.close();
setTimeout(function () { popup.close(); }, 8000);
}
which only print single image by merging all barcodes.
How can i print them separately as multiple images.
Any help will be appreciated.
The most part of this code is irrelevant to your question. Consider removing your logs, the parts about showing popup and hiding it for more clearance.
Seems imageSrc variable in your code contains the source of one image, so you need to change your code by sending the array of image sources and iterating over it:
var originalImage = '';
// assuming imageSrc is an array of image sources
for (var i=; i < imageSrc.length; i++) {
// note that I'm changing the id of the image a litle bit to ensure it will remain unique
originalImage += '<img id="imageViewer' + i + '" src="' + imageSrc[i] + '" style="padding-top: 20px" alt="' + imageSrc[i] + '" />';
}
then the rest of your code must work.

Image Currently Unavailable from Flickr

In my Firefox OS app i use Flickr API to show relevant images, My URL for the call is like this.
https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&lat=42.86366&lon=-75.91438&radius=3&format=json&nojsoncallback=1
and i use created a function to call the flicker api for the images. This is the function where i create the URL with the api key and latitude and longitude for the api call
function displayObject(id) {
console.log('In diaplayObject()');
var objectStore = db.transaction(dbTable).objectStore(dbTable);
objectStore.openCursor().onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
if (cursor.value.ID == id) {
var lat = cursor.value.Lat;
var lon = cursor.value.Lon;
showPosOnMap (lat, lon);
// create the URL
var url = 'https://api.flickr.com/services/rest/?method=flickr.photos.search';
url += '&api_key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
url += '&lat=' + lat + '';
url += '&lon=' + lon + '';
url += '&radius=3';
url += '&format=json&nojsoncallback=1';
$.getJSON(url, jsonFlickrFeed);
return;
}
cursor.continue();
} else {
$('#detailsTitle').html('No DATA');
}
};
}
This function gets the JSON object received from flickr. This function displays the thumbnails of the images in a jquery mobile grid.
function jsonFlickrFeed (data) {
console.log(data);
var output = '';
// http://farm{farmId}.staticflickr.com/{server-id}/{id}_{secret}{size}.jpg
for (var i = 0; i < data.photos.photo.length; i++) {
// generate thumbnail link
var linkThumb = '';
linkThumb += 'http://farm' + data.photos.photo[i].farm + '.staticflickr.com/' + data.photos.photo[i].server + '/' + data.photos.photo[i].id + '_' + data.photos.photo[i].secret + '_s.jpg';
// generate Full image link
var linkFull = '';
linkFull += 'http://farm' + data.photos.photo[i].farm + '.staticflickr.com/' + data.photos.photo[i].server + '/' + data.photos.photo[i].id + '_' + data.photos.photo[i].secret + '_b.jpg';
if (i < 20)
console.log(linkThumb);
//console.log(linkFull);
var title = data.photos.photo[i].title;
var blocktype = ((i % 3) == 2) ? 'c' : ((i % 3) == 1) ? 'b' : 'a';
output += '<div class="ui-block-' + blocktype + '">';
output += '<a href="#showphoto" data-transition="fade" onclick="showPhoto(\'' + linkFull + '\',\'' + title + '\')">';
output += '<img src="' + linkThumb + '_q.jpg" alt="' + title + '" />';
output += '</a>';
output += '</div>';
};
$('#photolist').html(output);
}
Then finally this function show the full screen view of the image. When the user taps on the thumbnail a larger image is taken and shown.
function showPhoto (link, title) {
var output = '<a href="#photos" data-transition="fade">';
output += '<img src="' + link + '_b.jpg" alt="' + title + '" />';
output += '</a>';
$('#myphoto').html(output);
}
My problem is that, i get the JSON object with the images by calling the API. i have console.log() where i output the json object and i checked all the image info is there. But when i go to the grid view and even the full view i get the default image that states that the This image or video is currently unavailable. I can't figure out what im doing wrong here.. Please help.
You may be requesting an image size that flickr does not have for that image. You are appending "_s", "_q" and "_b" to select a few sizes - so perhaps those are not available. You can check the flickr API 'photos.getSizes' to see what sizes are available. The Flickr API seems to be pretty inconvenient sometimes.
https://www.flickr.com/services/api/flickr.photos.getSizes.html

First a tag created in a Javascript loop not implemented

I am trying to populate a div (class='thumb") with thumnailpictures. The name of the pictures is gathered from an xml file. Every thumnail picture is encapsulated with an a-tag that points to a function to show the full picture.
On some browsers the first thumbnailpicture seems not to have this a-tag...clicking on it gives no action...
var rubriek = gup('rubriek'), // rubriek is a parameter in the url of this page pointing a specific photogallery
gallerij = rubriek + "gallery.xml",
xmlDoc = loadXMLDoc(gallerij),
x = xmlDoc.getElementsByTagName("filename"),
legebron = x[0].childNodes[0].nodeValue;
for (i = 0; i < x.length; i++) {
var beeldnummer = x[i].childNodes[0].nodeValue,
index = i + 1,
kleinbeeld = "/" + rubriek + "images/thumb/" + beeldnummer;
$('.thumb').append('<p><a class="kleintje" onclick="toonDezeFoto("' + beeldnummer + '",' + index + ',' + x.length + ');">
<img src="' + kleinbeeld + '" id="' + index + '">
</a></p>');
}
See http://www.karinedaelman.be/foto.php?rubriek=Mensen/
Found the solution: the z-index of the div that keeps the thumbnails was too low. Another div that has the site logo in it had a higher z-index and a width of 100%. Because of that the first thumbnail image was on a layer below the site logo and could not be accessed by the mouseevents....

jQuery/javaScript : images don't load

I have the following code:
all_images = new Array(Array);
$.get('../dotclear-files/themes/biblio/js/dynamic_ajax_php.php', function(data) {
var w = 0;
$(data).find('image').each(function() {
if (!all_images[w]) all_images[w] = new Array();
all_images[w]['url'] = $(this).find('url').text() + '#comments';
all_images[w]['src'] = $(this).find('src').text();
all_images[w]['title'] = $(this).find('title').text();
all_images[w]['width'] = $(this).find('width').text();
all_images[w]['height'] = $(this).find('height').text();
w = w + 1;
});
$("#carousel-comments").append('<ul></ul>');
for (x=0; x<3; x++) {
$('#carousel-comments ul')
.append('<li>')
.append('<a href="' + all_images[x]['url'] + '#comments" title="' + all_images[x]['title'] + '">')
.append('<img alt="' + all_images[x]['title'] + '" class="jcarousel-img jcarousel-img-' + x + '" width="' + all_images[x]['width'] + 'px" height="' + all_images[x]['width'] +'px" />')
.append('</a>')
.append('</li>');
var img = new Image();
$(img)
.load(function() {
$('.jcarousel-img-' + x)
.attr({'src': all_images[x]['src'], 'alt': all_images[x]['title']})
.fadeIn();
})
.attr('src', all_images[x]['src']);
}
$('#carousel-comments').jcarousel('reload');
}, 'xml');
The first part of this code loads images from a PHP script, that returns an XML file. This part works fine.
The issue comes with the 2nd part: $(img).load(...) It never displays my images.
This can be seen on my test page: it's the 3rd carousel, under the title named "C'est vous qui le dites!" We can see that the titles of the images are displayed... but the images themselves aren't loaded.
What am I doing wrong?
Thanx for any help!
I think you must append the <img> to the carousel.
$(img).appendTo($("#carousel-comments"));
Or something like this.
Edit after the comments exchange:
The element <IMG> in your LI are not the same that your var img = new Image. Then try something like this:
for (x=0; x<3; x++) {
var img = new Image();
img.load(function() {
$(this).fadeIn();
// Also, set your carousel here
});
img.attr('alt', all_images[x]['title'])
.attr('width', all_images[x]['width'])
.attr('height', all_images[x]['height'])
.addClass('jcarousel-img jcarousel-img-' + x)
.attr('src', all_images[x]['src']);
$('#carousel-comments ul')
.append('li')
.append('<a href="' + all_images[x]['url'] + '#comments" title="' + all_images[x]['title'] + '">')
.append(img);
}

Categories

Resources