Saya memiliki aplikasi web yang relatif sederhana yang saya buat sebagai rak buku dan saya ingin pengguna dapat menarik dan melepas buku di antara rak buku. Ini bekerja persis seperti yang saya inginkan ketika saya menjatuhkan buku ke sisi "kanan" dari buku-buku yang ada di salah satu rak buku. Buku yang telah diseret dan dijatuhkan ditambahkan ke rak.

Di mana itu tidak berfungsi adalah ketika saya menjatuhkan buku di atas buku yang ada. Ketika saya melakukannya, buku itu akan dihapus dari rak yang ada -- tetapi buku itu hilang sama sekali, bukannya ditambahkan ke rak buku yang ditargetkan seperti yang saya inginkan. Tidak jelas bagi saya mengapa ini terjadi.

Lihat di sini: https://mainstringargs.github.io/bookshelf-data/test.html

(Saya menggunakan Firefox, jika itu relevan)

Kode sumber yang relevan ada di sini (html mentah): https://github. com/mainstringargs/bookshelf-data/blob/master/test.html

Catatan: Ini awalnya dibuat melalui jekyll di github, tetapi karena masalah ini bukan jekyll centric, saya tidak menyertakan detail kode sumber itu.

Saya sebagian besar mengikuti panduan ini untuk cara menerapkan drag and drop:

https://www.w3schools.com/html/html5_draganddrop.asp

Kode javascript yang relevan di bawah ini. Fungsi 'jatuhkan' dimaksudkan untuk menjatuhkan item daftar yang relevan ke daftar baru.

     <script>
        
        function allowDrop(ev) {
           ev.preventDefault();
        }
        
        function drag(ev) {
           ev.dataTransfer.setData("text", ev.target.id);
        }
        
        function drop(ev) {
          ev.preventDefault();
          var data = ev.dataTransfer.getData("text");
          ev.target.appendChild(document.getElementById(data).parentNode);
        }
        
     </script>

Setiap rak buku itu sendiri dibungkus dalam div yang berisi satu daftar tidak berurutan (ul) dengan item daftar (li) yang mewakili setiap buku. Berikut cuplikan dari rak buku pertama:

     <div ondrop="drop(event)" ondragover="allowDrop(event)"  class="shelf read">
        <ul  class="books clearfix">
           <li id="The_Clean_Coder" class="book">
              <img id="img_The_Clean_Coder" draggable="true" ondragstart="drag(event)"  class="front" src="/bookshelf-data/assets/img/the_clean_coder.jpg" alt="The Clean Coder">
              <div class="back" onclick="" id="read_The_Clean_Coder">
                 <div class="p0">
                    <span class="score"><span id="rating_The_Clean_Coder"></span></span>
                    <script>
                       var span = document.getElementById("rating_The_Clean_Coder");
                       var rating = 4.3;
                       var starWidth = (span.offsetWidth - paddingLeft - (5*gapSize))/5.0;
                       var gaps = Math.floor(rating);
                       var width = (rating * starWidth) + (gaps * gapSize);
                       span.style.width = `${width}px`;
                       span.title=4.3 +" out of 5";
                    </script>
                    <dl class="p10">
                       <dt>Title:</dt>
                       <dd>The Clean Coder</dd>
                       <dt>Author:</dt>
                       <dd>Robert C. Martin</dd>
                       <dt>Released:</dt>
                       <dd>May 23, 2011</dd>
                    </dl>
                    <p class="description">
                       Programmers who endure and succeed amidst swirling uncertainty and nonstop pressure share a common attribute - They care deeply about...
                    </p>
                    <a href="https://www.amazon.com/Clean-Coder-Conduct-Professional-Programmers/dp/0137081073/ref=as_li_ss_tl?crid=9YJ9X71LWCXD&keywords=clean+architecture&qid=1564690296&s=gateway&sprefix=clean+arh,aps,155&sr=8-4&linkCode=ll1&tag=mainstringarg-20&linkId=cd98bbe94682a01daca2dcb8852cf52e&language=en_US" target="_blank">Amazon Link</a>
                 </div>
              </div>
           </li>

Seperti yang Anda lihat, saya telah menambahkan panggilan ini ke div rak buku: ondrop="drop(event)" ondragover="allowDrop(event)" dan pada setiap gambar, saya telah menyertakan draggable="true" ondragstart="drag (peristiwa)". Ini mengikuti pola dari tautan w3schools, tetapi ada kasus di mana tampaknya tidak menambahkan item ke daftar tidak berurutan.

2
mainstringargs 8 Januari 2021, 23:43

2 jawaban

Jawaban Terbaik

Masalahnya adalah ketika Anda menjatuhkan elemen di akhir, itu mempertimbangkan induk dari elemen yang sedang dipindahkan ul :

enter image description here

Tetapi ketika Anda meletakkan gambar Anda di atas gambar lain, itu menempatkan gambar itu di dalam gambar yang dijatuhkan, mengingat itu adalah induknya :

enter image description here

Anda kemudian mendapatkan gambar di dalam gambar, sehingga tidak akan ditampilkan dan tidak akan berfungsi.

Untuk memperbaikinya saya sarankan menggunakan metode 'terdekat', untuk menambahkan ke rak buku terdekat:

function closest(elem) {
  if (elem.className.indexOf(1)) {
    return elem;
  }
  var parent = elem.parentNode;
  if (parent.className.indexOf(1) != -1) {
    return parent;
  }
  return closest(parent);
}
function drop(ev) {
  ...
  ev.target.closest('ul').appendChild(document.getElementById(data).parentNode);
}

Anda akan mendapatkan hasil seperti berikut:

<link rel="stylesheet" href="https://mainstringargs.github.io/myshelf/assets/css/main.css">
<script>
  const paddingLeft = 15;
  const gapSize = 10;

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

  function drag(ev) {
    ev.dataTransfer.setData("text", ev.target.id);
  }

  function closest(elem) {
    if (elem.className.indexOf(1)) {
      return elem;
    }
    var parent = elem.parentNode;
    if (parent.className.indexOf(1) != -1) {
      return parent;
    }
    return closest(parent);
  }

  function drop(ev) {
    ev.preventDefault();
    var data = ev.dataTransfer.getData("text");
    console.log(ev.target)
    //console.log(data);
    //console.log(document.getElementById(data));
    //console.log(document.getElementById(data).parentNode);
    //var parent = document.getElementById(data).parentNode
    ev.target.closest('ul').appendChild(document.getElementById(data).parentNode);
  }
