Append child <img> to <a> in JavaScript [duplicate] - javascript

This question already has answers here:
How to append an element before another using Javascript?
(3 answers)
Closed 1 year ago.
Here is my code:
let a = document.createElement('a');
a.role = "menuitem";
a.tabindex = "-1";
a.href = "#";
a.onclick = function() {reloadPageWithChanges()};
a.innerHTML = stories["Chapter1"];
let img = document.createElement('img');
img.src = `pictures/cars/car1.png`;
img.style.marginRight = "3px";
img.style.marginLeft = "3px";
a.appendChild(img);
body.appendChild(a);
What this code does is that it creates a link that onclick reloads the page (with some small changes in the UI). This link contains the name (stories["Chapter1"]) and a picture next to it. However, this picture is always positioned on the right side from the text. I want it to be placed on the left side, so that all of these links (if there is more of them) have pictures left aligned. Is there any way to do that, using JavaScript's DOM?

You can use a.prepend(img); instead of a.appendChild(img);
let a = document.createElement('a');
a.role = "menuitem";
a.tabindex = "-1";
a.href = "#";
a.onclick = function() {
//reloadPageWithChanges()
};
a.innerHTML = "myChapter"; //stories["Chapter1"];
let img = document.createElement('img');
img.src = `pictures/cars/car1.png`;
img.style.marginRight = "3px";
img.style.marginLeft = "3px";
a.prepend(img);
document.body.appendChild(a);

Related

Add a span element within a link to make it accessible (AA) with javascript

I'm trying to modify a plugin in order to make it more modern and accessible. The problem is the icon: I need to add a span element with some text to make it readable but not visible.
My javascript is the following:
function _createInformationLink(linkText, linkHref) {
var infoLink = document.createElement('a');
_setElementText(infoLink, linkText);
infoLink.href = linkHref;
infoLink.target = '_blank';
infoLink.style.marginLeft = '8px';
return infoLink;
}
I tried to add a line in order to inject the html with .innerHTML like that:
function _createInformationLink(linkText, linkHref) {
var infoLink = document.createElement('a');
_setElementText(infoLink, linkText);
infoLink.href = linkHref;
infoLink.target = '_blank';
infoLink.style.marginLeft = '8px';
infoLink.innerHTML = "<span class='sr-only'>Close cookie policy</span>";
return infoLink;
}
But it didn't work. Any suggestion?
UPDATE:
The function _setElementText is the following:
function _setElementText(element, text) {
var supportsTextContent = 'textContent' in document.body;
if (supportsTextContent) {
element.textContent = text;
} else {
element.innerText = text;
}
}
You can generate the element then append it along with the text as such:
function _createInformationLink(linkText, linkHref) {
var infoLink = document.createElement('a');
_setElementText(infoLink, linkText);
infoLink.href = linkHref;
infoLink.target = '_blank';
infoLink.style.marginLeft = '8px';
var srSpan = document.createElement('span')
srSpan.innerText = 'Close cookie policy'
srSpan.classList.add('sr-only')
infoLink.appendChild(srSpan);
return infoLink;
}
Instead of .innerHTML maybe try using:
infoLink.classList.add('sr-only')

I need to add a third appendchild() inside a dom div

My goal is to have the appendChild(detail) appear after the appendChild(image) but it doesn't show up in the browser.
document.getElementById("myBtn2").addEventListener("click", hey);
function hey(){
for (i = 1; i < radio.length; i++){
f = radio[i].image ;
var item = document.createElement('div');
item.id = "box";
item.className = "dell";
item.style.height = "140px";
detail = document.createElement('div');
detail.className = "space";
image = document.createElement('img');
image.id = "pic";
image.className = "dell3";
image.setAttribute("src", f);
document.getElementById('case').appendChild(item).appendChild(image).appendChild(detail);
}
}
appendChild() returns the appended node. It's not chainable in the way that you think. In your code, item is appended to 'case', image to item and detail to image. Since image is an <img> element that should not have children, detail is not displayed.
The solution is to append each item separately to a document fragment, then append the document fragement to case.
var frag = document.createDocumentFragment();
var item = frag.appendChild(document.createElement('div'));
item.id = "box";
item.className = "dell";
item.style.height = "140px";
var detail = frag.appendChild(document.createElement('div'));
detail.className = "space";
var image = frag.appendChild(document.createElement('img'));
image.id = "pic";
image.className = "dell3";
image.setAttribute("src", f);
document.getElementById('case').appendChild(frag);
Note you probably want var keywords on the other variable assignments too as otherwise you'll create globals for each one implicitly. I've added these to the example changes I made. There are other optimisations you might want to make too, such as not doing the document.getElementById() lookup each time you loop (you can store it as a var outside of the loop).

