How can I remove elements from prepend() by click close button? - javascript

I have an interface where images is being showed by .prepend() method, I am trying to remove images one by one by click on close button and also remove all the images by one click on a button, but I have no idea how to do ?
Here is image list interface below, 3 images show as of now How can I attach close button and remove images individual and also on 1 click.
HTML:
<div id="imageList">
</div>
JS:
//Images are stored in this array as base64
var imagesBase64 = [];
// add images in the array ImagesBase64
function addToDownload() {
imagesBase64.push(dataURL);
appendImageToList(dataURL);
}
const imageList = document.getElementById("imageList");
function appendImageToList(image) {
var img = document.createElement("img");
img.src = image;
imageList.prepend(img);
}

I crafted a demo that does more or less what you asked (but using jQuery).
The page gets initialized with a list of pictures hardcoded in an array. Each picture gets appended in #imageList inside its own container and a little red box is added to trap the click event when you mean to remove the picture from the list. On top of that there's a button to remove all of them at once:
//a list of img urls needed to feed the list of pictures with some
const images = ['https://www.w3schools.com/css/img_5terre.jpg', 'https://www.w3schools.com/css/img_forest.jpg', 'https://www.w3schools.com/css/img_lights.jpg', 'https://www.w3schools.com/css/img_mountains.jpg'];
//inits the imageList with pictures coming from images constant
//..so when the document is ready,
$(document).ready(() => {
//for each url picture in the images constant
images.forEach((o, i) => {
//append a picture to imageList having that url
appendImageToList(o);
});
});
//appends an image to the list (where image is a picture url)
function appendImageToList(image) {
var img = document.createElement("img");
img.src = image;
//the img will be enclosed in a container
let container = $('<div>', {
class: 'imgContainer'
});
container.append(img);
//creates the close handle for this new picture and adds an event handler on its click event
let closeHandle = $('<div>', {
class: 'closeHandle'
});
//adds content x to the close handle
closeHandle.append('<i class="fa-solid fa-circle-xmark"></i>');
closeHandle.click(() => {
//when the button is clicked, remove this image from the list
removeOneImageFromList($(event.target).closest('.imgContainer'));
});
container.append(closeHandle);
//adds the container inside the imageList
$('#imageList').prepend(container);
}
//removes all images from the list
function removeAllImages() {
$('#imageList .imgContainer').remove();
}
//removes a specific image from the list
function removeOneImageFromList(imgParentElement) {
$(imgParentElement).remove();
}
/* rule to style every single img container */
#imageList .imgContainer {
position: relative;
width: fit-content;
}
/* rule to style the close handle */
#imageList .closeHandle {
position: absolute;
top: 15px;
right: 15px;
text-align: center;
cursor: pointer;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-3.6.0.slim.js"></script>
<button type="button" onclick="removeAllImages();">Remove all images</button>
<br><br>
<div id="imageList">
</div>

Related

Elements lose javascript functionality after cloning

The following is the code. What I have done is made an item (the first one) and when i hover on its button, its background color changes to red and so on.
What I did next is cloned the element and appended it to a new div. The html (elements having same classes) is the same but the mouseover event doesn't work anymore.
My question is that why it did not work and how can I fix it? Also I tried to do the same by copying inner HTML to the new element but it is the same everytime.
const colorDiv = document.querySelector(".color-div");
const button = document.querySelector("button");
const mainContainer = document.querySelector(".main-container");
button.addEventListener("mouseover", function() {
colorDiv.style.backgroundColor = "red";
});
button.addEventListener("mouseout", function() {
colorDiv.style.backgroundColor = "seagreen";
});
const newItem = mainContainer.cloneNode(true);
document.querySelector(".new-container").appendChild(newItem);
.color-div {
height: 300px;
width: 300px;
background-color: seagreen;
margin: 10px;
padding: 10px;
transition: all .3s;
}
<!-- I will copy the div with main container class -->
<div class="main-container">
<div class="color-div">Hello</div>
<button>Change</button>
</div>
<!-- and append copied item to the following item -->
<div class="new-container"></div>
Events are not cloned, here's a quick fix:
const colorDiv = document.querySelector(".color-div");
const button = document.querySelector("button");
const mainContainer = document.querySelector(".main-container");
// If someone clicks on anywhere on the website THAT IS A BUTTON, then change the color.
document.addEventListener("mouseover", function(e) {
if (e.target.matches("button")) {
colorDiv.style.backgroundColor = "red";
}
});
document.addEventListener("mouseout", function(e) {
if (e.target.matches("button")) {
colorDiv.style.backgroundColor = "seagreen";
}
});
const newItem = mainContainer.cloneNode(true);
document.querySelector(".new-container").appendChild(newItem);
This should work for every clone.

