jquery append 'x' number images elements applying 'x' to src and class - javascript

I have a directory with 590 pictures and my issue is being able to pull images using jquery alone from that directory and appending them which i have found out can not be done alone using jquery/javascript. alternatively i have renamed the pictures 1.jpg,2.jpg ... 590.jpg . how using jquery can i append 590 images to a div leaving me with the number of the appended element applied to the src being 'lq'+numberofappended+'.jpg' and class being 'image-'+numberofappended
as a result leaving me with the below
<div class="imagecontainer">
<img src="lq/1.jpg" class="image-1"/>
<img src="lq/2.jpg" class="image-2"/>
<img src="lq/3.jpg" class="image-3"/>
...
<img src="lq/590.jpg" class="image-590"/>
</div>
if what I have will be too extensive can i append 50 images at a time and apply a jquery pagination loading another 50 each time i reach the end of the page.
I personally know how to use append in jquery but I don't know how to individually append an image and depending on which append number it is applying it to the src and class.

Make an array of the image html.
var imgs=[];
for( i=1; i<= 590; i++){
imgs.push('<img src="lq/'+i+'/.jpg" class="image-'+i+'"/>')
}
Now you can add them all with:
$('.imagecontainer').html(imgs.join(''));
Or you could stagger loading them based on whatever works best in your UI( scroll event for example). Use slice() to get parts of the array to use for append()
Add first 50:
var first50= imgs.slice(0,50);
$('.imagecontainer').html(first50.join(''));

Here you go; store the images in an array, join them and append all at once.
var images = [];
for (var i = 1; i <= 50; i++) {
images.push('<img src="lq/'+i+'.jpg" class="image-'+i+'"/>');
}
$('.imagecontainer').append(images.join('\n'));

A for loop should do the trick,
var images = "";
for (var i = 1; i <= 5; i++) {
images += '<img src="lq/'+i+'.jpg" class="image-'+i+'"/>'
}
$('.imagecontainer').append(images);
Output
<div class="imagecontainer">
<img src="lq/1.jpg" class="image-1">
<img src="lq/2.jpg" class="image-2">
<img src="lq/3.jpg" class="image-3">
<img src="lq/4.jpg" class="image-4">
<img src="lq/5.jpg" class="image-5">
</div>
DEMO

Related

Javascript native .remove() does not work on HTMLCollection. Javascript Bug?

I'm simply trying to iterate through an HTMLCollection (images inside a div) with a simple for loop. I use the children() method to get the images, and the item() method to get the specific image. Although the console shows me each image element (that I am logging), using remove() on each element isn't working. It does not remove all images.
I've tried using array indexes, removeChild() method, but it's the same problem: so I guess the problem lies on the HTMLCollection capacity?
var imgs = document.getElementByID('box').children;
for (var i = 0; i < imgs.length; i++) {
var e = imgs.item(i);
console.log(e)
document.getElementByID('box').removeChild(e)
}
}
HTML markup:
<div id="box">
<img src="images/1.jpg" alt="">
<img src="images/2.jpg" alt="">
<img src="images/3.jpg" alt="">
</div>
I expect that every element will be removed from #box, but the second image element stays in place. I don't really grasp why.
HTMLCollection is not an array, it is a live list of DOM elements. Therefore your loop goes like this:
1st round:
imgs = 1.jpg, 2.jpg, 3.jpg
removeChild(imgs[0]) removes 1.jpg
2nd round:
imgs = 2.jpg, 3.jpg
removeChild(imgs[1]) removes 3.jpg
3rd round:
imgs = 2.jpg
removeChild(imgs[2]) removes undefined, does nothing
The simple fix is to loop through the array in reverse:
for (var i = imgs.length-1; i >= 0; i--) ...
I would loop through all childNodes of the div[id="box"] and remove them accordingly.
Check out the code sample:
document.querySelectorAll('#box img')
.forEach(node => {
// do some additional checks, if needed
node.remove();
});
<div id="box">
<img src="images/1.jpg" alt="">
<img src="images/2.jpg" alt="">
<img src="images/3.jpg" alt="">
</div>
You are using removeChild(), not remove().
A solution to your problem would be this:
let imgs = document.getElementById('box').children();
imgs.forEach(img => img.remove());
The first problem you have is document.getElementByID - the correct method is .getElementById - lowercase d in the end.
Second, your loop will miss some elements. If you do a for loop and start removing elements, then the length of the collection also changes. What happens (in pseudo representation):
loop start
index = 0;
collection = [1, 2, 3];
remove item 0;
index = 1;
collection = [2, 3];
remove item 1;
index = 2;
collection = [2];
remove item 3; //error
You can loop in reverse from the end to the beginning but it's easier to use forEach which guarantees you go over each element in the initial array:
document.getElementById("remove").addEventListener("click", removeImages)
function removeImages() {
var imgs = document.getElementById('box').children;
[...imgs].forEach(img => img.remove());
}
<div id="box">
<img src="images/1.jpg" alt="">
<img src="images/2.jpg" alt="">
<img src="images/3.jpg" alt="">
</div>
<button id="remove">Remove all</button>

