最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

html - drag and drop not working in IE - Javascript, HTML5 - Stack Overflow

matteradmin13PV0评论

I've built this checker-board app which uses HTML5's Drag&Drop with javascript. It works great on chrome and firefox, but not on IE9 or IE8. My guess is that the problem is with how I attached the events.

This here is where the events are attached for all browsers BUT IE:

function eventer(){
for (var i = 0, len = allPieces.length; i < len; i++){
        allPieces[i].addEventListener('dragstart', handlePieceDragStart, false);
}
for (var i = 0, len = allSquares.length; i < len; i++){
            allSquares[i].addEventListener('dragstart', handleDragStart, false);
            allSquares[i].addEventListener('dragenter', handleDragEnter, false);
            allSquares[i].addEventListener('dragover', allowDrop, false);
            allSquares[i].addEventListener('dragleave', handleDragLeave, false);
            allSquares[i].addEventListener('drop', handleDrop, false);  
    }
}

...and this is the attachments for IE:

function eventerIE(){
    for (var i = 0, len = allPieces.length; i < len; i++){
            allPieces[i].attachEvent('dragstart', handlePieceDragStart, false);
    }
    for (var i = 0, len = allSquares.length; i < len; i++){
                allSquares[i].attachEvent('dragstart', handleDragStart);
                allSquares[i].attachEvent('dragenter', handleDragEnter);
                allSquares[i].attachEvent('dragover', allowDrop);
                allSquares[i].attachEvent('dragleave', handleDragLeave);
                allSquares[i].attachEvent('drop', handleDrop);
    }
}

These are the functions that are called on event:

function handleDragStart(e){
    dragSrcEl = this;
    e.dataTransfer.effectAllowed = 'copy';
    e.dataTransfer.setData('text/html', this.innerHTML);

}
function handlePieceDragStart(e){
    dragPiece = this;
    e.dataTransfer.setData('id', dragPiece.id);
    dragPieceId = dragPiece.id;
}
function handleDragEnter(e){
    this.classList.add('over');

}
function allowDrop(e){
    e.preventDefault();
}; 
function handleDragLeave(e){
    this.classList.remove('over');
}
function handleDrop(e) {

  if (e.stopPropagation) {
    e.stopPropagation();
    e.preventDefault();
  }

  if (dragSrcEl != this) {
    dragSrcEl.innerHTML = this.innerHTML;
    this.innerHTML = e.dataTransfer.getData('text/html');
    pId = e.dataTransfer.getData('id');
    this.taken = dragPiece.id;
    sId = this.id;

  }
var sqrs = document.getElementsByTagName("td");
    [].forEach.call(sqrs, function (col){
        col.classList.remove('over');

    });
    for(var i=0, len = piecesPosition.length; i < len; i++){
            if (piecesPosition[i][0]==dragPiece.id){
            delete piecesPosition[i];       
            piecesPosition.push([dragPiece.id,sId]);
            piecesPosition = piecesPosition.filter(function(){return true});

        }

    }
    dragPiece = document.getElementById(dragPieceId);
    dragPiece.pstn = sId;
    this.classList.remove('over');

}

I hope the code gives a good idea as to what is happening there, if you have any questions about it I would love to comment and explain more.

Thanks ahead

EDIT: After Iv'e changed the events as @Chase suggested, The functions are being called upon event, and now I get an Invalid argument error for e.dataTransfer.setData('text/html', this.innerHTML); inside the function handleDragStart.

Again, that's only in IE9 and IE8 mode.

I've built this checker-board app which uses HTML5's Drag&Drop with javascript. It works great on chrome and firefox, but not on IE9 or IE8. My guess is that the problem is with how I attached the events.

This here is where the events are attached for all browsers BUT IE:

function eventer(){
for (var i = 0, len = allPieces.length; i < len; i++){
        allPieces[i].addEventListener('dragstart', handlePieceDragStart, false);
}
for (var i = 0, len = allSquares.length; i < len; i++){
            allSquares[i].addEventListener('dragstart', handleDragStart, false);
            allSquares[i].addEventListener('dragenter', handleDragEnter, false);
            allSquares[i].addEventListener('dragover', allowDrop, false);
            allSquares[i].addEventListener('dragleave', handleDragLeave, false);
            allSquares[i].addEventListener('drop', handleDrop, false);  
    }
}

...and this is the attachments for IE:

