简体   繁体   中英

html5 drag and drop prevent drop unless div empty

I'm attempting to create a sort of visual interface for simple graphic creation. It consists of 10 image icons, and 5 boxes in which those icons can be placed. I want users to be able to pick which of the 10 icons they would like to display, and arrange the elements as they see fit using drag and drop. The 5 icons are also inside of a div in which the icons can be dropped, so that they can return the icon to the "home" row if they change their mind and wish to select another icon.

not unlike this simple tutorial, but with more divs and icons: http://www.w3schools.com/html/tryit.asp?filename=tryhtml5_draganddrop2

my script:

<script>
function allowDrop(ev)
{
ev.preventDefault();
}
function drag(ev)
{
ev.dataTransfer.setData("Text",ev.target.id);
//CSS CHANGES HERE FOR ON PICKUP
$( ".dragfive" ).css("border", "2px solid #ff9d00");
$( ".select5" ).css("border", "2px solid #ff9d00");
}
function drop(ev)
{
ev.preventDefault();
var data=ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));
//CSS CHANGES HERE FOR ON DROP
$( ".dragfive" ).css("border", "2px solid transparent");
$( ".select5" ).css("border", "2px solid transparent");
}
</script>

my code is exactly the same as the tutorial, but I've added some nice CSS changes as the comments indicate - I made colorful borders appear to indicate to users where they can place the item. These become transparent once dropped. Works perfectly except...

  1. how can I prevent an icon from being dropped on top of another icon? (or rather, only allow dropping the icon into an empty div?)
  2. If I wished to create a second set of icons and replicate the process, how can I keep them and their allowed drop area separate? (so that the icons do not end up in unintended places)

thanks a bunch.

use this, it has worked for my script... in order to prevent drop in div, which already has something in it like - image.

if (ev.target.hasChildNodes()) {
    ev.target.appendChild(document.getElementById(data));
}

For #1, you need to make your drop function just a little bit more intelligent. Inside of it, check to make sure that there are no childNodes before appending the Child.

For #2, you need to make both drag and drop more intelligent. In drag , you need to look at the target and set some group information. In drop , you need to check that information to see if it matches appropriately.

I can show you what #1 should look like:

function drop(ev)
{
    ev.preventDefault();
    if (ev.target.hasChildNodes()) { return; }
    // ...all the rest as you had it

For #2, it will be a bit more complex, depending on how you want to define the second set of icons. Generally, it should make your code look something like this:

function drag(ev)
{
    ev.dataTransfer.setData("Text",ev.target.id);
    // I'm going to assume your group1 items will have "group1" in their id.  Set it up however you want.
    if (ev.target.id.indexOf("group1") != -1) {
        ev.dataTransfer.setData("Group", 1);
    } else {
        ev.dataTransfer.setData("Group", 2);
    }
    // ...all the rest as you had it
}

function drop(ev)
{
    ev.preventDefault();
    if (ev.target.hasChildNodes()) { return; }
    if (ev.target.id.indexOf("group1") != -1 && ev.dataTransfer.getData("Group") == 2 ||
        ev.target.id.indexOf("group2") != -1 && ev.dataTransfer.getData("Group") == 1) {
            return;
        }
    // ...all the rest as you had it

I ended up just adding

ev.target.appendChild(document.getElementById(data).cloneNode(true));

to the end of the drop command so that I wouldn't lose the icons. This is a workaround for issue 1 since I couldn't prevent the data I picked up from being dropped based on the child node of the intended target div. I could prevent the override with if (ev.target.hasChildNodes()) { return; } if (ev.target.hasChildNodes()) { return; }

, but I would still lose the data I had picked up with the drag, instead of refusing the drop like I was hoping for. Copying them instead with the code above was the best workaround. The issue with it dropping elements out of order was caused by a typo in the id. Scott's method for dividing icons into groups worked perfectly.

What I did to solve this is maybe a strange but it worked! I just made this function:

function testDiv(ev, x) {
    if (x.length > 0) {
        return false;
    }
    else {
        allowDrop(ev);
        return true;
    }
}

I call this function before I call allowdrop . x is the innerHTML of the div . It works perfectly for me!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM