0

I'm trying to modify some code for dragging out files from your browser window I found here: http://www.thecssninja.com/javascript/gmail-dragout

In my code I want to use for loops so I can handle a large number of files without repeating code over and over.

This is what I have:

<a href = "file0" id = "0" draggable = "true" data-downloadurl="application/pdf:file0name.pdf:file:///C:/filepath/file0.pdf">file0</a>
<a href = "file1" id = "1" draggable = "true" data-downloadurl="application/pdf:file1name.pdf:file:///C:/filepath/file1.pdf">file1</a>
<a href = "file2" id = "2" draggable = "true" data-downloadurl="application/pdf:file2name.pdf:file:///C:/filepath/file2name.pdf">file2</a>
<a href = "file3" id = "3" draggable = "true" data-downloadurl="application/pdf:file3name.pdf:file:///C:/filepath/file3name.pdf">file3</a>

<script type = "text/javascript>
    var file_count = 3;
var fileDetails = [];

var files = new Array(file_count);
for(var i=0; i<=file_count; i++) {
    files[i] = document.getElementById(i);
}

if(typeof files[0].dataset === "undefined") {
    for (i=0; i<=file_count; i++) {
        fileDetails[i] = files[i].getAttribute("data-downloadurl");
    }
}else {
    for (i=0; i<=file_count; i++) {
        fileDetails[i] = files[i].dataset.downloadurl;
    }
}

//I'm pretty sure the problem starts here.
//If you substitue i for a specific element from the array and comment out the for loop, the script works just fine for the element specified.
for(i=0; i<=file_count; i++) {
    files[i].addEventListener("dragstart",function(evt){
        evt.dataTransfer.setData("DownloadURL",fileDetails[i]);
    },false);
}

I'm fairly certain the problem starts where I have it labeled, I'm not sure why there is a problem or how to solve it.

Some things I should point out:

This only works in Chrome. This is not an issue for me.

I want this to handle 20+ files.

0

1 Answer 1

1

The problem does indeed start where you think it does

//I'm pretty sure the problem starts here.
//If you substitue i for a specific element from the array and comment out the for loop, the script works just fine for the element specified.
for(i=0; i<=file_count; i++) {
    files[i].addEventListener("dragstart",function(evt){
        evt.dataTransfer.setData("DownloadURL",fileDetails[i]);
    },false);
}

Basically your dragstart event listener is bound to i, which at the time of execution is the last element in the list.

The following will work better.

//I'm pretty sure the problem starts here.
//If you substitue i for a specific element from the array and comment out the for loop, the script works just fine for the element specified.
for(i=0; i<=file_count; i++) {
    files[i].addEventListener("dragstart", (function(idx) {
        return function(evt){
           evt.dataTransfer.setData("DownloadURL",fileDetails[idx]);
        }
    })(i),false);
}

In the above code you will be creating and returning an object of type function with the correct value of i bound - essentially the closure is created at a different level and thus when accessed will get the correct data.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.