function eventerIE(){
    for (var i = 0, len = allPieces.length; i < len; i++){
            allPieces[i].attachEvent('dragstart', handlePieceDragStart, false);
    }
    for (var i = 0, len = allSquares.length; i < len; i++){
                allSquares[i].attachEvent('dragstart', handleDragStart);
                allSquares[i].attachEvent('dragenter', handleDragEnter);
                allSquares[i].attachEvent('dragover', allowDrop);
                allSquares[i].attachEvent('dragleave', handleDragLeave);
                allSquares[i].attachEvent('drop', handleDrop);
    }
}

These are the functions that are called on event:

function handleDragStart(e){
    dragSrcEl = this;
    e.dataTransfer.effectAllowed = 'copy';
    e.dataTransfer.setData('text/html', this.innerHTML);

}
function handlePieceDragStart(e){
    dragPiece = this;
    e.dataTransfer.setData('id', dragPiece.id);
    dragPieceId = dragPiece.id;
}
function handleDragEnter(e){
    this.classList.add('over');

}
function allowDrop(e){
    e.preventDefault();
}; 
function handleDragLeave(e){
    this.classList.remove('over');
}
function handleDrop(e) {

  if (e.stopPropagation) {
    e.stopPropagation();
    e.preventDefault();
  }

  if (dragSrcEl != this) {
    dragSrcEl.innerHTML = this.innerHTML;
    this.innerHTML = e.dataTransfer.getData('text/html');
    pId = e.dataTransfer.getData('id');
    this.taken = dragPiece.id;
    sId = this.id;

  }
var sqrs = document.getElementsByTagName("td");
    [].forEach.call(sqrs, function (col){
        col.classList.remove('over');

    });
    for(var i=0, len = piecesPosition.length; i < len; i++){
            if (piecesPosition[i][0]==dragPiece.id){
            delete piecesPosition[i];       
            piecesPosition.push([dragPiece.id,sId]);
            piecesPosition = piecesPosition.filter(function(){return true});

        }

    }
    dragPiece = document.getElementById(dragPieceId);
    dragPiece.pstn = sId;
    this.classList.remove('over');

}

I hope the code gives a good idea as to what is happening there, if you have any questions about it I would love to comment and explain more.

Thanks ahead

EDIT: After Iv'e changed the events as @Chase suggested, The functions are being called upon event, and now I get an Invalid argument error for e.dataTransfer.setData('text/html', this.innerHTML); inside the function handleDragStart.

Again, that's only in IE9 and IE8 mode.

Share Improve this question edited Aug 5, 2013 at 6:58 Spudley 169k39 gold badges238 silver badges308 bronze badges asked Oct 9, 2012 at 15:16 TomcatomTomcatom 3653 gold badges6 silver badges16 bronze badges
Add a comment  | 

4 Answers 4

Reset to default 23

Use "text" instead of "text/html"

e.dataTransfer.setData("text", this.innerHTML);

See this article for explanation

Even though Internet Explorer started out by introducing only "text" and "URL" as valid data types, HTML5 extends this to allow any MIME type to be specified. The values "text" and "URL" will be supported by HTML5 for backwards compatibility, but they are mapped to "text/plain" and "text/uri-list".

You need to do two things for the drag and drop to work in I.E..

1) When you set and get the data use 'text' and not 'text/html'

e.dataTransfer.setData('text', this.innerHTML);

e.dataTransfer.getData('text');

2) Prevent the default behaviour when handling 'dragenter' (as well as 'dragover').

function handleDragEnter(e) {
    if (e.preventDefault) { 
        e.preventDefault(); 
    } 
    ... 
}

setData method expect String data type not Number

setData('text',1)//is wrong

setData('text',''+1)//is correct

IE is a bit different than most, try ondragstart, ondragenter, etc..

            allSquares[i].attachEvent('ondragstart', handleDragStart);
            allSquares[i].attachEvent('ondragenter', handleDragEnter);
            allSquares[i].attachEvent('ondragover', allowDrop);
            allSquares[i].attachEvent('ondragleave', handleDragLeave);
            allSquares[i].attachEvent('ondrop', handleDrop);

EDIT:

function handleDragStart(e){
    if(!e)
       e = window.event;

    dragSrcEl = (window.event) ? window.event.srcElement /* for IE */ : event.target;
    e.dataTransfer.effectAllowed = 'copy';
    e.dataTransfer.setData('text/html', dragSrcEl.innerHTML);
}
Post a comment

comment list (0)

  1. No comments so far