Skip to content

Instantly share code, notes, and snippets.

@vinit-churi
Forked from prof3ssorSt3v3/index.html
Created March 13, 2022 15:50
Show Gist options
  • Save vinit-churi/f91b830f25df74a28abb6a59513ee869 to your computer and use it in GitHub Desktop.
Save vinit-churi/f91b830f25df74a28abb6a59513ee869 to your computer and use it in GitHub Desktop.

Revisions

  1. @prof3ssorSt3v3 prof3ssorSt3v3 created this gist Jul 10, 2021.
    45 changes: 45 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,45 @@
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0" />
    <link rel="stylesheet" href="./css/main.css" />
    <title>Drag 'n Drop</title>
    </head>
    <body>
    <header>
    <h1>Drag 'n Drop</h1>
    </header>
    <main>
    <section>
    <h2>Dragon</h2>
    <div class="cards">
    <div class="card draggable" draggable="true">
    <p>Just a paragraph with some text.</p>
    </div>
    <div class="card draggable" draggable="true">
    <a href="https://www.google.ca/">Google Link</a>
    </div>
    <div class="card draggable" draggable="true">
    <img src="img/dragon-1.jpg" alt="dragon image 1" />
    </div>
    <div class="card draggable" draggable="true">
    <img src="img/dragon-2.jpg" alt="dragon image 2" />
    </div>
    </div>
    <!--
    all images from pexels.com
    -->
    </section>
    <section class="drop">
    <h2>Droppin'</h2>
    <div class="dropzone">&nbsp;</div>
    </section>
    </main>
    <footer>
    <p>&copy; 2021 Chicken Stuff Inc.</p>
    </footer>
    <script src="./js/main.js"></script>
    </body>
    </html>
    86 changes: 86 additions & 0 deletions main.css
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,86 @@
    *,
    *::before,
    *::after {
    padding: 0;
    margin: 0;
    box-sizing: border-box;
    }
    html {
    font-size: 20px;
    font-weight: 300;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
    Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
    line-height: 1.5;
    }
    body {
    min-height: 100vh;
    background-color: #333;
    color: #eee;
    }
    header,
    main,
    footer {
    width: 80vw;
    padding: 1rem 2rem;
    margin: 0 auto;
    }
    header h1 {
    color: orange;
    }
    header h2 {
    color: orangered;
    }
    main {
    display: flex;
    justify-content: space-between;
    }
    section {
    flex: 0 1 30vw;
    padding: 2rem;
    border: 1px solid #fff;
    }
    p {
    line-height: 1.7;
    margin: 1.5rem 0;
    }
    a {
    color: orange;
    }
    img {
    width: 100%;
    }

    .draggable {
    cursor: grab;
    padding: 0;
    margin: 1rem 0;
    /* outline: 1px solid gold; */
    }
    section.drop {
    height: auto;
    display: grid;
    gap: 0.5rem;
    grid-template-rows: 3rem 1fr;
    }
    .dropzone {
    background-color: #111;
    min-height: 300px;
    width: 100%;
    }
    .dropzone.over {
    border: 1px solid gold;
    background-color: hsla(90, 100%, 90%, 0.1);
    }
    .wheeeee {
    background-color: greenyellow;
    color: black;
    border: 1px solid rebeccapurple;
    font-size: 2rem;
    position: absolute;
    transform: translateX(-100vw);
    }
    footer img {
    width: 100px;
    position: absolute;
    transform: translateX(-100vw);
    }
    120 changes: 120 additions & 0 deletions main.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,120 @@
    let imgElement = new Image();
    let dragElement = document.createElement('span');
    let myData = {
    id: 123,
    tag: 'p',
    text: 'Just a paragraph',
    timestamp: 0,
    url: '',
    };

    document.addEventListener('DOMContentLoaded', () => {

    //required event listeners
    document.body.addEventListener('dragstart', handleDragStart); //for draggable
    document.body.addEventListener('drop', handleDrop); //for dropzone
    document.body.addEventListener('dragover', handleOver); //for dropzone

    //optional but useful events
    document.body.addEventListener('mousedown', handleCursorGrab);
    document.body.addEventListener('dragenter', handleEnter);
    document.body.addEventListener('dragleave', handleLeave);

    //set up draggable things (non-ios)
    imgElement.src = './img/dragon-3.jpg';
    document.querySelector('footer>p').appendChild(imgElement);
    dragElement.textContent = 'Wheeeee';
    dragElement.classList.add('wheeeee');
    document.querySelector('footer>p').appendChild(dragElement);
    });

    function handleDragStart(ev) {
    //user started to drag a draggable from the webpage
    let obj = ev.target;
    if (!obj.closest('.draggable')) return;
    if(obj.classList.contains('draggable')){
    obj = obj.firstElementChild;
    }
    // console.log('DRAGSTART');
    // ev.dataTransfer.setDragImage(dragElement, 50, 50);
    // ev.dataTransfer.setDragImage(imgElement, 50, 50);
    // ev.dataTransfer.setData('text/plain', ' No MORE DATA ');

    myData.tag = obj.tagName;
    myData.text = obj.textContent?obj.textContent:obj.alt?obj.alt:'';
    myData.url = obj.href?obj.href: obj.src? obj.src:'';
    myData.timestamp = Date.now();
    let data = JSON.stringify(myData);
    ev.dataTransfer.setData('application/json', data);
    obj.setAttribute('data-ts', myData.timestamp);

    let dataList = ev.dataTransfer.items;
    for(let i=0; i<ev.dataTransfer.items.length; i++){
    let item = ev.dataTransfer.items[i];
    // console.log(i, item.kind, item.type);
    }

    }
    function handleDrop(ev) {
    let dropzone = ev.target;
    if (!dropzone.classList.contains('dropzone')) return;

    ev.preventDefault();
    // console.log('DROP', ev.dataTransfer);
    // let data = ev.dataTransfer.getData('text/plain');
    let data = JSON.parse(ev.dataTransfer.getData('application/json'));
    let draggable = document.querySelector(`[data-ts="${data.timestamp}"]`);
    let clone = draggable.cloneNode(true);
    dropzone.append(clone);
    draggable.remove();

    // dropzone.textContent += data;
    dropzone.classList.remove('over');

    let len = ev.dataTransfer.items.length;
    for(let i = 0; i < len; i++){
    let item = ev.dataTransfer.items[i];
    if(item.kind === 'string' && item.type.match('^text/html')){
    //i got an html element
    }
    if(item.kind==='string' && item.type.match('^application/json')){
    //same as before... except the method getAsString
    item.getAsString((json)=>{
    let data = JSON.parse(json);
    console.log('timestamp was', data.timestamp);
    })
    }
    }


    }
    function handleOver(ev) {
    //fires continually
    let dropzone = ev.target;
    if (!dropzone.classList.contains('dropzone')) return;
    ev.preventDefault();
    // dropzone.classList.add('over'); //can do this in handleEnter
    // console.log('dragover dropzone');
    }

    //optional but useful visual stuff...
    function handleCursorGrab(ev) {
    let obj = ev.target;
    if (!obj.closest('.draggable')) return;
    obj.style.cursor = 'grabbing'; //close the hand
    }
    function handleEnter(ev) {
    //fires once
    let dropzone = ev.target;
    if (!dropzone.classList.contains('dropzone')) return;
    ev.preventDefault();
    dropzone.classList.add('over');
    // console.log('dragenter dropzone')
    }
    function handleLeave(ev) {
    let dropzone = ev.target;
    if (!dropzone.classList.contains('dropzone')) return;
    ev.preventDefault();
    dropzone.classList.remove('over');
    // console.log('dragleave dropzone');
    }