最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Firefox drag and drop redirect stop JQUERY - Stack Overflow

programmeradmin3浏览0评论

I am using fabric.js library to create a drag and drop moodboard creator. Everything works perfect, except in Firefox when I drag and drop the image to the canvas. It adds the image, but redirects to the img url. After the redirect, When I click on the back btn it goes back to the previous page and the image is on the canvas.

I have been searching and reading for a few hours now, trying all kinds of things. It seems that something in my code is preventing either "e.stopPropagation();" or "e.preventDefault()" from functioning correctly. I just cant seem to find the gremlin.

Any help would be great. Thanks!

UPDATE: Added JSFiddle.
here is a jsfiddle with my code:
/

UPDATE 2:
Fixed the issue, here is the part that fixed it:

function handleDrop(e) {
// this / e.target is current target element.

/*
    if (e.stopPropagation) {
        e.stopPropagation(); // stops the browser from redirecting.
    }
*/

    e.stopPropagation(); // Stops some browsers from redirecting.
    e.preventDefault(); // Stops some browsers from redirecting.

    var img = document.querySelector('#images img.img_dragging');

    console.log('event: ', e);

    var newImage = new fabric.Image(img, {
        width: img.width,
        height: img.height,
    // Set the center of the new object based on the event coordinates relative
    // to the canvas container.
        left: e.layerX,
        top: e.layerY
    });
    canvas.add(newImage);

    return false;
}

Thanks for all the help :)

window.onload=function(){

var canvas = new fabric.Canvas('canvas');

canvas.backgroundColor = '#ffffff';


function handleDragStart(e) {
    [].forEach.call(images, function (img) {
        img.classList.remove('img_dragging');
    });
    this.classList.add('img_dragging');

}

function handleDragOver(e) {
    if (e.preventDefault) {
        e.preventDefault(); // Necessary. Allows us to drop.

    }

    e.dataTransfer.dropEffect = 'copy';

    return false;
}

function handleDragEnter(e) {
    // this / e.target is the current hover target.

    this.classList.add('over');

}

function handleDragLeave(e) {
    e.stopPropagation();

    this.classList.remove('over'); // this / e.target is previous target element.

}

function handleDrop(e) {
    // this / e.target is current target element.

    if (e.stopPropagation) {
        e.stopPropagation(); // stops the browser from redirecting.
    }

    var img = document.querySelector('#images img.img_dragging');

    console.log('event: ', e);

    var newImage = new fabric.Image(img, {
        width: img.width,
        height: img.height,
        // Set the center of the new object based on the event coordinates relative
        // to the canvas container.
        left: e.layerX,
        top: e.layerY
    });
    canvas.add(newImage);
    return false;
}

function handleDragEnd(e) {
    // this/e.target is the source node.
    [].forEach.call(images, function (img) {
        img.classList.remove('img_dragging');

    });
}

  var removeSelectedEl = document.getElementById('remove-selected');
  removeSelectedEl.onclick = function() {
    var activeObject = canvas.getActiveObject(),
        activeGroup = canvas.getActiveGroup();
    if (activeGroup) {
      var objectsInGroup = activeGroup.getObjects();
      canvas.discardActiveGroup();
      objectsInGroup.forEach(function(object) {
        canvas.remove(object);
      });
    }
    else if (activeObject) {
      canvas.remove(activeObject);
        $("#imageControl").fadeOut('slow');

    }
  };

  var sendBackwardsEl = document.getElementById('send-backwards');
  sendBackwardsEl.onclick = function() {
    var activeObject = canvas.getActiveObject();
    if (activeObject) {
      canvas.sendBackwards(activeObject);
    }
  };

  var sendToBackEl = document.getElementById('send-to-back');
  sendToBackEl.onclick = function() {
    var activeObject = canvas.getActiveObject();
    if (activeObject) {
      canvas.sendToBack(activeObject);
    }
  };

  var bringForwardEl = document.getElementById('bring-forward');
  bringForwardEl.onclick = function() {
    var activeObject = canvas.getActiveObject();
    if (activeObject) {
      canvas.bringForward(activeObject);
    }
  };

  var bringToFrontEl = document.getElementById('bring-to-front');
  bringToFrontEl.onclick = function() {
    var activeObject = canvas.getActiveObject();
    if (activeObject) {
      canvas.bringToFront(activeObject);
    }
  };

 document.getElementById('saveImg').onclick = function() {
    if (!fabric.Canvas.supports('toDataURL')) {
      alert('This browser doesn\'t provide means to serialize canvas to an image');
    }
    else {
    canvas.deactivateAll().renderAll();
      window.open(canvas.toDataURL('png'));
    }
  };



canvas.on('selection:cleared', function(options) {
    var activeObject = canvas.getActiveObject();
        if (activeObject === null) {
                $("#imageControl").fadeOut('slow');
            }
});

canvas.on('object:selected', function(options) {
    var activeObject = canvas.getActiveObject();
         if (options.target && activeObject !== null) {
                     $("#imageControl").show('slow');
                }
});

canvas.on('selection:created', function(options) {
         if (options.target) {
                    $("#imageControl").show('slow');
                 }
});


if (Modernizr.draganddrop) {
    // Browser supports HTML5 DnD.

    // Bind the event listeners for the image elements
    var images = document.querySelectorAll('#images img');
    [].forEach.call(images, function (img) {
        img.addEventListener('dragstart', handleDragStart, false);
        img.addEventListener('dragend', handleDragEnd, false);
    });
    // Bind the event listeners for the canvas
    var canvasContainer = document.getElementById('canvas-container');
    canvasContainer.addEventListener('dragenter', handleDragEnter, false);
    canvasContainer.addEventListener('dragover', handleDragOver, false);
    canvasContainer.addEventListener('dragleave', handleDragLeave, false);
    canvasContainer.addEventListener('drop', handleDrop, false);

} else {
    // Replace with a fallback to a library solution.
    alert("This browser doesn't support the HTML5 Drag and Drop API.");
}

}