item.appendChild is not a function

I know this is a very common error but I have read and read and can't figure it out why. It's probably something very easy but I can't solve it by myself.
var item = document.createElement("div").className = "item";
var img = document.createElement("img").src = imgpath + $(this).attr("href");;
item.appendChild(img);
Any help is appreciated!
EDIT:
var item = document.createElement("div");
item.className = "item";
var img = document.createElement("img");
img.src = imgpath + $(this).attr("href");
item.append(img);
This throws the same error.
In your case you are creating a div and assigns it a class name, and the same value(class name) is assigned to the item variable. So it is a string value which does not have the appendChild method.
var item = document.createElement("div");
item.className = "item";
var img = document.createElement("img");
img.src = imgpath + $(this).attr("href");;
item.appendChild(img);
The same concept applies to img also
Problem is here
document.createElement("div").className = "item"
it will return a string which won't have a method called appendChild on it. You don't have any reference to the created div.
You should be doing like this
var item = document.createElement("div");
item.className = "item";
var img = document.createElement("img");
img.src = imgpath + $(this).attr("href");
item.appendChild(img);
Because item is the string "item", not an element. You need to break it up.
var item = document.createElement("div");
item.className = "item";
Same thing needs to happen with the image.
document.createElement("div").className = "item"; returns a string, not a DOM node, so it knows nothing about .appendChild(). Try this instead:
var item = document.createElement("div");
item.className = "item";
var img = document.createElement("img");
img.src = imgpath + $(this).attr("href");
item.appendChild(img);

Updating an array on button click Javascript

This question may be a bit long winded but bear with me.
I am trying to update and array every time a user hits the save button.
When they click save an image of a canvas on the page is created.
These DataURI values are kept in an array.
Once the value is saved a thumbnail of sorts is created and added at the bottom of the screen.
Clicking the X icon on those images calls a function to remove the correct image from the array.
The images should then be redrawn with the update array values, thus removing it from the
screen.
I have included images to try and demonstrate:
Image #1 (when save is clicked and image added below):
http://postimg.org/image/cybazwydf/
Image #2 (after closing the on screen images, adding a new image adds the deleted ones again along with the new one):
http://postimg.org/image/gi5pcornl/
That is the issue, that it re-adds the deleted values.
I will post the code for it below:
function getDataUrl () {
var a = document.getElementById("theCanvas");
var context = a.getContext("2d");
var dataURL = a.toDataURL();
save(dataURL);
}
var theImages = new Array();
//Add dataURL to array:
function save(URL) {
theImages.push(URL);
var x = JSON.stringify(theImages);
localStorage.setItem('images', x);
drawImages(x);
}
function drawImages(array){
var array = localStorage.getItem("images");
array = JSON.parse(array);
//If an image is saved, display the saveArea div:
if (array.length > 0){
document.getElementById("saveArea").style.visibility="visible";
}
//Clear the elements that might already be in the div so they don't appear twice:
var theDiv = document.getElementById("saveArea");
while (theDiv.firstChild) {
theDiv.removeChild(theDiv.firstChild);
}
for (var x=0; x < array.length; x++){
//Create image for each value in array:
var divimg = document.createElement("div");
divimg.style.marginRight="10px";
//divimg.style.border = "1px dotted red";
divimg.className = "saveContainer";
divimg.style.width = 300+"px";
divimg.style.padding = 5+"px";
divimg.style.marginRight="10px";
divimg.style.height = 150+"px";
divimg.style.display="inline-block";
divimg.style.marginRight="35px";
document.getElementById("saveArea").appendChild(divimg);
var img = document.createElement("img");
img.src = array[x];
img.width = 300;
img.height = 150;
img.setAttribute("id", "theImageId");
img.style.marginRight="10px";
img.className = "saveImg";
//Add each image to the containing div:
divimg.appendChild(img);
//Create close button:
var close = document.createElement("img");
close.src="close.png";
close.width = 50;
close.height = 50;
close.border = 0;
close.style.position="relative";
close.style.bottom=115+"px";
close.style.right=40+"px";
close.className="closeButton";
//close.style.cssFloat="right";
//close.style.right= 0+"px";
var link = document.createElement("a");
link.href = "#";
link.appendChild(close);
link.nameIndex = x;
//WHEN THE USER CLICKS THE CLOSE ICON:
link.onclick = (function (x) {
var imageNum = this.nameIndex;
alert("You clicked to close image "+(imageNum+1));
//Remove the image:
array.splice(x,1);
alert("The length of this array is: "+array.length);
//Update localStorage:
localStorage.removeItem('images');
array = JSON.stringify(array);
localStorage.setItem('images', array);
drawImages(array);
} );
//Add the close button the the containing div:
divimg.appendChild(link);
//divimg.appendChild(close);
} //End Loop
} //End drawImages();
I've been trying to solve this for hours but no luck..
After removing the image from the array you are not storing it anywhere so the splice result is lost and the array remains the same
array.splice(x,1);
needs to be
array = array.splice(x,1);

