HTML5 DnD - Warum funktioniert das Geisterbild nur nach dem Ziehen und Ablegen eines Elements wie erwartet?

compuphys

Ich versuche, ein pElement mit einem verschachtelten Element imgbeim Ziehen als Geisterbild anzuzeigen.

Ich bin nicht sicher, wie ich das debuggen soll, aber ich habe festgestellt, dass die Bilder nach dem Zwischenspeichern oder dem Ziehen und Ablegen irgendwo auf der Seite wie erwartet funktionieren. Ich habe hier eine MWE gemacht:

gif_of_dragging

Das Smiley-Gesicht wird beim ersten Laden der Seite gezogen und zeigt das fehlerhafte Verhalten an - das Emoji wird beim Ziehen nicht angezeigt. Das traurige Gesicht wird gezogen, losgelassen und dann neu gerafft, was zu dem erwarteten Verhalten führt - das Emoji wird als Teil des Geisterbilds angezeigt . Dies gilt für alle Bilder.

Was ich versucht habe: Ich dachte, es könnte ein Problem mit der Art und Weise sein, wie die Seitenelemente geladen werden. Deshalb habe ich das Javascript an den unteren Rand des Körpers verschoben (um sicherzustellen, dass alle Elemente geladen werden, bevor das Skript ausgeführt wird). Dies löst das Problem nicht.

MWE-Code: Ich habe die Emojis von hier bekommen , aber ich denke, alle PNGs, die Sie auf Ihrem Computer herumliegen haben, werden dies reproduzieren.

index.php:

<html>
<head>
  <link rel="stylesheet" type="text/css" href="stylesheet.css">
</head>
<body>
  <h2>Order these items</h2>
  <div id="main_wrapper">
    <?php
      $json = json_decode(file_get_contents("image_set.json"), true);
      echo '<div id="home_container" ondrop="drop(event, this)" ondragover="allowDrop(event)">';
      $i = 0;
      foreach($json as $k => $v)  {
        echo '<p class="drag_item" draggable="true" ondragstart="drag(event)" id="drag'.$i.'"><img draggable="false" src="/images/'.$v['fn'].'" width=200 height=200>'.$v['text'].'</p>';
        $i++;
      }
      echo '</div>';
    ?>
    <div id="buffer" style="min-height:100px; width:100%;"></div>
    <div id="dropzone_wrapper">
    <?php
      for($i = 0; $i < count($json); $i++) {
        echo '<div class="dropzone" id="dropzone'.$i.'" ondrop="drop(event, this)" ondragover="allowDrop(event)"></div>';
        if($i < count($json)-1){echo '&lt;';}
      }
    ?>
    </div>
    <div id="msg"></div>
  </div>
  <script>
  function allowDrop(ev) {
    ev.preventDefault();
  }

  function drag(ev) {
    var dataList = ev.dataTransfer.items;
    dataList.add(ev.target.id, "text/plain");
  }

  function drop(ev, el) {
    ev.preventDefault();
    var data            = ev.dataTransfer.getData("text");
    var element_to_drop = document.getElementById(data);
    let droppable       = true;

    // If the dropzone already contains something (not text due to
    // spaces in markup being counted as text), don't allow 
    // another drop to occur.
    if (el.childNodes.length > 0) {
      el.childNodes.forEach(function(obj) {
        if(obj.nodeName != '#text') {
          droppable = false;
        }
      });
    }

    if(droppable)
      el.appendChild(document.getElementById(data));
  }

  function reset() {
    // Put all drag items back into the home container
    let home  = document.getElementById('home_container');
    let cards = document.querySelectorAll('.drag_item');

    for(var i = 0; i < cards.length; i++) {
      home.appendChild(cards[i]);
    }
  }
  </script>
</body>
</html>

image_set.json:

{
  "happy": {
    "fn":"happy.png",
    "text":"A happy face"
  },
  "sad": {
    "fn":"sad.png",
    "text":"A sad face"
  },
  "angry": {
    "fn":"angry.png",
    "text":"An angry face"
  },
  "confused": {
    "fn":"confused.png",
    "text":"A confused face"
  },
  "sleepy": {
    "fn":"sleepy.png",
    "text":"A sleepy face"
  }
}

