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]
Related
I have looked at almost every question that has been asked here about htmlcollection.
So I have a div and I am fetching data and creating divs inside this div with ajax so they are not hardcoded.
this is how div look like before I fetch the data
<div id="tivvits"></div>
this is how div#tivvits looks like after I call function show_all_tivvits();
show_all_tivvits() is a function where I create a ajax request and create new divs
such as div#tivvit-21, div#tivvit-22, etc.
<div id="tivvits">
<div id="tivvit-19" class="grid-container">...</div>
<div id="tivvit-20" class="grid-container">...</div>
</div>
this is part of the js file
document.addEventListener("DOMContentLoaded", function(){
show_all_tivvits();
var t = document.getElementById('tivvits');
const j = t.getElementsByClassName("grid-container");
const k = Array.prototype.slice.call(j)
console.log(k);
for (var i = 0; i < k.length; i++) {
console.log(k[i]);
}
});
what I wanted to do in show_all_tivvits() function is I want to get the divs that are already in the div#tivvits and that way I am not gonna create them again but the problem is when I use console.log() to print out document.getElementById('tivvits').getElementsByClassName('grid-container') there are items in the htmlcollection but when I print out length it returns 0.
one more thing when I open inspect>source in chrome my index.php doesn't have updated div#tivvits.
I have tried almost every way to loop this htmlcollection but it is not working.
list of things I have tried;
Array.from(links)
Array.prototype.slice.call(links)
[].forEach.call(links, function (el) {...});
HTMLCollection.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
HTMLCollection.prototype.forEach = Array.prototype.forEach;
It's not really clear, but are you looking for something like this?
targets = document.querySelectorAll('#tivvits > .grid-container')
for (let target of targets)
{console.log(target.id)}
This should select all <div> nodes which are direct children of the <div id="tivvits"> node and have a class attribute with the value "grid-container", and extract from them the attribute value of the id attribute.
Have a go with this
I use the spread operator to allow the use of map on the HTMLCollection
window.addEventListener("load", function() {
const gridContainers = document.querySelectorAll("#tivvits .grid-container");
const ids = [...gridContainers].map(div => div.id);
console.log(ids)
});
<div id="tivvits">
<div id="tivvit-19" class="grid-container">...</div>
<div id="tivvit-20" class="grid-container">...</div>
</div>
To just display change
const ids = [...gridContainers].map(div => div.id);
to
[...gridContainers].forEach(div => console.log(div.id));
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";
I've got following HTML:
<span class="testClass1" >
wanted Text
<a class="ctx" href="#"></a>
</span>
Now I want to get the text "wanted Text".
How can I achieve this?
I tried with:
document.getElementsByClassName("testClass1");
I also tried with document.getElementsByTagName() but I don't know how to use them properly.
You can use querySelectorAll
hence:
document.querySelectorAll('.testclass1 a')
will return all the <a> items children of a .testclass1
Snippet example:
var elements = document.querySelectorAll('.testClass1 a')
console.log(elements) // open the console to see this
console.log(elements[0].text) // this gets the first <a> text `wanted Text`
<span class="testClass1" >
wanted Text
<a class="ctx" href="#"></a>
</span>
The getElementsByClassName() function returns an array of matching elements, so if you need to access them, you could do so using a loop :
// Get each of the elements that have the class "testClass1"
var elements = document.getElementsByClassName("testClass1");
// Iterate through each element that was found
for(var e = 0; e < elements.length; e++){
// Get the inner content via the innerHTML property
var content = elements[e].innerHTML;
}
If you need to actually access the <a> tags directly below some of the elements as your edit indicates, then you could potentially search for those wihtin each of your existing elements using the getElementsbyTagName() function :
// Get each of the elements that have the class "testClass1"
var elements = document.getElementsByClassName("testClass1");
// Iterate through each element that was found
for(var e = 0; e < elements.length; e++){
// Find the <a> elements below this element
var aElements = elements[e].getElementsByTagName('a');
// Iterate through them
for(var a = 0; a < aElements.length; a++){
// Access your element content through aElements[a].innerHTML here
}
}
You can also use an approach like squint's comment or Fred's which take advantage of the querySelectorAll() function as the getElementsByClassName() and getElementsByTagName() are better served when accessing multiple elements instead of one specifically.
Try this:
document.getElementsByClassName("testClass1")[0].getElementsByTagName('a')[0].innerText
var testClass1 = document.getElementsByClassName("testClass1");
console.log(testClass1[0].innerHTML);
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";
}
}
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