HTML:

<div id="images">
<img draggable="true" src=".png" width="70" height="90"></img>    
</div>

<div id="canvas-container-controls">
<div id="imageControlWrapper">
<div id="imageControl">
<button class= "imgBtn" id="saveImg">Save Canvas</button>
<button class="imgBtn" id="remove-selected">Remove selected object/group</button>
<button id="send-backwards" class="imgBtn">Send backwards</button>
<button id="send-to-back" class="imgBtn">Send to back</button>
<button id="bring-forward" class="imgBtn">Bring forwards</button>
<button id="bring-to-front" class="imgBtn">Bring to front</button>
</div>
</div>

<div id="canvas-container">
    <canvas id="canvas" width="400" height="400"></canvas>
</div>
</div>

I am using fabric.js library to create a drag and drop moodboard creator. Everything works perfect, except in Firefox when I drag and drop the image to the canvas. It adds the image, but redirects to the img url. After the redirect, When I click on the back btn it goes back to the previous page and the image is on the canvas.

I have been searching and reading for a few hours now, trying all kinds of things. It seems that something in my code is preventing either "e.stopPropagation();" or "e.preventDefault()" from functioning correctly. I just cant seem to find the gremlin.

Any help would be great. Thanks!

UPDATE: Added JSFiddle.
here is a jsfiddle with my code:
http://jsfiddle/bQxMu/

UPDATE 2:
Fixed the issue, here is the part that fixed it:

function handleDrop(e) {
// this / e.target is current target element.

/*
    if (e.stopPropagation) {
        e.stopPropagation(); // stops the browser from redirecting.
    }
*/

    e.stopPropagation(); // Stops some browsers from redirecting.
    e.preventDefault(); // Stops some browsers from redirecting.

    var img = document.querySelector('#images img.img_dragging');

    console.log('event: ', e);

    var newImage = new fabric.Image(img, {
        width: img.width,
        height: img.height,
    // Set the center of the new object based on the event coordinates relative
    // to the canvas container.
        left: e.layerX,
        top: e.layerY
    });
    canvas.add(newImage);

    return false;
}

Thanks for all the help :)