Replacing an old image with a new one. JavaScript

I have a function that places an image provided by the input of the user into the body of an html page. When a second input is received I want to replace this picture with the new one. I have attempted to do just this in the below function.
function show_image(src, alt) {
var img = document.createElement("img");
img.src = src;
img.width = 400;
img.height = 300;
img.alt = alt;
var counter;
var mynodes= new Array();
mynodes.push(img);
counter+=1;
if(counter==1){
// This next line will just add it to the <body> tag
document.body.appendChild(img);
}
else if(counter!=1)
{
var newNode=mynodes[counter-1];
var oldNode=mynodes[counter-2];
document.body.replaceChild(newNode,oldNode);
}
The variable counter is a local variable.
Each time the method is called counter is initialized to 0.
Same thing with your mynodesvariable. It is always going to have only one node in the array.
So you may want to change your logic here. Do you want help rewriting this function?
Your code is totally awkward. As far as I can tell, you could simply change the same img tag instead of changing the whole node each time. There's barely a reason for a function..
Click here for a live demo.
function changeImg(img, src, alt) {
//I doubt you even need a function for this.
img.src = src;
img.alt = alt;
}
var img = document.createElement('img');
//you could just use a css class instead...
//that's probably better anyway...why does your js care how it looks?
img.width = 400;
img.height = 300;
document.body.appendChild(img);
changeImg(img, 'http://static.jsbin.com/images/favicon.png', 'image');
var imgSrcInput = document.getElementById('imgSrc');
var imgAltInput = document.getElementById('imgAlt');
var button = document.getElementById('change');
button.addEventListener('click', function() {
changeImg(img, imgSrcInput.value, imgAltInput.value);
});
I put together an object oriented example. This makes your logic very reusable and friendly. Check out the code in action here (click).
window.onload = function() { //usage
var someElement = document.getElementById('someIdHere');
var anotherElement = document.getElementById('anotherIdHere');
imageReplacer.setup({
element: someElement,
initSrc: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRg-icdkibfDt8VE7FkaKZyVUh8SBR4YTGd-2Jz1wZeUVacv4YD8zrvwclN',
initAlt: 'Starting Image'
});
imageReplacer.setup({
element: anotherIdHere,
initSrc: 'https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcRrHWuOzgYPbsuSF9cYQo3ORkcdIC4-8xaszlCrI3f7arAC7vhV7HwMN_fG',
initAlt: 'Starting Image'
});
};
var imageReplacer = { //package up your app
setup : function(options) {
//create a new imageReplacer so that each one will operate independently. The "this" pointer will refer to each element's imageReplacer.
options.element.imageReplacer = Object.create(imageReplacer);
options.element.imageReplacer.makeReplacer(options);
},
makeReplacer : function(options) {
options.element.className = 'imageReplacer';
var markup = this.createMarkup();
this.changeImage(options.initSrc, options.initAlt);
this.addClick(this.button);
options.element.appendChild(markup);
},
createMarkup : function() {
var frag = document.createDocumentFragment();
this.srcInput = document.createElement('input');
this.srcInput.type = 'text';
this.srcInput.placeholder = 'Image Source';
this.altInput = document.createElement('input');
this.altInput.type = 'text';
this.altInput.placeholder = 'Image Alt';
this.button = document.createElement('button');
this.button.textContent = 'Change Image';
this.imgTag = document.createElement('img');
frag.appendChild(this.srcInput);
frag.appendChild(this.altInput);
frag.appendChild(this.button);
frag.appendChild(this.imgTag);
return frag;
},
addClick : function(button) {
var that = this;
button.addEventListener('click', function() {
that.changeImage(that.srcInput, that.altInput);
});
},
changeImage : function(src, alt) {
this.imgTag.src = src;
this.imgTag.alt = alt;
}
};
Instead of creating a function to dynamically change the picture(which did work), I decided to hide one picture on my index.html file. And then changed the src with $("#my_image").attr("src","img/fire.gif"); #my_image being the id of the image tag.

Categories