How to load several images in the same place - javascript

I have created an html document that uses javascript to connect to xml and get the name of a picture to load using this CSS :
#container {
width:800px;
}
#left {
top:10%;
position: relative;
float: left;
width:200px;
left:30px;
}
#right {
position:absolute;
top: 0px;
right: 300px;
z-index:-1;
}
And this code:
var TestP = new Array();
function loadImg(n){
TestP[n] = xmlDoc.documentElement.childNodes[n].textContent;
var img = document.createElement('img');
alert(TestP[n]);
img.src = TestP[n];
alert(n);
alert(TestP[n]);
document.getElementById('right').appendChild(img);
A part of the HTML :
<li>Part 1</li>
The thing is when I first click on the link, everything works well, but when I click another time, I will get two images, each at a different position. I want to have the second image take the exact same place, beeing on top of the first one.

elem = document.getElementById( 'right' );
child = elem.firstChild;
if ( child )
elem.replaceChild( img, child );
else
elem.appendChild( img );

Sounds like you just want one image, of which you change the URL each time.
Define in your HTML:
<img id="image">
and use in JavaScript:
var TestP = []; // cleaner way for creating an array
function loadImg(n) {
TestP[n] = xmlDoc.documentElement.childNodes[n].textContent;
document.getElementById('image').src = TestP[n];
}
Also note that HTML5 introduces some semantics, one of which being binding event handlers through JavaScript instead of through HTML.

don't create a new image, but replace the src attribute.
first give the image an id, so you can find it:
<img id="myimage" src="..."/>
changing it goes like this:
document.getElementById("myimage").src = "...new source...";
another option:
var TestP = new Array();
function loadImg(n) {
TestP[n] = xmlDoc.documentElement.childNodes[n].textContent;
var myImage = document.getElementById("myimage");
if(myImage != null) {
myImage.parentNode.removeChild(myImage);
}
var img = document.createElement('img');
img.src = TestP[n];
img.id = "myimage";
document.getElementById('right').appendChild(img);
}

well, you are doing it with .appendChild(). then you call it again and it appends second child. so, you have two options. before you append the second image, remove the old one, OR, just replace it.

Related

Change Element href Right Before Drag

I'm creating an extension that allows me to drag photo links in some website that doesn't allow it. The element (photoCell) has a default href of "javascript://" and has a child element (photo) which holds the image.
I want to be able to change the href of the parent element to the src of the child image so when i drag, i drag the URL of the child image. (This works if i do it without a drag listener but then when i click on an element it loads the image and not the expected javascript function). So i need to change the href back to "javascript://" after drag is done.
However, even though the href changes the dragged URL still is "javascript://"
function dragstart() {
this.href = this.children[0].src;
}
function dragend() {
this.href = "javascript://";
}
function doForPicturedesk() {
var gallaryCells = document.getElementsByClassName("gallery-cell");
for (var i = 0; i < gallaryCells.length; i++) {
var gallaryCell = gallaryCells[i];
var photoCell = element.children[0];
photoCell.addEventListener("dragstart", dragstart);
photoCell.addEventListener("dragend",dragend);
}
}
Here's a sample of the HTML
<div class="gallery-cell jg-entry entry-visible" style="width: 534px; height: 345px; top: 10px; left: 10px;">
<a href="javascript://" onclick="openPictureDetail('343563491-516813675371465101')" class="gallery-cell__link gallery-cell__image--hoverable">
<img id="thumb_343563491-516813675371465101" class="gallery-cell__image " src="/bild-disp/diasdb/thumbnailextl.action?ref=343563491-516813675371465101&w=false" onerror="correctMissing(this, '343563491-516813675371465101');" style="width: 534px; height: 356px; margin-left: -267px; margin-top: -178px;">
</a>
</div>
enter code here
I didn't think was possible, but what do I know. All you have to do is use dataTransfer.setData to achieve your goal. Try it below:
let anchor = document.querySelector('a');
anchor.ondragstart = function(event) {
let urlWeWant = 'https://www.example.com';
event.dataTransfer.types.forEach(type => {
//Note that all you HAVE to do for this to work is:
//event.dataTransfer.setData(type, urlWeWant);
//BUT, I think checking the type and replace HTML is better
if (type.includes('html')) {
let clone = event.target.cloneNode(true);
clone.href = urlWeWant;
let dataHTML = clone.outerHTML
event.dataTransfer.setData(type, dataHTML);
} else {
event.dataTransfer.setData(type, urlWeWant);
};
});
};
<a href='javascript:void(0);'>Drag Me Into Another Window :)</a>