I am looking to mouseover in javascript where the event is attached to a paragraph, but it will change the style of a different element

I have 8 pics containing paragraphs all with the class .pic-link (i used the paragraph as the link because it's z-index has to remain the highest). There is a div underneath the pic which is orginally styled in css for a shaded effect, it's class is .shade..
I want to mouseover .pic-link but change .shade to make it's background = "white"...i think i can do this in css like this- .pic-link:hover:shade, but i want to know it for javascript.. this is my attempt
var shade = document.querySelector(".shade");
var pic = document.querySelectorAll(".pic-
link");
for (var i = 0; i < pic.length; i++) {
pic[i].addEventListener("mouseover",
function(event) {
shade.style.background = "white";
})
}
i know i will have to add mouseout, i'm just looking for the logic..my code will add the mouseover for every pic, but doesnt match the style change to the pic that's hovered over... i even tried selecting all .shade class and writing
shade[i].style.background = "white" but that is even less affective.
EDIT...HTML as followed...
<div class="single-pic-container">
<div class="shade"></div>
<img src="./images/mobile/image-deep-earth.jpg" alt="picture of earth" class="pic mobile-pic">
<img src="./images/desktop/image-deep-earth.jpg" alt="picture of earth" class="pic desktop-pic">
<a href="#" class="pic-link"><p>
Deep <br> earth
</p></a>
</div>
one image is set to dislpay = "none"; until media queries.
and the container div .single-pic-container is display = "grid", so i could easily overlay the paragraph.
Plus i'm practicing grid.
You should use backgroundColor instead of background:
const pics = document.querySelectorAll('.pic-link');
const mouseOverHandler = (e) => { // e - it's an event.
// e.currentTarget - it's an access to an element-source of the event.
const shade = e.currentTarget.parentNode.querySelector('.shade');
shade.style.backgroundColor = '#ffffff';
};
const mouseOutHandler = (e) => {
const shade = e.currentTarget.parentNode.querySelector('.shade');
shade.style.backgroundColor = 'transparent'; // Set there background color as it was before
};
pics.forEach((pic) => {
pic.addEventListener('mouseover', mouseOverHandler);
pic.addEventListener('mouseout', mouseOutHandler);
});
If elements will be destroyed, you have to remove listeners, to avoid of memory leaks. So use as event listeners functions with names only. Because anonymous functions can not be removed in expression like pic.removeEventListener('mouseover', function(e) { //... }).

How to select a new added element and edit it?

I have an <a> element:
<a id='addNewElementk' onclick='//Some Js Code' class='continueButton'>Click To Add</a>
When this anchor is clicked , A new element added:
New Added Element
And the first anchor which was clicked , Is removed.
I want to select that new element.
I tried:
window.onload = function(){
var newElem = document.getElementsByClassName('continueButton')[1];
alert(newElem.innerHTML);
}
I'm using ('continueButton')[1] , As there is another input with the same class before that anchor.
But for sure I get Click To Add from the first one , As that's was found when the page is loaded.
So how can I select that new element?
You're attempting to select the element before it exists in the DOM.
You instead need to run that code within the click event handler of the first <a>, like this:
window.onload = function() {
document.querySelector('#addNewElementk').addEventListener('click', function(e) {
e.preventDefault();
var a = document.createElement('a');
a.textContent = 'New Added Element';
a.href = '#';
a.classList.add('continueButton');
a.addEventListener('click', function(e) {
console.log(a.innerHTML);
});
this.parentNode.insertBefore(a, this);
this.remove();
});
}
<a id='addNewElementk' href="#" class='continueButton'>Click To Add</a>
Note the use of addEventListener() over the outdated on* event attributes which should be avoided.
You are attempting to select on an element that doesn't exist in the DOM. Dynamically added elements can be accessed in a couple of ways, above someone has an answer that adds an event listener to the created element which is a solid solution. The other most common way would be to use event delegation (if you are familiar with jQuery that would be $(parentElement).on('action', 'elementWeWantToWatch', function)) in Vanilla js the pattern is effectively the same, find or make a container element for your dynamic html, then add a listener to that container. Inside the listener you will want to ensure the target matches whatever your dynamic selection would be and execute when you find a match.
In this Example
The event listener is initiated on page load to watch the container element. The listener watches for clicks on elements with the continueButton class and when it finds one it removes the clicked element and adds a new element (the counter is to demonstrate that new content is being displayed :D)
(function() {
let i = 1;
const makeButton = () => {
const a = document.createElement('a');
a.classList.add('continueButton');
a.href = '#';
a.textContent = `Button ${i}`
i++;
return a;
}
const init = () => {
const container = document.querySelector('.test');
container.addEventListener('click', e => {
if (e.target.classList.contains('continueButton')) {
let button = makeButton();
container.appendChild(button);
container.removeChild(e.target);
return;
}
});
};
if (document.readyState == 'loading') {
window.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})()
.test {
width: 100%;
display: block;
text-align: center;
}
.continueButton {
display: block;
color: white;
background-color: green;
border-radius 2px;
padding: 15px 30px;
line-height: 2;
margin: 50px auto;
width: 200px;
text-decoration: none
}
<section class="test">
<a id='addNewElementk' class='continueButton'>Click To Add</a>
</section>

Remove dynamically added checkboxes and corresponding images

I have a button which opens a file selector window. When the user selects a file, the script uploads that image to a div with a checkbox.
This is the part of the script that removes the checkbox and image, but it is currently removing the parent element as well.
$("#imageForm").on('click', 'input[value="Delete"]', function () {
$('#iso_preview').has('input:checkbox:checked').remove()
});
How can I remove all checked checkboxes and their corresponding images when the delete button is clicked?
jsFiddle
You need to alter your insert fileUpload() function so that the image is contained within the inner wrapper. Change the following lines
if (imageType.test(file.type)) {
fileTemp = document.createElement("img");
$("#iso_preview").append("<div class='ct'><input value='remove'type='checkbox'/></div>");
fileTemp.classList.add("preview_image");
} else{
fileTemp = document.createElement('div');
fileTemp.classList.add('div');
}
fileTemp.file = file;
$('#'+preview).append(fileTemp);
To this...
var container = $("<div class='ct'><input value='remove'type='checkbox'/></div>");
if (imageType.test(file.type)) {
fileTemp = document.createElement("img");
fileTemp.classList.add("preview_image");
} else{
fileTemp = document.createElement('div');
fileTemp.classList.add('div');
}
fileTemp.file = file;
container.append(fileTemp);
$("#iso_preview").append(container);
Then you need to make a slight modification in this line
$('#iso_preview').has('input:checkbox:checked').remove();
To select #iso_preview div instead of #iso_preview
$('#iso_preview div').has('input:checkbox:checked').remove();
This will remove any div elements containing a checked checkbox that is contained within #iso_preview
(Demo)

Having text show on mouseover

So I'm trying to have a background image disappear and then have some text appear in the div with a link. I've gotten the image to disappear on mouseover but I can't get the text to display. Here is what I've got so far. I'm kinda new to this stuff.
/* I'm have the image removed with the first line, then setting the link
as hidden then trying to make it visible, but the link never shows */
$('#res').mouseover(function(){
$(this).removeClass('resume');
$('#reslink').css(visibility,visible);
});
HTML:
<div id = "res" class = "floatleft squares resume"><a id = "reslin" class = "link" href="resume.php">link</a></div>
<div id = "pro" class = "floatleft squares projects"><a id = "prolin" class = "link" href="projects.php"></a></div>
<div id = "con" class = "floatleft squares contact"><a id = "conlin" class = "link" href="contact.php"></a></div>
<div id = "abo" class = "floatleft squares about"><a id = "abolin" class = "link" href="about.php"></a></a></div>
Styles:
a{
display: block;
background: grey;
height: 100%;
width: 100%;
visibility: hidden;
}
If any more info is needed, lmk, thanks.
Instead of
$('#reslink').css(visibility,visible)
try
$('#reslin').css('visibility','visible')
Maybe it's just a typo: #reslink or #reslin?
Your id on the anchor is "reslin" not "reslink"
Try this:
$('#reslin').css("visibility", "visible");
or
$('#reslin').css("display", "block");

Categories

Resources