Reputation: 2031
I am developing a simple drag and drop image upload option.
When I drag the image on the drag area it's showing me the uploaded image. That's good. Now, I drag multiple images at a time.
Using this JavaScript code I am Uploading Image:
function uploadFile(files) {
let url = 'process.php'
let formData = new FormData();
let allowedExt = ['jpg', 'jpeg', 'png', 'gif'];
for (const [key, value] of Object.entries(files)) {
let extension = value.name.split(".").pop();
if (allowedExt.includes(extension) == false) {
alert('Invalid file formate, we are only accepting ' + allowedExt.join(", ") + ' file formates');
return false;
}
formData.append('files[]', value);
previewFile(value, value.name);
}
fetch(url, {
method: 'POST',
body: formData,
})
.then((data) => {
console.log('Success');
})
.catch((error) => {
console.log(error);
})
}
For previewing the Image
function previewFile(file, fileName) {
let reader = new FileReader();
reader.readAsDataURL(file);
console.log( reader );
reader.onload = function () {
let html = '';
html += '<div class="col-md-4"><div class="item" id="item"><img src="' + reader.result + '" alt="" class="img-fluid filter-me"><span>' + fileName + '</span></div></div>';
loadImage.innerHTML += html;
// let filterMe = document.querySelector('.filter-me').src;
// console.log(filterMe);
// for( let i =0; i < filterMe.length; i++) {
// console.log( filterMe[i]);
// // filterMe[i].addEventListener( 'click', function () {
// // console.log( this );
// // localStorage.setItem("imgData", this.src);
// // });
// }
}
reader.onloadend = function () {
let filterMe = document.querySelector(".filter-me");
filterMe.addEventListener("click", function () {
console.log( this );
});
}
}
Now, on this function you can see I want to see this this
value using console.log( this );
But it's showing me first upload image this
value not other images when I click on other images :(
Upvotes: 0
Views: 487
Reputation: 1294
The main problem is that you are using document.querySelector(".filter-me");
, which returns the first element that matches the selector .filter-me
You need to use document.querySelectorAll(".filter-me");
which will return a nodeList of all elements that match.
Then you can iterate through them adding your event listener, something like:
const filterElements = document.querySelectorAll(".filter-me");
filterElements.forEach(function(filterMe){
// do your stuff
})
The problem here is if you then drop another image you will add more listeners to the first lot. So you will need to identify the ones that you have already added listeners to, for instance by adding a class filterMe.classList.add('listener-added')
. Then all you have to do is make sure that they don't get selected, so change the selector to .filter-me:not(.listener-added)
Upvotes: 0
Reputation: 506
querySelector returns only the first element of the selector type. so i would say that it is behaving correctly. You're applying the click event only to the first element.
You eventually want to use querySelectorAll and then cycle through all the elements.
let filterMe = document.querySelectorAll(".filter-me");
if (filterMe) {
for(const x of filterMe) {
x.addEventListener('click', function() {
console.log('image', this.src);
});
}
}
<html>
<body>
<img class="filter-me" src="img1.jpg" />
<img class="filter-me" src="img2.jpg" />
<img class="filter-me" src="img3.jpg" />
</body>
</html>
Upvotes: 3