How to insert 200 photos to HTML <img> tags by not adding one by one

I have a situation that there is gallery with a few categories, and each have like 200 photos. What is best optional and simple way to handle that not adding one by one in HTML?
The website is based on HTML, CSS, and JavaScript, not WordPress.
For the fun since many answers are efficient.
Here is a loop of 200 looking at pictures from picsum and dispatching them in a grid:
galery = document.querySelector('#galery')
for (let i = 0; i < 200; i++) {
img = document.createElement('IMG')
img.src = 'https://picsum.photos/id/' + i * 4 + '/200/100'
img.setAttribute('alt', img.src)
img.classList.add('img')
galery.appendChild(img)
}
* {
box-sizing: border-box;
}
.img {
display: block;
min-width: 100%;
max-width:100%;
border: solid;
transition: 0.15s
}
div {
margin: auto;
padding: 4% 5px 0;
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-gap: 5px;
width: 1200px;
max-width: 80%;
}
.img:hover {
transform: scale(2);
}
<div id="galery"></div>
Solutions
Here are a few quick and easy-to-read ways of doing something like this:
Make sure to read the performance section at the bottom
Using a forEach() loop
// Images array holds the URLs/directories of the images
const urls = [
'https://images.unsplash.com/photo-1494548162494-384bba4ab999',
'https://images.unsplash.com/photo-1503803548695-c2a7b4a5b875',
'https://images.unsplash.com/photo-1500382017468-9049fed747ef'
]
// Get the element by id
const imagesSection = document.querySelector('#images')
// Loop all URLs
urls.forEach(url => {
// Insert the elements into the image section
images.innerHTML += `<img src="${url}" height="100">`
})
<!-- images container -->
<div id="images">
</div>
Using a for(... of ...) loop
// Images array holds the URLs/directories of the images
const urls = [
'https://images.unsplash.com/photo-1494548162494-384bba4ab999',
'https://images.unsplash.com/photo-1503803548695-c2a7b4a5b875',
'https://images.unsplash.com/photo-1500382017468-9049fed747ef'
]
// Get the element by id
const imagesSection = document.querySelector('#images')
// Loop through all URLs
for (url of urls) {
// Add images to imges section
imagesSection.innerHTML += `<img src="${url}" height="100" >`
}
<!-- images container -->
<div id="images">
</div>
Using a for() loop
// Images array holds the URLs/directories of the images
const urls = [
'https://images.unsplash.com/photo-1494548162494-384bba4ab999',
'https://images.unsplash.com/photo-1503803548695-c2a7b4a5b875',
'https://images.unsplash.com/photo-1500382017468-9049fed747ef'
]
// Get the element by id
const imagesSection = document.querySelector('#images')
// Loop through all URLs
for (let i = 0; i < urls.length; i++) {
// Get the current URL
const url = urls[i]
// Add images to the images section
imagesSection.innerHTML += `<img src="${url}" height="100" >`
}
<!-- images container -->
<div id="images">
</div>
Performance
Being that you are going to be adding many elements to the DOM you should not use innerHTML as I did in my code examples (I used it for readability and cleaner code). innerHTML will reparse and recreate all of the DOM elements in the div element. Instead, you would do something like this to create the img elements.
const urls = [
'https://images.unsplash.com/photo-1494548162494-384bba4ab999',
'https://images.unsplash.com/photo-1503803548695-c2a7b4a5b875',
'https://images.unsplash.com/photo-1500382017468-9049fed747ef'
]
// Get the element by id
const imagesSection = document.querySelector('#images')
// Loop through all URLs
urls.forEach(url => {
// Create image node
const img = document.createElement('img')
// Make src equal to the URL
img.setAttribute('src', url)
img.setAttribute('height', '100') // Ignore me (just makes images smaller)
// Append img node to image section
imagesSection.appendChild(img)
})
<div id="images">
</div>
Using JavaScript you can create HTML elements:
imgArr = // I am not sure if you're reading them from a file, etc. But we need an array of all the images src location
body = document.getElementById('imagelocation') // Where you want the img tags to be
for (let i = 0;i<imgArr.length;i++) {
newImg = document.createElement('IMG')
newImg.src = imgArr[i].url // Adds the src for the where the image is located
newImg.classList.add('styling') // Optional. We can add styling to the images, i.e., make them all of a uniform size
body.appendChild(newImg)
}
You can do that by naming all the images in your folder to img0.png,img1.png....img199.png(you can use a simple python code to rename your image) and then use the javascript code below to add them to the DOM by looping through them
<div><p id="photos" /></div>
<script>
var container=
document.getElementById("photos");
for (var i=0, len<200,i++) {
var img = new Image();
var imgname=“img”+i+”.png”;
img.src = imgname;
container.appendChild(img);}
</script>