window.onload=function(){

var canvas = new fabric.Canvas('canvas');

canvas.backgroundColor = '#ffffff';


function handleDragStart(e) {
    [].forEach.call(images, function (img) {
        img.classList.remove('img_dragging');
    });
    this.classList.add('img_dragging');

}

function handleDragOver(e) {
    if (e.preventDefault) {
        e.preventDefault(); // Necessary. Allows us to drop.

    }

    e.dataTransfer.dropEffect = 'copy';

    return false;
}

function handleDragEnter(e) {
    // this / e.target is the current hover target.

    this.classList.add('over');

}

function handleDragLeave(e) {
    e.stopPropagation();

    this.classList.remove('over'); // this / e.target is previous target element.

}

function handleDrop(e) {
    // this / e.target is current target element.

    if (e.stopPropagation) {
        e.stopPropagation(); // stops the browser from redirecting.
    }

    var img = document.querySelector('#images img.img_dragging');

    console.log('event: ', e);

    var newImage = new fabric.Image(img, {
        width: img.width,
        height: img.height,
        // Set the center of the new object based on the event coordinates relative
        // to the canvas container.
        left: e.layerX,
        top: e.layerY
    });
    canvas.add(newImage);
    return false;
}

function handleDragEnd(e) {
    // this/e.target is the source node.
    [].forEach.call(images, function (img) {
        img.classList.remove('img_dragging');

    });
}

  var removeSelectedEl = document.getElementById('remove-selected');
  removeSelectedEl.onclick = function() {
    var activeObject = canvas.getActiveObject(),
        activeGroup = canvas.getActiveGroup();
    if (activeGroup) {
      var objectsInGroup = activeGroup.getObjects();
      canvas.discardActiveGroup();
      objectsInGroup.forEach(function(object) {
        canvas.remove(object);
      });
    }
    else if (activeObject) {
      canvas.remove(activeObject);
        $("#imageControl").fadeOut('slow');

    }
  };

  var sendBackwardsEl = document.getElementById('send-backwards');
  sendBackwardsEl.onclick = function() {
    var activeObject = canvas.getActiveObject();
    if (activeObject) {
      canvas.sendBackwards(activeObject);
    }
  };

  var sendToBackEl = document.getElementById('send-to-back');
  sendToBackEl.onclick = function() {
    var activeObject = canvas.getActiveObject();
    if (activeObject) {
      canvas.sendToBack(activeObject);
    }
  };

  var bringForwardEl = document.getElementById('bring-forward');
  bringForwardEl.onclick = function() {
    var activeObject = canvas.getActiveObject();
    if (activeObject) {
      canvas.bringForward(activeObject);
    }
  };

  var bringToFrontEl = document.getElementById('bring-to-front');
  bringToFrontEl.onclick = function() {
    var activeObject = canvas.getActiveObject();
    if (activeObject) {
      canvas.bringToFront(activeObject);
    }
  };

 document.getElementById('saveImg').onclick = function() {
    if (!fabric.Canvas.supports('toDataURL')) {
      alert('This browser doesn\'t provide means to serialize canvas to an image');
    }
    else {
    canvas.deactivateAll().renderAll();
      window.open(canvas.toDataURL('png'));
    }
  };



canvas.on('selection:cleared', function(options) {
    var activeObject = canvas.getActiveObject();
        if (activeObject === null) {
                $("#imageControl").fadeOut('slow');
            }
});

canvas.on('object:selected', function(options) {
    var activeObject = canvas.getActiveObject();
         if (options.target && activeObject !== null) {
                     $("#imageControl").show('slow');
                }
});

canvas.on('selection:created', function(options) {
         if (options.target) {
                    $("#imageControl").show('slow');
                 }
});


if (Modernizr.draganddrop) {
    // Browser supports HTML5 DnD.

    // Bind the event listeners for the image elements
    var images = document.querySelectorAll('#images img');
    [].forEach.call(images, function (img) {
        img.addEventListener('dragstart', handleDragStart, false);
        img.addEventListener('dragend', handleDragEnd, false);
    });
    // Bind the event listeners for the canvas
    var canvasContainer = document.getElementById('canvas-container');
    canvasContainer.addEventListener('dragenter', handleDragEnter, false);
    canvasContainer.addEventListener('dragover', handleDragOver, false);
    canvasContainer.addEventListener('dragleave', handleDragLeave, false);
    canvasContainer.addEventListener('drop', handleDrop, false);

} else {
    // Replace with a fallback to a library solution.
    alert("This browser doesn't support the HTML5 Drag and Drop API.");
}

}

HTML:

<div id="images">
<img draggable="true" src="http://i.imgur./q9aLMza.png" width="70" height="90"></img>    
</div>

<div id="canvas-container-controls">
<div id="imageControlWrapper">
<div id="imageControl">
<button class= "imgBtn" id="saveImg">Save Canvas</button>
<button class="imgBtn" id="remove-selected">Remove selected object/group</button>
<button id="send-backwards" class="imgBtn">Send backwards</button>
<button id="send-to-back" class="imgBtn">Send to back</button>
<button id="bring-forward" class="imgBtn">Bring forwards</button>
<button id="bring-to-front" class="imgBtn">Bring to front</button>
</div>
</div>

<div id="canvas-container">
    <canvas id="canvas" width="400" height="400"></canvas>
</div>
</div>
Share Improve this question edited Sep 27, 2013 at 20:51 JustAnotherDude asked Sep 27, 2013 at 12:13 JustAnotherDudeJustAnotherDude 452 silver badges5 bronze badges 3
  • It would be helpful if you added a fiddle with your code. – Kerry Liu Commented Sep 27, 2013 at 20:02
  • sorry, here is a link jsfiddle/bQxMu – JustAnotherDude Commented Sep 27, 2013 at 20:25
  • Next time if you figure out your own question, you can always add your answer and mark it as accepted. :) – Kerry Liu Commented Sep 27, 2013 at 21:28
Add a ment  | 

2 Answers 2

Reset to default 7

Add an e.preventDefault() in handleDrop: http://jsfiddle/wN29y/

function handleDrop(e) {
// this / e.target is current target element.
e.preventDefault();
if (e.stopPropagation) {
    e.stopPropagation(); // stops the browser from redirecting.
}

var img = document.querySelector('#images img.img_dragging');

console.log('event: ', e);

var newImage = new fabric.Image(img, {
    width: img.width,
    height: img.height,
    // Set the center of the new object based on the event coordinates relative
    // to the canvas container.
    left: e.layerX,
    top: e.layerY
});
canvas.add(newImage);

return false;
}

My understanding is that you should have e.stopPropagation in handleDragOver, otherwise the browser still accepts the event, and opens the image.

(Similar to my answer here: Why can't I get file dropping to work with jquery?)

发布评论

评论列表(0)

  1. 暂无评论