stylesheet.css:

* {
  box-sizing:border-box;
  padding:0px;
  margin:0px;
  font-family:sans-serif;
  font-weight:100;
}

body {
  padding:20px;
}

h2 {
  padding:20px 0;
  font-size:4em;
}

p.drag_item {
  text-align:center;
  transition:0.5s;
  width:200px;
  height:200px;
}

.drag_item:hover {
  cursor:move;
}

#home_container, #dropzone_wrapper {
  min-height:200px;
  width:100%;
  display:flex;
  flex-direction:row;
  justify-content:space-around;
  margin:20px 0;
  align-items:center;
}

#dropzone_wrapper {
  font-size:3em;
}

#dropzone_wrapper p {
  font-size:initial;
}

#home_container {
  border:1px solid black;
  border-radius:8px;
  background-color:#e5e5e5;
}

#home_container p {
  width:200px;
  font-size:16px;
}

#msg {
  display:block;
  font-size:2.5em;
}

.dropzone {
  min-height:200px;
  width:200px;
  border:1px dashed black;
  background-color:#00a8bd;
}
Tamás Kriskó

Ich habe ein bisschen recherchiert, um das Problem zu finden. Das war etwas schwierig für mich, da Firefox der einzige Browser war, in dem das Geisterbild beim ersten Laden der Seite und beim ersten Ziehen nicht angezeigt wurde. Ich habe die NetworkRegisterkarte geöffnet und festgestellt, dass das Bild nur beim ersten Ziehen angefordert wird (was ich nicht wirklich verstehe, da die Bilder vollständig geladen wurden).

Wie auch immer, ich habe es endlich geschafft, dies zum Laufen zu bringen, indem ich das ziehbare Element in das Bild anstelle des Absatzes geändert habe.

index.php:

<div id="main_wrapper">
    <?php
        $json = json_decode(file_get_contents("image_set.json"), true);
        echo '<div id="home_container" ondrop="drop(event, this)" ondragover="allowDrop(event)">';
        $i = 0;
        foreach($json as $k => $v)  {
            echo '<p class="drag_item"><img ondragstart="drag(event)" id="drag'.$i.'" draggable="true" src="images/'.$v['fn'].'" width=200 height=200>'.$v['text'].'</p>';
            $i++;
        }
        echo '</div>';
    ?>
    <div id="buffer" style="min-height:100px; width:100%;"></div>
    <div id="dropzone_wrapper">
        <?php
            for($i = 0; $i < count($json); $i++) {
                echo '<div class="dropzone" id="dropzone'.$i.'" ondrop="drop(event, this)" ondragover="allowDrop(event)"></div>';
                if($i < count($json)-1){echo '&lt;';}
            }
        ?>
    </div>
    <div id="msg"></div>
</div>

JS:

function allowDrop(ev) {
    ev.preventDefault();
}

function drag(ev) {
    // get the cursor position relative to the element
    var x = (ev.pageX - ev.target.offsetLeft) + document.body.scrollLeft;
    var y = (ev.pageY - ev.target.offsetTop) + document.body.scrollTop;

    ev.dataTransfer.setData("text", ev.target.id);

    // set the parent element (the paragraph) as the custom ghost image and set the position of the ghost image (x, y)
    ev.dataTransfer.setDragImage(ev.target.parentElement, x, y);
  }

function drop(ev, el) {
    ev.preventDefault();
    var data = ev.dataTransfer.getData("text");
    var element_to_drop = document.getElementById(data);
    let droppable = true;

    if (el.childNodes.length > 0) {
        el.childNodes.forEach(function(obj) {
            if(obj.nodeName != '#text') {
                droppable = false;
            }
        });
    }

    if(droppable)
        el.appendChild(document.getElementById(data).parentElement);
}

function reset() {
    let home = document.getElementById('home_container');
    let cards = document.querySelectorAll('.drag_item');

    for(var i = 0; i < cards.length; i++) {
        home.appendChild(cards[i]);
    }
}

