ondragstart on an array of elements dynamically in javascript - javascript

I have an array of image elements,
var im = ["im1","im2"]; // from db or local drive
Then creating the images dynamically as:
var l = imagelist.length;
for (var i = 0; i < l; ++i) {
if (i in im) {
var s = im[i];
var img = document.createElement("img");
img.src = s;
img.width = width;
img.draggable = true;
var body = document.getElementById("body");
body.appendChild(img);
this.addEventListener('ondragstart', function(event) {
alert(event.target.id);
event.dataTransfer.setData('text/plain', event.target.id);
});
}
While the ondragstart event fires, but alert(event.target.id); shows blank.
That's the reason, the drag and drop functionality is not working for an array of images created dynamically .
Although tried dragging with a single image tag <img> which works absolutely fine, but the array of images doesn't work in this way.
Any solution for this?

You haven't assigned an id to any of your elements.
Something like this should do the trick:
var img = document.createElement("img");
img.src = s;
img.id = "image_" + i;
// The rest of your assignments and code...

Related

I don't how why my backgroundImage doesn't work

Why does my banner doesn't change her background? Please help me.
When I run the file the console tells me:
Uncaught TypeError: flechedroite.addEventListener is not a function
I really don't understand. I'm a beginner in Javascript so please explain me with kind words how I can fix this error :)
var flechedroite = document.getElementsByClassName('fa-arrow-right');
var flechegauche = document.getElementsByClassName('switch-left');
var banner = document.getElementById('banner');
var images = [];
var changeBackground = function (bElement, bUrl) {
return bElement.style.backgroundImage = "url(" + bUrl + ")";
}
//image list
images[0] = 'images/image1.jpg';
images[1] = 'images/image2.jpg';
images[2] = 'images/image3.jpg';
flechedroite.addEventListener('click', function() {
for (var i = 0; i < images.length; i++) {
changeBackground(document.body, images[i]);
}
})
addEventListener should be called in window.onload or in $(document).ready()
Since getElementsByClassName returns an array, you need to use array index with flechedroite to add an event listener. i.e. flechedroite[0].addEventListener('click', function() {...});
You are calling changeBackground function in a loop to set the background image, effectively you will see only the last image from the array being set as background.
JS Code
var images = [];
var changeBackground = function (bElement, bUrl) {
return bElement.style.backgroundImage = "url("+bUrl+")";
}
//image list
images[0] = 'https://www.gettyimages.ie/gi-resources/images/Homepage/Hero/UK/CMS_Creative_164657191_Kingfisher.jpg';
images[1] = 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTOGUhZo0Qe81U5qY_Z-seXgsD79LEEet832TVOlLMOEy10ZPsV';
images[2] = 'https://cdn.pixabay.com/photo/2016/06/18/17/42/image-1465348_960_720.jpg';
window.onload = function(){
var flechedroite = document.getElementsByClassName('fa-arrow-right');
var flechegauche = document.getElementsByClassName('switch-left');
var banner = document.getElementById('banner');
var currentImageIndex = 0;
flechedroite[0].addEventListener('click', function() {
currentImageIndex = (currentImageIndex+1)%images.length;
changeBackground(document.body, images[currentImageIndex]);
})
}
The function getElementsByClassName returns a HTMLCollection, which is an array like structure that can contain multiple elements. So you need to use an index to access the elements contained in it.
So flechedroite.addEventListener results in an error but flechedroite[0].addEventListener should work
https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByClassName
if you use 'getElementsByClassName' and you want to add an 'addEventListener', you can not do it in a 'generic' way: "flechedroite.addEventListener ('click', function () {}". You have to do this for each element:
var flechedroite = document.getElementsByClassName('fa fa-arrow-right');
//flechedroite contains all the elements that have the 'fa fa-arrow-right' classes
//on each element you have to add the "addEventListener"
for (var i = 0; i < flechedroite.length; i++) {
flechedroite[i].addEventListener('click', function() {
alert('flechedroite');
});
}
basic example JSFiddle1
a more advanced example
JSFiddle2

Using a loop, but only one element is being added