Parse image from json string

I need to get all my images (for futher converting to canvas) from plain json string...
For example i can have in json string:
<p>someText</p>
<img src="">
or
asdasdasasd
asdasdasd
asd <img class="asd" src="123">
and i use it so:
var html = $.parseHTML(someString)
**
.children('img')
.find('img')
but those functions didn't work(
How can i get all my img objects from this html? So, that i can further use it with drawImage (canvas)
is it possible?
upd
via ajax i get, for example, such data:
<p>someText</p>
<img src="">
or
asdasdasasd
asdasdasd
asd <img class="asd" src="123">
or
<h3><p>someText <img src=""></p><h3>
etc...
and somehow i need to convert this string to a 'virtual' DOM, where i can get images (and other elements too) and manipulate with them with jQuery. Like i can fetch images for my window-object: $('img') - this will fetch all images from page body. And i need something similar for my string. So, that i can use this images with jQuery.
You are getting an array after the parseHTML function. I think, you should traverse it and look that if it is an image, get it and add $(array_element).
After this process, you will get a Jquery object that can use attr(), find() etc. functions.
var k = '<p>sosmeT22ext2</p><img class="c" src="empty"><img class="empty" src="123">';
var html = $.parseHTML(k);
for(var i = 0; i < html.length; i++){
if(html[i] instanceof HTMLImageElement){
console.log($(html[i]).attr("src")); // all jquery functions works on $(html[i])
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Update
Above code doesn't work in nested dom html. Because it just traverse in one level as you see. Below code is more complicated beacuse it is a recursive method. My suggestion is that, if your dom is not nested use the first code block, it is not use the recursive method to extract and use your images.
var k = '<div><p>s133o4s3meT232ext2</p><img class="c" src="empty"><img class="empty" src="123"></div>';
var html = $.parseHTML(k);
var images_arr = [];
get_child_nodes(html);
console.log(images_arr[1].attr("src"));
function get_child_nodes(html_l){
for(var i = 0; i < html_l.length; i++){
if(html_l[i] instanceof HTMLImageElement){
images_arr.push($(html_l[i]));
}
else {
for(var j = 0; j < html_l[i].childNodes.length; j++){
get_child_nodes($(html_l[i].childNodes[j]));
}
}
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Adding to my comment, found the actual solution for your Problem:
> $('<p>someText</p><img src="">').filter('img')
[img]
The problem is that your HTML does not have a child which can be an img, but one of the root elements is, filter takes the root elements into account.
Compare (bad/worse but finds nested):
> $('<div><p>someText</p><img src=""></div>').find('img')
> $('<div></div>').append($('<p>someText</p><img src="">')).find('img')
Solution that always works, combining the selectors find and filter without creating an extra root element:
> $('<p>someText</p><img src=""><div><img></div>').filter('img')
[img]
> $('<p>someText</p><img src=""><div><img></div>').find('img')
[img]
> h = $('<p>someText</p><img src=""><div><img></div>')
[p, img, div]
> h.find('img').add(h.filter('img'))
[img, img]

Change only one character of all img src of a class using javascript

I want to change the src of all the images which are in the 'car-image' class.
But I do not have to change whole url. I just want to change one character.
I want edit this -
<div class="car-image">
<img src="/cars/3_large_1.png">
</div>
To this-
<div class="car-image">
<img src="/cars/3_large_2.png">
</div>
And this format is common in all the image in this class.
I tried something like this-
var allsrc = document.getElementsByClassName('car-image');
allsrc[0].src="/cars/3_large_2.png";
This is not working.
How can i do this in javascript?
you are setting src of wrong node allsrc returns your div not the image.
Try this
allsrc[0].childNodes[1].setAttribute("src","/cars/3_large_2.png")
A more elegant solution would be to use replace function with regex. If you know the image src pattern and similar changes apply to all image src, you can build a regex. In that case, instead of changing each image src one by one, you can iterate over the elements that contains car-image class and find out the first childNode and change the src attr.
// find all elements that contains class car-image
var carImgDivs = document.getElementsByClassName('car-image');
// iterate over carImgDivs and execute an imediate function to just pass the
// childNode1 that is the image. Use replace function with regex to find out the
// changed image src value and set the changed src value to childNode1
for(var i = 0; i < carImgDivs.length; i++) (function(childNode1) {
if(childNode1) {
var replacedSrc = childNode1.getAttribute('src').replace(/(_)(\d)/, "$12");
childNode1.setAttribute("src", replacedSrc);
}
})(carImgDivs[i].childNodes[1]);
For a image src like /cars/3_large_1.png, the regular expression (_)(\d) matches a underscore that follows a digit and captures both. The $1 in replace string "$12" says to keep the first capture group(underscore) as it is and 2 says to replace the second capture group(a digit) with 2. Basically, the regex matches with _1 in the above image src. _ is the first capture group and 1 is the second capture group. So, in the end, the image src gets changed to /cars/3_large_2.png
I want to change the src of all the images which are in the
'car-image' class using javascript.
You can change <img> src for all car-image classes like this:
var all = document.getElementsByClassName('car-image');
for(var i = 0; i < all.length; i++){
var image = document.getElementsByClassName('car-image')[i].getElementsByTagName('img');
image[0].setAttribute("src", "/cars/3_large_2.png");
}
<div class="car-image">
<img src="/cars/3_large_1.png">
</div>
<div class="car-image">
<img src="/cars/5_large_1.png">
</div>
<div class="car-image">
<img src="/cars/7_large_1.png">
</div>
<div class="car-image">
<img src="/cars/9_large_1.png">
</div>
(Inspect elements and see new src's)
If you include jquery in your page you can do
$(".car-image img").attr("src", "/cars/3_large_2.png");
Use(jQuery solution) : $( "img:nth-child(1)" ).attr('src', <new_name>);
The nth-child(i) means ith image.
Example:
$(".car_image img:nth-child(1)").attr('src', '/cars/3_large_2.png');
To change all the images just remove the :nth-child()
What about this
var x = document.getElementsByClassName('car-image')[0];
var img = x.getElementsByTagName('img')[0];
img.src = "/cars/3_large_2.png";

Using javascript to change width of multiple images with same id

I have a page with multiple images with the same id, I want to use javascript to size each of these depending on their original size. It only seems to check the first instance of the image and not the others, is there any way to get this working on all images?
<img id="myImg" src="compman.gif" width="100" height="98">
<img id="myImg" src="compman.gif" width="49" height="98">
<p id="demo"></p>
<button onclick="myFunction()">Try it</button>
<script>
<script>
var x = document.getElementById("myImg").width;
var yourImg = document.getElementById('myImg');
if(x < 50) {
yourImg.style.height = '100px';
yourImg.style.width = '200px';
}
</script>
The reason this isnt working is that getElementById is intended to find and return a single element with that Unique element Id. If you have two elements with the same Id, only the first is returned.
So to start off with you would need to make sure that your images share a common class, instead of the same Id, like so:
<img class="myImg" src="compman.gif" width="100" height="98">
<img class="myImg" src="compman.gif" width="49" height="98">
Then instead of using document.getElementById you should use document.querySelectorAll() which will return all elements which match the selector (as a NodeList). document.querySelectorAll on MDN
Then you can turn the NodeList returned by querySelectorAll into a normal array of images using Array#slice Array#slice on MDN.
Once done then you can itterate over each of the images (Array#forEach) and set their width/height if appropriate
So here is a possible solution for what you need to do, with comments:
var images = document.querySelectorAll('.myImg'), // Fetch all images wih the 'myImg' class
imageArray = Array.prototype.slice.call(images); // Use Array.prototype.slice.call to convert the NodeList to an array
imageArray.forEach(function (img) { // Now itterate over each image in the array
if (img.width < 50) { // If the width is less than 50
img.style.setAttribute('height', '100px'); // Set the height and width
img.style.setAttribute('width', '200px');
}
});
You will also need to make sure that the code will be executed, if you are using jQuery, put the code above in an document ready function, or if you are going to use the button which you currently have. Then put the javascript above into the myFunction function your buttons onclick event would call.
Change your id to class since id is unique for each element.
Then to change everything in the class do something like
function change(x) {
elements = document.getElementsByClassName(x);
for (var i = 0; i < elements.length; i++) {
elements[i].style.width ="100px";
}
}

Can you do a loop to change array size depending on the number of photos in a file in javascript/php?

Sorry for the question isn't very clear, basically
I have got the php code to search for photos in the directory based on the userId given in the url. So if the userId = 1, it will go to Photos/1 and get all the photos in that directory and output it into an array that I can use in Javascript. It works.
I have an external javascript to my php/html code.
I am changing the attr of the div's to display the photos. I have 5 "photo containers" in the array called photodisplay:
var photodisplay =
[
$("#photo1"),
$("#photo2"),
$("#photo3"),
$("#photo4"),
$("#photo5"),
];
Then I have a loop to change the attribute/img src:
function preloadingPhotos() {
for (var x=0; x<galleryarray.length; x++)
{
photodisplay[x].attr("src", "Photos/" + userid + "/" + galleryarray[x]);
console.log("preloaded photos");
}
displayPhoto();
}
It works. Providing no more than 5 photos because that is how many photocontainers I have. But what if I had photos? The question is: Would I be able to do a loop to keep changing the photos in the photodisplay array?
I also have code for the photocontainers to fade in and out:
function displayPhoto(){
photodisplay[0].fadeIn(3000);
photodisplay[0].delay(3000).fadeOut(3000, function() { //first callback func
photodisplay[1].fadeIn(3000);
photodisplay[1].delay(3000).fadeOut(3000, function() { //second callback func
photodisplay[2].fadeIn(3000);
photodisplay[2].delay(3000).fadeOut(3000, function() { //third callback func
photodisplay[3].fadeIn(3000);
photodisplay[3].delay(3000).fadeOut(3000, function() { // fourth callback func
photodisplay[4].fadeIn(3000);
photodisplay[4].delay(3000).fadeOut(3000, function() {
setTimeout(displayPhoto(), 3000);
});
});
});
});
});
}// end of function displayPhoto
Which requires me to manually enter the number of the array of the photodisplay.
I would thinking of adding more to the array with duplications of the photocontainers. But I don't think that would work since I would have to manually enter the number of the array in the code above to make it fade in and out.
Sorry if this is confusing. I tried my best to explain my problem. I hope someone can help. Don't worry about the retrieving images in the directory part, because it works. It increases the array of photos accordingly, I just don't know how to adjust this change with my javascript.
The method you are using, does not scale as you have a callback function for every element in your slideshow.
What you should do, is put all images in a list (or a list of div's) and hide them all / change the z-index so that only the active one shows. The you can loop through your elements using .next() on the list items to get the next one (or the first one if .next().length is 0).
This will clean up your code and is pretty easy to do yourself but there are also loads of jQuery plugins that do it for you.
You need a little bit of abstraction here. So instead of manually code numbers, try another approach. For this example I've used jQuery; since you've tagged your question with it, I assume it's okay:
// Set a default value and store the current photo in it.
var currentPhoto = 0;
// Calculate the total number of photos
var photoTotal = photodisplay.length;
var photoTimeout = false;
// Create a function to go to the next photo
var nextPhoto = function () {
// Keep track of the new current
currentPhoto = (currentPhoto + 1) % photoTotal;
// Just to be sure clearTimeout
clearTimeout(photoTimeout);
// Fadein each photo; you might want to do something to reset the style
photodisplay[0].fadeIn({
duration: 3000,
complete: function () {
photoTimeout = setTimeout(nextPhoto, 3000);
}
});
}
nextPhoto();
You don't want to define JS from the backend like that; just have PHP render the markup, then use JS to query and parse the markup for the presentational layer.
Let's assume your markup looks like this:
<div id="photocontainers">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<!-- A hidden array of images. -->
<div id="images">
<img src="http://placehold.it/100x100&text=1" />
<img src="http://placehold.it/100x100&text=2" />
<img src="http://placehold.it/100x100&text=3" />
<img src="http://placehold.it/100x100&text=4" />
<img src="http://placehold.it/100x100&text=5" />
<img src="http://placehold.it/100x100&text=6" />
<img src="http://placehold.it/100x100&text=7" />
<img src="http://placehold.it/100x100&text=8" />
<img src="http://placehold.it/100x100&text=9" />
<img src="http://placehold.it/100x100&text=10" />
<img src="http://placehold.it/100x100&text=11" />
</div>
So your server renders this; #images is just a hidden container, that basically preloads all the image assets you'll cycle between in #photocontainers.
var cycleImages = function() {
// Cache selectors that we'll need.
var $photoContainers = $('#photocontainers').children(),
$images = $('#images img'),
// Use `.data()` to get the starting point, or set to 0
// (if this is the first time the function ran).
startImage = $images.data('nextImage') || 0;
// Loop from the starting point, filling up the number of
// photocontainers in the DOM.
for (var i = startImage; i < startImage + $photoContainers.length; i++) {
var $targetImage = $images.eq(i % $images.length),
$targetPhotoContainer = $photoContainers.eq(i - startImage);
// Get rid of the current contents.
$targetPhotoContainer.empty();
// Clone the desired image, and append it into place.
$targetImage.clone().appendTo($targetPhotoContainer).fadeOut(0).fadeIn();
}
// Let's figure out which starting image is next up, and store that
// with `.data()`.
var nextImage = startImage + $photoContainers.length;
if (nextImage >= $images.length) {
nextImage -= $images.length;
}
$images.data('nextImage', nextImage);
}
// When the DOM is ready, call the method, then
// call it again however often you'd like.
$(document).ready(function() {
cycleImages();
setInterval(function() {
cycleImages();
}, 3000);
});
Here's a plunkr showing that in action: http://plnkr.co/SumqkXYpRXcOqEhAPOHm

Categories