Dies funktioniert ziemlich gut in: Chrome, Edge, IE 11

HINWEIS: Dies funktioniert nur in Firefox einwandfrei (der Absatztext wird nur in diesem Browser angezeigt).

Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.

Bei Verstößen wenden Sie sich bitte [email protected] Löschen.

bearbeiten am
0

Lass mich ein paar Worte sagen

0Kommentare
LoginNach der Teilnahme an der Überprüfung

Verwandte Artikel

Wie kann man ein Geisterbild beim Ziehen und Ablegen über das Dialogfeld des Registerkartenfensters hinaus bewegen?

Das Ziehen und Ablegen von Ag-Grids funktioniert nach dem Sortieren von Zeilen nicht

Wie kann ich nach dem Ziehen und Ablegen des Recyclerview-Elements die aktualisierte Position eines Listenelements bei der Onbind-Methode eines Adapters angeben?

Wie funktioniert das Ziehen und Ablegen einer Mat-Table-Zeile mit cdkDragHandle, sodass die Zeile nur mit dem Handle ziehbar ist?

Nachdem Sie das Ziehen eines DOM-Elements mit dem ziehbaren Attribut gestartet haben, können wir das Ziehen beenden und das Ziehen und Ablegen beenden?

Verhindern Sie das Ablegen innerhalb eines untergeordneten Elements beim Ziehen und Ablegen mit JS

Das Ziehen und Ablegen funktioniert in Xcode nicht

So stellen Sie den Fokus in der Anwendung nach dem Ziehen und Ablegen in das Raster wieder her

Nach dem Ziehen und Ablegen des Sortierelements erstellen Sie Duplikate

Ändern der Höhe nach dem Ziehen und Ablegen

So aktualisieren Sie Datensätze nach dem Ziehen und Ablegen

Das Ziehen und Ablegen von QTreeWidgetItem funktioniert nicht ordnungsgemäß

Das Ziehen und Ablegen von Bildern im Querformat funktioniert nicht

Scrollen Sie beim Ziehen und Ablegen eines Elements durch Elemente

Die Mouseup-Erkennung funktioniert nach dem Ziehen mit Strichzeichnung nicht wie erwartet

Wie verwende ich Steuerelemente (insbesondere eventAllow) aus dem Vollkalender in einer Winkelumgebung, um das Ziehen und Ablegen bestimmter Ereignisse einzuschränken?

: nach dem Unterricht funktioniert nicht wie erwartet

Aktivieren Sie das Ziehen und Ablegen einer Zeile, nur wenn das Ziehen auf eine bestimmte Spalte erfolgt

Wie behebt man das Problem, dass pkpass nach dem Ziehen in den iOS-Simulator nicht funktioniert?

Ziehen und Ablegen von 2 Listwidgets, aber Ändern des Texts nach dem Ablegen in 2nd ListWidget

JSON-Datei kann nach dem Ziehen und Ablegen in Xcode - Xcode / Swift nicht gelesen werden

Richten Sie die PictureBox nach dem Ziehen und Ablegen an den Schaltflächen aus

Speichern Sie die Textansichtsposition nach dem Ziehen und Ablegen mit com.jmedeisis.draglinearlayout.DragLinearLayout

Aktualisieren von React-Table-Werten nach dem Ziehen und Ablegen einer Zeile in React Redux

Die Ausrichtung der TabPage-Titel ist nach dem Ziehen und Ablegen falsch

Das Attribut "Akzeptieren" des Dateifelds funktioniert beim Ziehen und Ablegen der Datei nicht ordnungsgemäß

Warum funktioniert das Kontrollkästchen "Vuetify" nur dann wie erwartet, wenn ich etwas lese?

Das Scannen eines Zeichens nach der Methode funktioniert nicht wie erwartet

Wie erhalten Sie programmgesteuert den Dateinamen beim Ziehen und Ablegen aus dem .Net Solution Explorer?

TOP Liste

heißlabel

Archiv