I was working on some JavaScript and was trying to add things dynamically. Below is my code. My problem is that I am trying to add three "li" elements, attach "img" tags to it ans attaching the src dynamically. But it is attaching only the last image i.e in my code "bid_3" to all the "li". Help appreciated.
(function() {
var bxSlider = document.createElement("ul"); //created ul
bxSlider.setAttribute("class", "bxslider"); // gave a class name bxslider.
for (i = 1; i < 4; i++) {
var itemsList = document.createElement("li");
var linkImages = document.createElement("img");
linkImages.src = "images/bid_" + i + ".jpg";
itemsList.appendChild(linkImages);
}
bxSlider.appendChild(itemsList);
document.body.appendChild(bxSlider); //append everything to the body.
var ulNum = document.getElementsByTagName("ul");
alert(ulNum.length); // should return 1
var liNum = document.getElementsByTagName("li");
alert(liNum.length); // should return 3
var imgNum = document.getElementsByTagName("img");
alert(imgNum.length); //should return 3
//call the slider.
$(document).ready(function() {
$('.bxslider').bxSlider();
});
}());
PS:- I am not a JavaScript expert. Please forgive if my code is bad.
You're only attaching itemsList after you've passed through the loop. Try this:
// Before loop stuff...
for (i = 1; i < 4; i++) {
var itemsList = document.createElement("li");
var linkImages = document.createElement("img");
linkImages.src = "images/bid_" + i + ".jpg";
itemsList.appendChild(linkImages);
bxSlider.appendChild(itemsList);
}
// After loop stuff...

Setting a the background image of a div from an array

I have to make a div and set the background image from an array of images, and make a two buttons that will change the picture to the next image in the array, or the previous image of the array. I've been looking around stackoverflow and w3 schools, but I don't know why it's not working.
var backgroundImage = new Array();
backgroundImage[0] = "np.jpg";
backgroundImage[1] = "putin.png";
backgroundImage[2] = "fob.jpg";
function nextImage()
var img = document.getElementById(element);
for(var i = 0; i < backgroundImage.length;i++)
for(var i = 0; i < backgroundImage.length;i++) {
document.getElementById(element).src = [0].src;
document.style.backgroundImage="url(backgroundImage[0])";
}
You are not evaluating the array, you are creating a literal you want
document.style.backgroundImage="url(" + backgroundImage[0] + ")";

Passing image array values and changing image source onclick

OK, so finally the penny dropped (loud clunk!) on the click issue I was having here Append dynamic div just once and a JSFiddle issue. The code now shows user a choice of pics once per node clicked. Phew.
However, now my img.src=e.target.src line is having trouble accessing the other images in the array. Only the last image in the array will add to the table. I think this is because the allImages.onclick event should be inside the loop?
I have tried that and then img is showing up as undefined. I'm guessing that is because the loop (and therefore the function) is running before var img is declared? I think it is an issue with the order of things.
All help appreciated.
var makeChart = function () {
var table = document.createElement('table'),
taskName = document.getElementById('taskname').value,
header = document.createElement('th'),
numDays = document.getElementById('days').value, //columns
howOften = document.getElementById('times').value, //rows
row,
r,
col,
c;
var myImages = new Array();
myImages[0] = "http://www.olsug.org/wiki/images/9/95/Tux-small.png";
myImages[1] = "http://a2.twimg.com/profile_images/1139237954/just-logo_normal.png";
for (var i = 0; i < myImages.length; i++) {
var allImages = new Image();
allImages.src = myImages[i];
var my_div = document.createElement("div");
my_div.id = "showPics";
document.body.appendChild(my_div);
var newList = document.createElement("ul");
newList.appendChild(allImages);
my_div = document.getElementById("showPics");
my_div.appendChild(newList);
my_div.style.display = 'none';
}
header.innerHTML = taskName;
table.appendChild(header);
header.innerHTML = taskName;
table.appendChild(header);
function addImage(col) {
var img = new Image();
img.src = "http://cdn.sstatic.net/stackoverflow/img/tag-adobe.png";
col.appendChild(img);
img.onclick = function () {
my_div.style.display = 'block';
allImages.onclick = function (e) { // I THINK THIS IS THE PROBLEM
img.src = e.target.src;
my_div.style.display = 'none';
img.onclick=null;
};
}
}
for (r = 0; r < howOften; r++) {
row = table.insertRow(-1);
for (c = 0; c < numDays; c++) {
col = row.insertCell(-1);
addImage(col);
}
}
document.getElementById('holdTable').appendChild(table);
document.getElementById('createChart').onclick=null;
}
Well, the problem seems to stem from different parts. First of all,
for (var i = 0; i < myImages.length; i++) {
var allImages = new Image();
allImages.src = myImages[i];
var my_div = document.createElement("div");
my_div.id = "showPics";
document.body.appendChild(my_div);
var newList = document.createElement("ul");
newList.appendChild(allImages);
my_div = document.getElementById("showPics");
my_div.appendChild(newList);
my_div.style.display = 'none';
}
This loop creates a new div for EACH image in myImages, then appends a ul to that div, and finally appends the Image for the current image to the ul.
The question of what document.getElementById('showPics') returns, since there are as many divs with the id showPics appended to body as myImages.length, has a mystical magical answer which should never be spoken, or even thought, of again.
Why not do the sensible thing and create one singular happy div outside the loop? Append a single ul child to it, outside the loop. Then proceed to append as many li as you want in the loop.
var my_div = document.createElement('div');
my_div.id = 'showPics';
var newList = document.createElement('ul');
my_div.appendChild(newList);
for var i = 0; i < myImages.length; i++) {
...
var li = document.createElement('li');
li.appendChild(allImages);
newList.appendChild(li);
...
}
my_div.style.display = 'none';
Now, my_div is the one and only div containing the images. So, the click event handlers can toggle its visibility safely.
Second,
function addImage(col) {
var img = new Image();
img.src = "http://cdn.sstatic.net/stackoverflow/img/tag-adobe.png";
col.appendChild(img);
img.onclick = function () {
my_div.style.display = 'block';
allImages.onclick = function (e) { // I THINK THIS IS THE PROBLEM
img.src = e.target.src;
my_div.style.display = 'none';
img.onclick=null;
};
}
}
allImages references the same Image object now that you are out of the loop, which happens to be the last image in myImages. So, only the last image in myImages will register the handler to a click event. To solve this problem, we make a new variable.
var sel = null; //This comes before my_div
Now, we add the click handler to allImages inside the loop so that every image in myImages gets a piece of the pie, as they say.
for var i = 0; i < myImages.length; i++) {
var allImages = new Image();
allImages.src = myImages[i];
allImages.onclick = function (e) {
if(sel !== null) {
sel.src = e.target.src;
my_div.style.display = 'none';
sel.onclick=null;
sel = null;
}
};
...
}
And finally, adjust addImage so that sel can be set when the image is clicked.
function addImage(col) {
...
img.onclick = function () {
my_div.style.display = 'block';
sel = img;
}
...
}
That's all there is to it! Example.
Note that, if you comment out sel.onclick = null, you can change a particular cell's image as many times you like.
Your addImage() function makes a direct reference to the allImages variable. One problem is that since you were using (and reusing) that variable in a for loop earlier in the code it is only going to retain the last value that was assigned to it. So no matter how many times you call addImage() it's always adding the onclick function to the last image that allImages pointed to.
I'd also suggest renaming the allImages variable. That's a very misleading name because it in fact only ever represents a single image.
Hope that helps!