</script>
<section id="bookshelf">
  <div class="user-details">
    <h1> My Shelf </h1>
  </div>
  <div class="shelf ondeck" ondrop="drop(event)" ondragover="allowDrop(event)">
    <ul class="books clearfix">
      <li id="Clean_Architecture" class="book">
        <img id="img_Clean_Architecture" draggable="true" ondragstart="drag(event)" class="front" src="https://mainstringargs.github.io/bookshelf-data/assets/img/clean_architecture.jpg" alt="Clean Architecture">
        <div class="back" onclick="" id="ondeck_Clean_Architecture">
          <div class="p0">
            <span class="score"><span id="rating_Clean_Architecture"></span></span>
            <script>
              var span = document.getElementById("rating_Clean_Architecture");
              var rating = 4.3;
              var starWidth = (span.offsetWidth - paddingLeft - (5 * gapSize)) / 5.0;
              var gaps = Math.floor(rating);
              var width = (rating * starWidth) + (gaps * gapSize);
              span.style.width = `${width}px`;
              span.title = 4.3 + " out of 5";
            </script>
            <dl class="p10">
              <dt>Title:</dt>
              <dd>Clean Architecture</dd>
              <dt>Author:</dt>
              <dd>Robert C. Martin</dd>
              <dt>Released:</dt>
              <dd>September 20, 2017</dd>
            </dl>
            <p class="description">
              By applying universal rules of software architecture, you can dramatically improve developer productivity throughout the life of any software system....
            </p>
            <a href="https://www.amazon.com/Clean-Architecture-Craftsmans-Software-Structure/dp/0134494164/ref=as_li_ss_tl?crid=9YJ9X71LWCXD&keywords=clean+architecture&qid=1564690296&s=gateway&sprefix=clean+arh,aps,155&sr=8-1&linkCode=ll1&tag=mainstringarg-20&linkId=d660a50d6cae9d31db54a46b1367c79e&language=en_US"
              target="_blank">Amazon Link</a>
          </div>
        </div>
      </li>
      <li id="Designing_Data-Intensive_Applications" class="book">
        <img id="img_Designing_Data-Intensive_Applications" draggable="true" ondragstart="drag(event)" class="front" src="https://mainstringargs.github.io/bookshelf-data/assets/img/designing_data_intensive_applications.jpg" alt="Designing Data-Intensive Applications">
        <div class="back" onclick="" id="ondeck_Designing_Data-Intensive_Applications">
          <div class="p0">
            <span class="score"><span id="rating_Designing_Data-Intensive_Applications"></span></span>
            <script>
              var span = document.getElementById("rating_Designing_Data-Intensive_Applications");
              var rating = 4.7;
              var starWidth = (span.offsetWidth - paddingLeft - (5 * gapSize)) / 5.0;
              var gaps = Math.floor(rating);
              var width = (rating * starWidth) + (gaps * gapSize);
              span.style.width = `${width}px`;
              span.title = 4.7 + " out of 5";
            </script>
            <dl class="p10">
              <dt>Title:</dt>
              <dd>Designing Data-Intensive Applications</dd>
              <dt>Author:</dt>
              <dd>Martin Kleppmann</dd>
              <dt>Released:</dt>
              <dd>April 2, 2017</dd>
            </dl>
            <p class="description">
              Data is at the center of many challenges in system design today. Difficult issues need to be figured out, such...
            </p>
            <a href="https://www.amazon.com/Designing-Data-Intensive-Applications-Reliable-Maintainable/dp/1449373321/ref=as_li_ss_tl?crid=2J0BUT3XUW5BX&keywords=streaming+systems&qid=1561728107&s=books&sprefix=Streaming+Systems,stripbooks,156&sr=1-2&linkCode=ll1&tag=mainstringarg-20&linkId=f07f59f79a517afbf479cd3642e61c3a&language=en_US"
              target="_blank">Amazon Link</a>
          </div>
        </div>
      </li>
      <li id="Streaming_Systems" class="book">
        <img id="img_Streaming_Systems" draggable="true" ondragstart="drag(event)" class="front" src="https://mainstringargs.github.io/bookshelf-data/assets/img/streaming_systems.jpg" alt="Streaming Systems">
        <div class="back" onclick="" id="ondeck_Streaming_Systems">
          <div class="p0">
            <span class="score"><span id="rating_Streaming_Systems"></span></span>
            <script>
              var span = document.getElementById("rating_Streaming_Systems");
              var rating = 4.5;
              var starWidth = (span.offsetWidth - paddingLeft - (5 * gapSize)) / 5.0;
              var gaps = Math.floor(rating);
              var width = (rating * starWidth) + (gaps * gapSize);
              span.style.width = `${width}px`;
              span.title = 4.5 + " out of 5";
            </script>
            <dl class="p10">
              <dt>Title:</dt>
              <dd>Streaming Systems</dd>
              <dt>Author:</dt>
              <dd>Tyler Akidau, Slava Chernyak & Reuven Lax</dd>
              <dt>Released:</dt>
              <dd>August 2, 2018</dd>
            </dl>
            <p class="description">
              Streaming data is a big deal in big data these days. As more and more businesses seek to tame the...
            </p>
            <a href="https://www.amazon.com/Streaming-Systems-Where-Large-Scale-Processing/dp/1491983876/ref=as_li_ss_tl?keywords=Streaming+Systems&qid=1564691718&s=gateway&sr=8-2&linkCode=ll1&tag=mainstringarg-20&linkId=3976bbc20ed7fc47509f68ea58a53b19&language=en_US"
              target="_blank">Amazon Link</a>
          </div>
        </div>
      </li>
      <li id="Clean_Code" class="book">
        <img id="img_Clean_Code" draggable="true" ondragstart="drag(event)" class="front" src="https://mainstringargs.github.io/bookshelf-data/assets/img/clean_code.jpg" alt="Clean Code">
        <div class="back" onclick="" id="ondeck_Clean_Code">
          <div class="p0">
            <span class="score"><span id="rating_Clean_Code"></span></span>
            <script>
              var span = document.getElementById("rating_Clean_Code");
              var rating = 4.3;
              var starWidth = (span.offsetWidth - paddingLeft - (5 * gapSize)) / 5.0;
              var gaps = Math.floor(rating);
              var width = (rating * starWidth) + (gaps * gapSize);
              span.style.width = `${width}px`;
              span.title = 4.3 + " out of 5";
            </script>
            <dl class="p10">
              <dt>Title:</dt>
              <dd>Clean Code</dd>
              <dt>Author:</dt>
              <dd>Robert C. Martin</dd>
              <dt>Released:</dt>
              <dd>August 11, 2008</dd>
            </dl>
            <p class="description">
              Best agile practices of cleaning code “on the fly” that will instill within you the values of a software craftsman...
            </p>
            <a href="https://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882/ref=as_li_ss_tl?_encoding=UTF8&pd_rd_i=0132350882&pd_rd_r=779f34be-10b6-4da1-bee1-315e02822e8a&pd_rd_w=cbXpV&pd_rd_wg=7e0si&pf_rd_p=1c11b7ff-9ffb-4ba6-8036-be1b0afa79bb&pf_rd_r=5DNWQZ8VE6S37W6B11GZ&psc=1&refRID=5DNWQZ8VE6S37W6B11GZ&linkCode=ll1&tag=mainstringarg-20&linkId=c0c7bb9dde941f0956bbee5628952f98&language=en_US"
              target="_blank">Amazon Link</a>
          </div>
        </div>
      </li>
      <li id="Weapons_of_Math_Destruction" class="book">
        <img id="img_Weapons_of_Math_Destruction" draggable="true" ondragstart="drag(event)" class="front" src="https://mainstringargs.github.io/bookshelf-data/assets/img/weapons_of_math_destruction.jpg" alt="Weapons of Math Destruction">
        <div class="back" onclick="" id="ondeck_Weapons_of_Math_Destruction">
          <div class="p0">
            <span class="score"><span id="rating_Weapons_of_Math_Destruction"></span></span>
            <script>
              var span = document.getElementById("rating_Weapons_of_Math_Destruction");
              var rating = 4.1;
              var starWidth = (span.offsetWidth - paddingLeft - (5 * gapSize)) / 5.0;
              var gaps = Math.floor(rating);
              var width = (rating * starWidth) + (gaps * gapSize);
              span.style.width = `${width}px`;
              span.title = 4.1 + " out of 5";
            </script>
            <dl class="p10">
              <dt>Title:</dt>
              <dd>Weapons of Math Destruction</dd>
              <dt>Author:</dt>
              <dd>Cathy O'Neil</dd>
              <dt>Released:</dt>
              <dd>September 6, 2016</dd>
            </dl>
            <p class="description">
              We live in the age of the algorithm. Increasingly, the decisions that affect our lives—where we go to school, whether...
            </p>
            <a href="https://www.amazon.com/Weapons-Math-Destruction-Increases-Inequality/dp/0553418815/ref=as_li_ss_tl?ie=UTF8&linkCode=ll1&tag=mainstringarg-20&linkId=e04f1e235dca487c6ea2eaf6050243d1&language=en_US" target="_blank">Amazon Link</a>
          </div>
        </div>
      </li>
      <li id="Microservices_in_Action" class="book">
        <img id="img_Microservices_in_Action" draggable="true" ondragstart="drag(event)" class="front" src="https://mainstringargs.github.io/bookshelf-data/assets/img/microservices_in_action.jpg" alt="Microservices in Action">
        <div class="back" onclick="" id="ondeck_Microservices_in_Action">
          <div class="p0">
            <span class="score"><span id="rating_Microservices_in_Action"></span></span>
            <script>
              var span = document.getElementById("rating_Microservices_in_Action");
              var rating = 4.4;
              var starWidth = (span.offsetWidth - paddingLeft - (5 * gapSize)) / 5.0;
              var gaps = Math.floor(rating);
              var width = (rating * starWidth) + (gaps * gapSize);
              span.style.width = `${width}px`;
              span.title = 4.4 + " out of 5";
            </script>
            <dl class="p10">
              <dt>Title:</dt>
              <dd>Microservices in Action</dd>
              <dt>Author:</dt>
              <dd>Morgan Bruce & Paulo A. Pereira</dd>
              <dt>Released:</dt>
              <dd>November 5, 2018</dd>
            </dl>
            <p class="description">
              Microservices in Action is a practical book about building and deploying microservice-based applications. Written for developers and architects with a...
            </p>
            <a href="https://www.amazon.com/Microservices-Action-Morgan-Bruce/dp/1617294454/ref=as_li_ss_tl?ie=UTF8&linkCode=ll1&tag=mainstringarg-20&linkId=74fa14a366397e614b1f8916f01d2464&language=en_US" target="_blank">Amazon Link</a>
          </div>
        </div>
      </li>
    </ul>
  </div>
</section>

Penafian, fungsi terdekat yang saya dapatkan untuk algoritme saya adalah dari di sini.

2
Islam Elshobokshy 12 Januari 2021, 08:08

Masalahnya adalah ketika Anda menjatuhkan di atas buku yang ada, target acaranya adalah elemen img dari buku yang ada. Saat Anda meletakkan di sisi kanan daftar, target acara adalah elemen ul yang berfungsi dengan benar.

Jawaban ini akan menyelesaikan masalah Anda: https://stackoverflow.com/a/28203782/9262488

Silakan lihat biola ini: https://jsfiddle.net/4gsrpv31/

Atau Anda dapat memeriksa target acara dan menambahkan ke simpul induknya jika itu adalah elemen img seperti di bawah ini:

function drop(ev) {
    ev.preventDefault();
    var data = ev.dataTransfer.getData("text");
    var appendNode = ev.target;
    if(appendNode.nodeName == "IMG")
        appendNode = appendNode.parentNode.parentNode;
    appendNode.appendChild(document.getElementById(data).parentNode);
}

Contoh: https://jsfiddle.net/n8t7Lory/

0
NiK648 11 Januari 2021, 09:32