Say I had the following three divs with unique ids on a page
<div id="product-id-001"></div>
<div id="product-id-002"></div>
<div id="product-id-003"></div>
What code would I need to add the following image elements based on the id of the div?
<div id="product-id-001">
<img src="images/product-id-001-1.jpg"></img>
<img src="images/product-id-001-2.jpg"></img>
<img src="images/product-id-001-3.jpg"></img>
</div>
<div id="product-id-002">
<img src="images/product-id-002-1.jpg"></img>
<img src="images/product-id-002-2.jpg"></img>
<img src="images/product-id-002-3.jpg"></img>
</div>
<div id="product-id-003">
<img src="images/product-id-003-1.jpg"></img>
<img src="images/product-id-003-2.jpg"></img>
<img src="images/product-id-003-3.jpg"></img>
</div>
Thanks for any tips.
$('div[id^=product]').each(function(index, elem) {
for(var i = 1; i < 4; i++) {
$('<img>', {
src: '/images/' + elem.id + i
}).appendTo(this);
}
});
Demo: http://www.jsfiddle.net/9S9Av/
(You need Firebug or another DOM inspector to see the result)
From the jQuery docs:
"The .append() method inserts the specified content as the last child of each element in the jQuery collection"
So:
$('#product-id-001").append('<img src="images/product-id-001-1.jpg"></img>');
etc...
// Select all elements with an id beginning with product-id:
var $productContainers = $('[id^=product-id]');
// Loop through the matched elements and append the images:
$productContainers.each(function () {
var $this = $(this),
productId = $this.attr('id'),
numImages = 3,
extension = '.jpg';
// Create and append the images based on the configuration above. Note that this
// assumes that each product have three valid images.
for (var i = 1; i <= numImages; i++)
{
var $image = $('<img alt="" />').attr('src', 'images/'+productId+'-'+i+extension);
$image.appendTo($this);
}
});
Related
I'm working on a system that puts all images inside paragraph-tags, as such:
<p>
<img src="..." />
</p>
So I wrote a function to move the images out of the paragraph tags. It looks like this:
moveImagesOutOfPtags() {
let images = document.querySelectorAll('p > img');
Object.entries(images).forEach(entry => {
let value = entry[1];
if( value.parentNode.nodeName === 'P' || value.parentNode.nodeName === 'p' ){
value.parentNode.outerHTML = value.parentNode.innerHTML;
}
});
}
But it doesn't work if there are two images inside the same p-tag, as such:
<p>
<img src="..." />
<img src="..." />
</p>
... Since the parent is removed/rewritten/overwritten with the value.parentNode.outerHTML = ...-line, for the first image. So when it gets to the second image in that p-tag, then it throws the error:
Failed to set the 'outerHTML' property on 'Element': This element has no parent node.
Any suggestions on a good way to solve this?
This is easy to achieve with DOM manipulating methods instead of setting HTML strings, like this:
function moveImagesOutOfPtags() {
let images = document.querySelectorAll('p > img');
images.forEach(img => {
const parent = img.parentElement;
// Insert the image as a previous sibling to the paragraph
parent.parentElement.insertBefore(img, parent);
if (parent.children.length === 0) {
// Remove the empty paragraph
parent.remove();
}
});
}
moveImagesOutOfPtags();
<p>
<img src="...">
<img src="...">
</p>
<p>
<img src="...">
</p>
You don't have to check the parent, since the query will select the images wrapped in a paragraph only, just insert the image as a previous sibling of the parent. Then check if the parent is empty, and remove if needed.
use id for every paragraph-tags and check the previously modified id with current one . i don't think this is the best way but this will let the job done.
html contents
<p id = "p_id_1">
<img src="..." />
<img src="..." />
</p>
<p id = "p_id_2">
<img src="..." />
<img src="..." />
</p>
script will be
moveImagesOutOfPtags() {
let images = document.querySelectorAll('p > img');
var p_id='';
Object.entries(images).forEach(entry => {
let value = entry[1];
if(p_id != value.parentNode.id && (value.parentNode.nodeName === 'P' || value.parentNode.nodeName === 'p' )){
value.parentNode.outerHTML = value.parentNode.innerHTML;
p_id = value.parentNode.id;
}
});
}
You could just catch the error and not carry on like this:
Try this:
moveImagesOutOfPtags() {
document.querySelectorAll('p > img').forEach(entry => {
const value = entry && entry[0]; // catches error if p has been replaced and doesn't continue.
if(value){ // you don't have to test if parent is p tag, you've already determined that with your direct child selector p > img
value.parentNode.outerHTML = value.parentNode.innerHTML;
}
});
}
I have this code:
<div class="main_flex">
<div class="flex_items">
</div>
<div class="flex_items">
</div>
<div class="flex_items">
</div>
</div>
javascript:
function shoe_images () {
for (var i = 0; i < shoes.length; i++){
var getFlexItems = document.querySelector('.flex_items');
var createImgTag = document.createElement('img');
createImgTag.src = shoes[i].imageUrl;
getFlexItems.appendChild(createImgTag);
}
};
And i have an array of object with different images. I want to add different images to the
class="flex_items"
How do i do that? I used a for loop, but all the images shows in the first class="flex_items".
The problem is in the querySelector() method. This method return only the first element. It is the reason for this.
See: https://www.w3schools.com/jsref/met_document_queryselector.asp
You need to use querySelectorAll()
See: https://www.w3schools.com/jsref/met_document_queryselectorall.asp
Rewrited your code:
function shoe_images () {
var getFlexItems = document.querySelectorAll('.flex_items');
for (var i = 0; i < shoes.length; i++){
var createImgTag = document.createElement('img');
createImgTag.src = shoes[i].imageUrl;
getFlexItems[i].appendChild(createImgTag);
}
you can do this by css or by js
this for CSS
.flex_items:nth-of-type(2) {
background: #ff0000;
}
.flex_items:nth-of-type(1) {
background: #324445;
}
to used js
var elements = document.getElementsByClassName('flex_items');
it will return arry contain 3 elment [0,1,2]
elements[0].innerHTML ='<img src="path">';
elements[1].innerHTML ='<img src="path">';
You can select the flex_items then append the element image like this:
const images = [{
src: "https://picsum.photos/id/284/200/300"
}, {
src: "https://picsum.photos/id/284/200/300"
}, {
src: "https://picsum.photos/id/284/200/300"
}]
document.querySelectorAll(".flex_items").forEach((el, index) => {
const image = document.createElement("img");
image.setAttribute("src", images[index].src);
el.appendChild(image);
})
<div class="main_flex">
<div class="flex_items">
</div>
<div class="flex_items">
</div>
<div class="flex_items">
</div>
</div>
I need some help with the click event, I'm trying to have an individual counter that is incremented by the click event that I have on the img. I've tried many variations, I want to resolve this without using jQuery.
<script async>
var count = 0;
var clickerCount = document.getElementsByClassName('clicker');
var cat = {
count : 0,
counter: function(){
this.count++;
clickerCount.textContent = "Kitten Click Count :" + this.count;
console.log("counter function working");
console.log(cat.count);
}
};
function modifyNum(){
cat.counter();
console.log("modifyNum function working");
}
</script>
</head>
<body>
<div style="display:inline">
<div>
<img src="http://placekitten.com/200/296" id="cat0" onclick="modifyNum();">
<p id='clicker'>Kitten Click Count :</p>
</div>
<div>
<img src="http://placekitten.com/200/296" id='cat1' onclick="modifyNum();">
<p id='clicker'>Kitten Click Count :</p>
</div>
</div>
For a start, you are using id='clicker' in two places (IDs are supposed to be unique), and then using document.getElementsByClassName, which returns nothing because you used an ID and not a class.
Once you do change it to a class, document.getElementsByClassName will return an array of elements. You'll have to use clickerCount[0] and so on, or loop through the array.
This example should work. I've separated the HTML from the Javascript because it looks clearer for me. You can use it as an example to expand / create your own in your own way.
Hope it help
HTML:
<div style="display:inline">
<div>
<img src="http://placekitten.com/200/296" id="1" class="countable">
<span>Kitten Click Count :</span><span id="counter-for-1">0</span>
</div>
<div>
<img src="http://placekitten.com/200/296" id="2" class="countable">
<span>Kitten Click Count :</span><span id="counter-for-2">0</span>
</div>
</div>
JS:
var imagesCountable = document.getElementsByClassName("countable");
var counters = [];
for (var i = 0; i < imagesCountable.length; i++) {
counters[imagesCountable[i].id] = 0;
imagesCountable[i].onclick = function(e) {
document.getElementById("counter-for-" + e.currentTarget.id)
.innerHTML = ++counters[e.currentTarget.id];
}
}
var imagesCountable = document.getElementsByClassName("countable");
var counters = [];
for (var i = 0; i < imagesCountable.length; i++) {
counters[imagesCountable[i].id] = 0;
imagesCountable[i].onclick = function(e) {
var cElem = document.getElementById("counter-for-" + e.currentTarget.id);
cElem.innerHTML = ++counters[e.currentTarget.id];
}
}
<div style="display:inline">
<div>
<img src="http://placekitten.com/200/296" id="1" class="countable">
<span>Kitten Click Count :</span><span id="counter-for-1">0</span>
</div>
<div>
<img src="http://placekitten.com/200/296" id="2" class="countable">
<span>Kitten Click Count :</span><span id="counter-for-2">0</span>
</div>
</div>
I have solved this problem in this JSFiddle!
If you can hardcode the IDs then it's easier in my point o view to just manipulate things by ID.
<div>
<img src="http://placekitten.com/200/296" id="cat0" onclick="counter(0);">
<p id='clicker0'>Kitten Click Count :</p>
<input type="hidden" id="counter0" value="0">
</div>
function counter(id) {
var cnt = parseInt(document.getElementById("counter" + id).value);
cnt++;
document.getElementById("counter" + id).value = cnt;
document.getElementById('clicker' + id).innerHTML = 'Kitten Click Count :' + cnt;
}
It's not the same approach but I find it easy to understand.
Hope it helps.
Ok, so first off you have two elements with the id of 'clicker'. You probably meant for those to be classes and ids. So when you call modifynum() it cant locate those because the class doesn't exists. Second, your JS is loading before your HTML elements. So when the JS gets to this line:
var clickerCount = document.getElementsByClassName('clicker');
It is going to find nothing, even if you correct the class names. So you want to move your JS to the footer of your HTML document, or wrap the code in a method that is called on pageLoad().
I think that should take care of it. Your object, for the most part, looks correct.
I'm creating 4 divs and adding 4 images in to each div.
var divid = ["aa","bb","cc","dd"],
imgid = ["a.png","b.png","c.png","d.png"];
for(var i = 0; i < divid.length;i++ ){
document.write('<div id="'+divid[i]+'" class="divCl"><input type="image" src="'+imgid[i]+'" class="imgCl"/></div>');
}
css:-
.divCl{
/*display: none;*/
}
.imgCl{
width: 100px;
height: 100px;
}
Why isn't the css applying? also is it ok to use this method to create divs and add images?
Well, document.write will overwrite the entire contents of the DOM once the document is loaded so you should not use this. You should instead use document.getElementById to select the parent element where you want to insert the images and then set the .innerHTML of that element to the new images. Here is an example:
HTML
<div id="imgParent"></div>
JS
var divid = ["aa","bb","cc","dd"],
imgid = ["a.png","b.png","c.png","d.png"];
var imgs = '';
for(var i = 0; i < divid.length;i++ ){
imgs += '<div id="'+divid[i]+'" class="divCl"><input type="image" src="'+imgid[i]+'" class="imgCl"/></div>';
}
var parent = document.getElementById('imgParent');
parent.innerHTML = imgs;
Output HTML
<div id="imgParent">
<div id="aa">
<input type="image" src="a.png" class="imgCl" />
</div>
<div id="bb>
<input type="image" src="b.png" class="imgCl" />
</div>
...
</div>
There is a syntax error.
Your arrays elements are not strings. The elements are variables not defined. I used jQuery to append each div to the body.
var divid = ['aa','bb','cc','dd'],
imgid = ['a','b','c','d'];
for(var i = 0; i < divid.length; i++ ) {
var str = $('<div id="'+ divid[i] +'" class="divCl"><input type="image" src="'+ imgid[i] +'" class="imgCl"/></div>');
$('body').append(str);
}
https://jsfiddle.net/hjepjnk3/
Going the document.write route will cause your CSS (and everything else) to be overwritten. A better way would be to create a container div and place the new div's in there
var divid = ["aa","bb","cc","dd"],
imgid = ["a.png","b.png","c.png","d.png"];
for(var i = 0; i < divid.length;i++ ){
document.getElementById('containerDiv').innerHTML += '<div id="'+divid[i]+'" class="divCl"><input type="image" src="'+imgid[i]+'" class="imgCl"/></div>'
}
You could also just add it directly to the body by doing
document.getElementsByTagName('body')[0].innerHTML
i have an retrieved array items in the var test,
for example :
var test = img;
Where test[0] holds the value that is grabbed from database as /images/gallery/1.jpp
Now i need to place the var test[0] to be place within img src="" and a href="", so how can i achieve this?
Assign a value to the property "id" of your img and play with its attributes.
<img src="" id="image_id_here" width="300" height="400">
<script>document.getElementById('image_id_here').setAttribute('src', test[0]);</script>
Assumptions made:
"test" is an array of strings
You demand working through a client-sided scripting language such as Javascript to perform front-end operations.
you need a div tag with the id of container:
<div id="container"></div>
You can then use javascript to iterate over the list:
var imgs = "";
for (var i = 0; i < test.length; i++) {
var img = document.createElement('img');
img.setAttribute('src', test[i]);
imgs += img.outerHTML;
}
var container = document.getElementById('container');
container.innerHTML = imgs;
See plunker