Accessing functions from within a Javascript Object (Javascript)

I am attempting to create a basic Hangman program. It's an array of tags which are assigned into an array of Objects (called Buttons). Each image is an image of a letter, so for example you would press the 'L' button, it would check whether this was in an WordArray (which is an array of chars), then it would act accordingly (to hide the letter, then update the gallows image if it needed to).
I cannot get the onclick method of the images to access the checkinarray function. What am i doing wrong?
var LetterAmount = 3; //make this 26. checked.
var WordArray = new Array();
var Buttons = new Array();
function checkinarray(num){
var z = 0;
while (z<4){
document.write("looping through word now");
if (num == WordArray[z]){
document.write("<br/>it is in the word");
}
z++;
}
}
function ButtonClicked(){
this.Image.src = "images/blank.jpg";
checkinarray(this.Number);
}
function Button(Image, Number) {
this.Image = Image;
this.Number = Number;
this.ButtonClicked = ButtonClicked;
}
function initialiseletters(){
var x;
//set up empty img tags for use
for(i = 0; i < LetterAmount; i++) {
document.write("<img id=" + i + ">");
}
for(x = 0; x < LetterAmount; x++) {
document.images[x].src = "images/" + x + ".jpg";
document.getElementById(x).onclick =function(){
Buttons[this.id].ButtonClicked();
}
Buttons[x] = new Button(document.images[x], "" + x);
}
}
function initialiseword(){
//WordArray = new Array();
WordArray[0] = 0;
WordArray[1] = 1;
WordArray[2] = 2;
WordArray[3] = 3;
}
function initialise(){
initialiseword();
initialiseletters();
document.write("testing overall");
}
I'm not seeing a problem with ButtonClicked calling checkinarray, but I'm seeing a problem with checkinarray -- it's calling document.write after the page rendering is complete (e.g., when the user clicks), which won't work. You need to modify the DOM via DOM methods (this will be made much easier if you use a toolkit like Prototype, jQuery, MooTools, Dojo, the Closure Library, YUI, etc.).
document.getElementById(x).onclick =function(){
Buttons[this.id].ButtonClicked();
}
Is where your problem is. 'this.id' is undefined.
document.write is not a good way to add elements to the DOM... Try document.createElement('img');
Then you already have reference to the image like so:
var img = document.createElement('img');
img.onclick = function()
{
//your click...
}
//add it to the view stack
document.body.appendChild(img);

Categories

Resources