I load an image from URL by using document.createElement('img'). And a button triggers it. But, every time I click the button, it creates another img element instead of removing the current one. Can you help me to remove the current image so that there is always maximum one image displayed. Here is the code:
<script>
function() {
var imageUrl = document.getElementById('image-url').value;
var loadedImage = document.createElement('img');
loadedImage.src = imageUrl;
loadedImage.className = 'container';
document.getElementById('imagePlace').appendChild(loadedImage);
}
</script>
Every time you call appendChild method, you add a node to your document, so some changes to your code are required - you should check if the image node is already present and either create a new img element or replace the src attribute of the existing one.
<script>
function() {
// Get a new image url
var imageUrl = document.getElementById('image-url').value;
// Get a parent element
var parent = document.getElementById('imagePlace');
// Try to get an 'img' element that is inside '#imagePlace' node.
var currentImage = parent.querySelector('img');
// Check if there already is an image in the document.
if (currentImage) {
// If there is, replace its 'src' attribute with the new url.
currentImage.src = imageUrl;
}
else {
// If there is no image in the parent, create and add new image node.
var loadedImage = document.createElement('img');
loadedImage.src = imageUrl;
loadedImage.className = 'container';
parent.appendChild(loadedImage);
}
}
</script>
In other approach you may start with removing the img node if it's present in the #imagePlace container, however changing the src attribute is "cheaper" to perform.
<script>
function() {
// Get a new image url
var imageUrl = document.getElementById('image-url').value;
// Get a parent element
var parent = document.getElementById('imagePlace');
// Try to get an 'img' element that is inside '#imagePlace' node.
var currentImage = parent.querySelector('img');
// Check if there already is an image in the document.
if (currentImage) {
// If it's there, remove it.
currentImage.remove();
}
// Create and add new image node.
var loadedImage = document.createElement('img');
loadedImage.src = imageUrl;
loadedImage.className = 'container';
parent.appendChild(loadedImage);
}
</script>
Related
I am building a small web-tool where editors can write content by using buttons to add paragraphs and images. I store the elements with an id ((number of element) starting at 0 and incremented for every new element) and load with a button in order to a div "preview" where the content is supposed to be displayed as in the web page later on.
My issue is that, for a reason I don't understand, the image is always displayed below all the paragraphs instead of being in order. Presumably there is an easy fix, but I am very new to HTML, CSS and JS and couldn't find the solution online.
Sorry if this is a stupid mistake or the solution was already posted somewhere.
Javascript handling the preview rendering:
// Preview current document status
document.getElementById("previewButton").addEventListener("click", function() {
// Clear
document.getElementById("preview").innerHTML = "";
// Add all elements properly
var section = document.getElementById("preview");
var id = "preview";
for (var counter = 0; counter < element_counter; counter++) {
var type = document.getElementById(counter).nodeName;
// If text element
if (type === "TEXTAREA") {
var paragraph = document.createElement("p");
var text = document.getElementById(counter).value;
paragraph.setAttribute("id", id + counter);
paragraph.setAttribute("class", "flow-text");
paragraph.append(text);
section.appendChild(paragraph);
}
// If image element
if (type === "INPUT") {
var file = document.getElementById(counter).files[0];
var reader = new FileReader();
reader.onload = function(e) {
var image = document.createElement("img");
image.setAttribute("id", id + counter);
image.setAttribute("src", e.target.result);
image.setAttribute("class", "materialboxed responsive-img");
section.appendChild(image);
}
reader.readAsDataURL(file);
}
}
});
This might work. I can't test though without your code. However basically the principle at work is to isolate some of the vars so they represent distinct instantiations. And then immediately add the image element to the DOM. The reader.onload is expected to run asynchronously still.
enter code here if (type === "INPUT") {
(function() {
var file = document.getElementById(counter).files[0];
var reader = new FileReader();
var image = document.createElement("img");
image.setAttribute("id", id + counter);
image.setAttribute("class", "materialboxed responsive-img");
section.appendChild(image);
reader.onload = function(e) {
image.setAttribute("src", e.target.result);
}
reader.readAsDataURL(file);
}());
}
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]
I've looked at numerous other answers regarding this but haven't found a solution that has worked. I'm using a PHP page that contains some HTML code, with Javascript working some functions. Ideally I would select an image on the page, the image will become colored green as it is selected. I would then like to deselect the image and have it return to the original state. I can only get half-way there however. What am I missing? Is it something with post back?
Here's some code examples:
The HTML:<div onclick="changeImage(1)" id="toolDiv1"><img id="imgCh1" src="/images/Tooling/1.png"></div>
The Javascript function:
function changeImage(var i){
var img = document.getElementById("imgCh" + i + ".png");
if (img.src === "images/Tooling/" + i + ".png"){
img.src = "images/Tooling/" + i + "c.png";
}
else
{
img.src = "images/Tooling/" + i + ".png";
}
}`
The "1c.png" image is the one that is selected and should replace "1.png". There are multiple divs on this page that hold multiple images, which are named 2/2c, 3/3c, which is why the var i is included. Any insight? Thanks in advance.
You could do it something like this, it would also allow for different file names.
<img class="selectable" src="/images/Tooling/1.png"
data-original-source="/images/Tooling/1.png"
data-selected-source="/images/Tooling/1c.png">
<img class="selectable" src="/images/Tooling/2.png"
data-original-source="/images/Tooling/2.png"
data-selected-source="/images/Tooling/2c.png">
var images = document.getElementsByClassName('selectable');
for (var image of images) {
image.addEventListener('click', selectElementHandler);
}
function selectElementHandler(event) {
var image = event.target,
currentSrc = image.getAttribute('src'),
originalSrc = image.getAttribute('data-original-source'),
selectedSrc = image.getAttribute('data-selected-source'),
newSrc = currentSrc === originalSrc ? selectedSrc : originalSrc;
image.setAttribute('src', newSrc);
}
With comments:
// find all images with class "selectable"
var images = document.getElementsByClassName('selectable');
// add an event listener to each image that on click runs the "selectElementHandler" function
for (var image of images) {
image.addEventListener('click', selectElementHandler);
}
// the handler receives the event from the listener
function selectElementHandler(event) {
// the event contains lots of data, but we're only interested in which element was clicked (event.target)
var image = event.target,
currentSrc = image.getAttribute('src'),
originalSrc = image.getAttribute('data-original-source'),
selectedSrc = image.getAttribute('data-selected-source'),
// if the current src is the original one, set to selected
// if not we assume the current src is the selected one
// and we reset it to the original src
newSrc = currentSrc === originalSrc ? selectedSrc : originalSrc;
// actually set the new src for the image
image.setAttribute('src', newSrc);
}
Your problem is that javascript is returning the full path of the src (you can try alert(img.src); to verify this).
You could look up how to parse a file path to get the file name in javascript, if you want the most robust solution.
However, if you're sure that all your images will end in 'c.png', you could check for those last 5 characters, using a substring of the last 5 characters:
function changeImage(var i){
var img = document.getElementById("imgCh" + i);
if (img.src.substring(img.src.length - 5) === "c.png"){
img.src = "images/Tooling/" + i + ".png";
}
else
{
img.src = "images/Tooling/" + i + "c.png";
}
}
I've created a snippet to swap images between no underscore and '_1' in the source path when hovering and leaving the .hover()
Sometimes I see an issue whereby the next image I hover over get's the 'styled' image from the previous image i hovered over (this is inconsistent!) with '_1'?
I think it has to do with the speed at which you hover over the images.
I'm using $(this) to refer to the div the user is currently hovering over and maybe it's inconsistently storing the src for the img and referencing it too soon?
Please see below a video demonstrating my issue:
http://screencast.com/t/lJEDb5lyTXj5
PS: I don't have access to the source code - I am injecting this code onto the site, (So i can't manipulate the divs/images without JS)
<head>
<style>
.js div.result.product {
display: none;
}
</style>
<script>
$('html').addClass('js');
</script>
<script>
$( document ).ready(function() {
$('div.result.product').show();
});
</script>
</head>
<script>
console.log($('div.result-image').length);
// Function to set all images with _1 to no "_1".
$( "div.result-image > a > img" ).each(function() {
console.log('one image');
var styled = "_1";
var revertStyledOriginal = $(this).attr('src');
var preset = "?hei=245&qlt=85,1&wid=245&fmt=jpeg&resMode=bicub&op_sharpen=1";
// if the img is silo
var s = revertStyledOriginal;
// Only takes everything up until the "_"
unstyle = s.substring(0, s.indexOf('_'));
// add the preset back onto the src to make the img crisp
var unstyled = unstyle + preset;
// sets this instance of the image in the each loop to the "new link" with removed "_1"
$(this).attr('src', unstyled);
});
// Hover Function
$('div.result.product').hover(function myfunc() {
//Store 'this' as a reference to the current product image to be referred to when switching images
var selection = $(this);
$link = selection.find('img').attr('src');
$parsed = $link;
var styled = "_1";
var revertStyledOriginal = selection.find('img').attr('src');
var preset = "?hei=245&qlt=85,1&wid=245&fmt=jpeg&resMode=bicub&op_sharpen=1";
//if the img is silo
if(revertStyledOriginal.indexOf(styled) === -1 && ($link !== "http://www.kirklands.com/assets/HTML/MVS/AB_tests/NextPageButton/Next_Page_Buttons_Page_2.jpg"))
{
$preset = "?hei=245&qlt=85,1&wid=245&fmt=jpeg&resMode=bicub&op_sharpen=1";
//Need to remove preset to add _1 (then readd preset).
$removedPreset = $parsed.substring(0, $parsed.indexOf('?'));
var Unstyled = $removedPreset + $preset;
var Styled = $removedPreset + "_1" + $preset;
function checkImage(src) {
var img = new Image();
img.onload = function() {
// code to set the src on success
selection.find('img').attr('src', Styled)
//console.log('exists');
//console.log(revertStyledOriginal);
};
img.onerror = function() {
selection.find('img').attr('src', Unstyled)
console.log('doesnt exist');
//console.log();
};
img.src = src; // fires off loading of image
}
checkImage(Styled);
}
//if the img is styled
else {}
//$( this ).attr("src",);
},
//Function to reset the image on when you exit hover of img
function() {
$original = $(this).find('img').attr('src')
$removedPreset = $parsed.substring(0, $parsed.indexOf('?'));
$link = $removedPreset + $preset;
if ($original !== "http://www.kirklands.com/assets/HTML/MVS/AB_tests/NextPageButton/Next_Page_Buttons_Page_2.jpg") {
// set on hover image src to silo
$(this).find('img').attr('src', $link)
}
});
</script>
The following is my function that is called on click of a button.
The goal is to get the text value entered by the user and use it as an image source and finally display the image on the html body.
function ButtonClick() {
var link = document.createElement("a");
// create an image element.
var MyImg = document.createElement("img");
var MyImg.src = document.getElementById("textfield").value;
// append it to a list of elements.
link.appendChild(MyImg);
// append the newly added image to the html page body.
document.body.appendChild(link);
// clear textfield for next image src.
document.getElementById("textfield").value = "";
}
The error I receive is on line#7: "var MyImg.src = document.getElementById("textfield").value;"
SyntaxError: missing ; before statement example.js:19
*edited code after the fist suggestion.
MyImg.src = document.getElementById("textfield").value;
you should define variable once,
change
var MyImg = document.createElement("img");
var MyImg.src = document.getElementById("textfield").value;
to
var MyImg = document.createElement("img");
MyImg.src = document.getElementById("textfield").value;