5

我已经构建了这个棋盘应用程序,它使用 HTML5 的 Drag&Drop 和 javascript。它适用于 chrome 和 firefox,但不适用于 IE9 或 IE8。我的猜测是问题在于我如何附加事件。

这是为所有浏览器附加事件的地方,但 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);  
    }
}

...这是 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);
    }
}

这些是事件调用的函数:

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');

}

我希望代码可以很好地了解那里发生的事情,如果您对此有任何疑问,我很乐意发表评论和解释。

提前谢谢

编辑:在我按照@Chase 的建议更改了事件之后,函数正在被事件调用,现在我在函数内部得到一个Invalid argument错误。e.dataTransfer.setData('text/html', this.innerHTML);handleDragStart

同样,这仅适用于 IE9 和 IE8 模式。

4

4 回答 4

23

使用“文本”而不​​是“文本/html”

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

这篇文章的解释

尽管 Internet Explorer 一开始只引入“文本”和“URL”作为有效数据类型,但 HTML5 对此进行了扩展以允许指定任何 MIME 类型。HTML5 将支持值“text”和“URL”以实现向后兼容性,但它们被映射到“text/plain”和“text/uri-list”。

于 2013-08-05T06:36:09.913 回答
3

您需要做两件事才能在 IE 中进行拖放操作。

1)当你设置和获取数据时使用'text'而不是'text/html'

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

e.dataTransfer.getData('text');

2) 在处理“dragenter”(以及“dragover”)时防止默认行为。

function handleDragEnter(e) {
    if (e.preventDefault) { 
        e.preventDefault(); 
    } 
    ... 
}
于 2016-04-13T07:59:41.400 回答
2

setData方法期望字符串数据类型不是数字

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

setData('text',''+1)//is correct
于 2016-09-19T14:45:51.680 回答
1

IE 与大多数浏览器有点不同,请尝试ondragstartondragenter等等。

            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);

编辑

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);
}
于 2012-10-09T15:22:54.700 回答