JQuery append image not showing

For this code block
$(document).ready(() => {
for (let i = 0; i < 10; i++) {
$("#main").append(factory());
}
});
this will show the image:
function factory() {
return $('<image class="champ-icon rounded-circle" src="resources/irelia.jpg" />');
}
while this doesn't
function factory() {
let $champIcon = $(document.createElement("image"))
.addClass("champ-icon rounded-circle")
.attr("src", "resources/irelia.jpg");
return $champIcon;
}
I'm using Bootstrap 4 as well.
The page currently is just a static mock up. I want to dynamically build elements from data given to it by a local server.
I literally just messed around with HTML/CSS and jQuery over the weekend so I'm not sure what went wrong here. Shouldn't both function return the same jQuery object?
Thanks!
CSS class
.champ-icon {
width: 100px;
height: 100px;
}
Edit: creating it with normal javascript works as well.
function factory() {
let img = new Image();
img.src = "resources/irelia.jpg";
img.className = "champ-icon rounded-circle";
return img;
That's because you are trying to programmatically create <image> element in html, which... doesn't exist. To insert element on a page you should use <img src="">, not <image...>. Change this line
let $champIcon = $(document.createElement("image"))
to
let $champIcon = $(document.createElement("img"))
And it should work.

Image Swap on MouseOut (JavaScript, not JQ)

I am trying to create functions to mouseover and mouseout of images. The tricky part is this function needs to work for any image, and I cannot use direct image names. I have to therefore use variables.
The HTML code is as follows for the images:
The HTML for the images is like this, and there are 3 images:
<img src="images/h1.jpg" alt="" id="images/h4.jpg" onmouseover="swapToNewImage(this)" onmouseout="swapImageBack(this)">
I'm expecting that you have to reference the id for the new image, and then the src attribute for the previous image to revert when you mouseout.
The problem is that, if I reference the id attribute, the image no longer has information on the src attribute so I cannot call it to revert back.
Here is the JavaScript I have thus far. It works to swap the image to a new one, but not to swap it back :(
//FUNCTION
var $ = function (id) {
return document.getElementById(id);
}
//ONLOAD EVENT HANDLER
window.onload = function () {
//GET ALL IMG TAGS
var ulTree = $("image_rollovers");
var imgElements = ulTree.getElementsByTagName("img");
//PROCESS EACH IMAGE
//1. GET IMG TAG
for (var i = 0; i < imgElements.length; i++) {
console.log (imgElements[i]);
console.log (imgElements[i].getAttribute("src"));
//2. PRELOAD IMAGE FROM IMG TAG
var image = new Image();
image.setAttribute("src", imgElements[i].getAttribute("src"));
//3. Mouseover and Mouseout Functions Called
image.addEventListener("mouseover", swapToNewImage);
image.addEventListener("mouseout", swapImageBack);
}
}
//MOUSE EVENT FUNCTIONS
var swapToNewImage = function(img) {
var secondImage = img.getAttribute("id", "src");
img.src = secondImage;
}
var swapImageBack = function(img) {
var previousImage = img.getAttribute("src");
img.src = previousImage;
}
Let me know if you can help me figure out how to call the image's src attribute so it can be reverted back. Again, I cannot reference specific image names, because that would be a lot easier (: Thank you!
Well, You can use a data attribute to store your src, and a data attribute to store the image you want to swap when mouseover.
Please try the following example.
var swapToNewImage = function(img) {
var secondImage = img.dataset.swapSrc
img.src = secondImage;
}
var swapImageBack = function(img) {
var previousImage = img.dataset.src
img.src = previousImage;
}
<img src="https://images.pexels.com/photos/259803/pexels-photo-259803.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500" alt="" data-src="https://images.pexels.com/photos/259803/pexels-photo-259803.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500" data-swap-src="https://images.pexels.com/photos/416160/pexels-photo-416160.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500" onmouseover="swapToNewImage(this)" onmouseout="swapImageBack(this)">
I also notice that the image tag is generated by code, in order to set the dataset values, we can do this:
var image = new Image();
image.scr = [src]
image.dataset.src = [src]
image.dataset.swapSrc = [swap src]

Javascript – PNG not showing when adding dynamically

I’m a beginner JS coder and I’m struggling with the following – can anyone please help?
I’m trying to add a series of PNGs to a page using a function which will allow the placement of multiple copies of the same image and also assign a unique reference to each copy of the image.
The images are not showing in the page, plus the console.log() shows that the 2 images created by the code below both have the same position on the page.
var imgSrc = 'arrow_red.png';
function generateArrow(numArrows) {
var img = document.createElement('img');
img.src = imgSrc;
for (i = 1; i <= numArrows; i++) {
window['arrow'+i] = img;
}
}
generateArrow(2);
arrow1.style.position = 'absolute';
arrow1.style.top = '50px';
arrow1.style.left = '50px';
arrow2.style.position = 'absolute';
arrow2.style.top = '100px';
arrow2.style.left = '100px';
console.log(arrow1);
console.log(arrow2);
Why are the images not showing in the page and why does the console.log() show that the 2 images created are both using the same positional co-ordinates?
When you create a new element, it only exists in memory - - it hasn't been added to the document that the browser is currently rendering. So, it's not enough to create new elements and configure them. You must then inject them into the DOM with parentElement.appendChild(newChild).
Here's an example:
let newChild = document.createElement("img");
newChild.src = "https://static.scientificamerican.com/sciam/cache/file/D14B1C22-04F8-4FB4-95937D13A0B76545.jpg?w=590&h=393";
let parent = document.querySelector(".parent");
parent.appendChild(newChild); // <-- Now, inject the new element
img { width: 400px; }
<div class="parent"></div>
Now, in your particular case, you've got more issues than just this to work on. You are only creating a new image element one time because your line that does that is not inside of your loop. Also, the way you are referring to arrow1 and arrow2 in your code and with window['arrow' + i] indicates that you have img elements with ids already set up in your HTML, which is not an ideal approach. Next, it's much simpler to set up the CSS you'll want to work with as pre-made classes ahead of time, rather than setting up the CSS as inline styles in the script.
As my answer above indicates, you need to have a parent element that will contain the new element(s) that you create, so your solution would really look something like this:
var imgSrc = 'https://icon2.kisspng.com/20180320/rle/kisspng-arrow-computer-icons-clip-art-red-arrow-line-png-5ab19d059bfa98.5843437015215895096389.jpg';
// You can pick any pre-existing element to be the "parent"
var parent = document.getElementById("parent");
function generateArrow(numArrows) {
for (i = 1; i <= numArrows; i++) {
// The creation of the elementt and it's configuration
// need to be inside of the loop to make several of them
var img = document.createElement('img');
img.classList.add("position" + i); // Add pre-made CSS classes
img.src = imgSrc;
parent.appendChild(img); // Inject the new element inside of the parent
}
}
generateArrow(5);
/*
Instead of setting inline styles, use pre-made CSS classes
that you can just connect or disconnect to/from
*/
/* All the injected images get this: */
#parent > img { width:40px; position:absolute; }
/* These get assigned individually */
.position1 { top:50px; left:50px; }
.position2 { top:100px; left:100px; }
.position3 { top:150px; left:150px; }
.position4 { top:200px; left:200px; }
.position5 { top:250px; left:250px; }
<div id="parent"></div>
You usually add elements to DOM using document.appendChild(element);, or in your case: document.appendChild(img);. (Or any preferred parent instead of document)
Edit: removed second part addressing variable declaration, since I didn't notice the window["arrow" + i] = img.
You need to add the generated element to the DOM using the appendChild() method.
Furhermore you're actually just generating a single instance of the image because it's happening once outside of the for-loop. This is why the console shows identical screen positions for 'both' images because actually you're referring to the same image instance.
Try this:
function generateArrow(numArrows) {
var img;
for (i = 1; i <= numArrows; i++) {
img = document.createElement('img');
img.src = imgSrc;
document.body.appendChild(img);
window['arrow' + i] = img;
}
}

Categories

Resources