Skip to content

Latest commit

 

History

History
248 lines (184 loc) · 13 KB

JS-DragNDrop.md

File metadata and controls

248 lines (184 loc) · 13 KB

Drag and Drop

Overview

data-* Attribute

  • data attribute

    • storing extra info on standard elements w/o other hacks
    • html syntax: data attribute: any attribute started w/ data-
    • Javascrip access
      • using getAttribute() w/ their full HTML name to read
      • alternative: reading out via a dataset property
  • data-* attributes

    • metadata: a powerful way to add structured data into HTML code
    • HTML5 adding the possibility of adding arbitrary data to an HTML element
      • attributes starting w/ data- followed by any string literal (w/o uppercase)
      • treated as a storage area for private data
    • some classic attributes, including alt, rel and title, misused for storing arbitrary data
    • official way to add arbitrary data to HTML elements
    • custom data attributes: intended to store customer data private to the page or application
    • creating and accessing data attributes by the dataset property
    • attr() function: taking an attribute name as a parameter and return its value
    • examples:
      • invalid: <img src="photo.jpg" photographer="Michel Buffa" date="14July2020">
      • valid: <img src="photo.jpg" data-photographer="Michel Buffa" date="14July2020">
  • Example: accessing dataset property

    • task: access data- attributes w/ dataset property
  • Example: adding data- attributes w/ CSS

    • task: using attr() in CSS to take an attribute name as a parameter and return its value

Drag Detection

  • Draggable attribute

    • making any visible element draggable w/ true value
    • some elements draggable by default, such as <img>
    • example: <li draggable=true data-value="fruit-apple">Apple</li>
  • dragstart event

    • add listener to detect a drag
    • ondragstart for HTML event handler
    • inheritance of handler: each of its children triggering the event
    • example: <ol ondragstart="dragStartHandler(evt)"> ... </ol>
  • Example: draggable attribute and event handler

Drop Detection

  • Procedure to handle drop

    1. in the dragstart handler, copy a value in the drag and drop clipboard for later use
    2. define a "drop zone"
    3. write a drop handler, fetch content from the clipboard , and do something with it
  • Utilizing drag and drop clipboard

    • get the value of the data-value attribute from the dragged element w/ dragStart handler
    • copy the obtained value into "drag and drop clipboard"
    • data as key/value pair
    • example: function dragStartHandler(evt) { evt.dataTransfer.setData("Fruit", evt.target.dataset.value); }
  • Defining drop zone

    • any visible element if drop event listener attached
    • listen for dragover or dragend events and stop their propagation
    • mouse moving over any drop zone triggering dragover event
    • a few dragover events to be handled before the element finally dropped
    • ondragover handler used to avoid propagating dragover events
    • example: <div ondragover="return false" ondrop="dropHandler(event);">...</div>
  • Processing fetched content w/ drop handler

    • drop event triggered once the dragged element placed
    • acquiring data from "drag and drop clipboard"
    • example: function dropHandler(evt) { var data = evt.dataTransfer.getData("Fruit"); // do sth. w/ the data }
  • Example: handling drag and drop

    • tasks
      • define drop zone and prevent event propagation
      • copy data-value of dragged element into drag'n'drop clipboard
      • handle drop event to fetch data and add dropped-item as a listed item

Visual Feedback

  • Visual feedback for drag & drop

    • scenarios
      • when drag something
      • when mouse enters a drop zone
      • etc.
    • associating CSS styling w/ the lifecycle of a drag and drop
  • Events related to draggable object

    • dragstart:
      • used on draggable elements
      • used to get a value from the dragged element
      • copying value to the clipboard
      • good practice: visual feedback on draggable elements
    • dragend:
      • launched as the drag ended
      • on a drop or if the user releases the mouse button outside a drop zone
      • best practice: reset the style of the draggable object to default
    • dragenter:
      • binding the event to the drop zone
      • occurred when a dragged object enters a drop zone
      • good practice: change the appearance of the drop zone
    • dragleave:
      • used in relation to the drop zone
      • good practice: set appearance back to normal once leaving the drop zone
    • dragover:
      • generally bound to elements corresponding to a drop zone
      • best practice: preventing the propagation of the event and the default behavior of the browser
    • drop:
      • on the drop zone and processing the the drop, such as getting the value from the clipboard, etc.
      • good practice: reset the look of the drop zone to default
  • Example: visualizing the drag and

  • Example: visual feedback on draggable object and the drop zone

The dropEffect Property

  • The dropEffect property

    • changing the cursor's shape during the drag process
    • turning cursor into a "copy", "move" or "link" icon, depending on the semantic of the drag and drop
      • copy icon: copying an object into the drop zone
      • moving icon: moving an object
      • link icon: making a link or shortcut
    • alternative: using any customized image/icon
    • visual feedback:
      • using the effectAllowed and dropEffect properties of the dataTransfer object
      • specifying an effect in the dragStart handler by setting one of the possible predefined cursors
      • specifying the effect (to "copy", "move", etc.) in the dragEnter and dragOver handlers
  • Possible values for dropEffect and effectAllowed properties

    • dataTransfer.effectAllowed: none, copy, copyLink, copyMove, link, linkMove, move, all, uninitialized
    • dataTransfer.dropEffect: none, copy, link, move
  • Syntax of visual effect for drag and drop

    • allow a copy cursor effect: function dragStartHandler(evt) { evt.dataTransfer.effecctAllowed = 'copy'; ... }
    • change the cursor shape to a '+': function dragEnterHandler(evt) { evt.dataTransfer.dropEffect = 'copy'; ... }
  • Example: customerized image

HTML Elements for Drag and Drop

  • Drag and drop HTML elements

    • copy and past to/from the clipboard
    • clipboard accessed through the dataTransfer property of the different evnets
      • copy data into the clipboard: event.dataTransfer.setData("Fruit", event.targte.dataset.value);
      • past data from the clipboard: var data = event.dataTransfer.getData("Fruit");
    • <img> elements all draggable by default
  • Example: moving images as an HTML subtree

    • tasks
      • only work on the DOM directly
      • move icon from child of <body> to child of selected container

Text Drag and Drop

  • Moving selected text

    • no need to add a dragstart handler on an element containing text
    • selected text automatically added to the clipboard w/ a name/key equal to "text/plain"
    • adding a drop event handler on the drop zone
    • "text/plain" as the access key to fetch the data from the clipboard
    • typical syntax: function drop(target, event) { event.preventDefault(); target.innerHTML = event.dataTransfer.getData('text/plain'); }
  • Example: moving selected text to the drop zone

    • tasks:
      • use a CSS trick to make a paragraph non-selectable
      • move selected text to a drop zone

Files Drag and Drop

Prevent Default Behavior

  • Prevent browser's deafult behavior

    • default behavior
      • dropping an image into an HTML page $\to$ open a new tab and display the image
      • dropping a mp3 file $\to$ open a new tab and start streaming the audio w/ a default player
    • two functions to prevent the default behavior of the browser
      • not propagating the event: event.stopPropagation();
      • preventing default behavior, in particular when dropping images or links: event.preventDefault();
    • best practice: add event.stopPropagation and event.preventDefault to handlers attached to the drop zone
      • the drop handler
      • the dragOver handler
    • ref: R. Gravelle, Drag Files Into the Browser From the Desktop with HTML5, 2012
  • Example: preventing default behavior

Drop Zone

  • Example: moving files to drop zone w/ filenames
    • tasks
      • prevent the browser default behavior
      • create listed items for the drop zone
    • HTML snippet:
      • drop zone container: <div id="droppableZone" ondragenter="dragEnterHandler(event)" ondrop="dropHandler(event)" ondragover="dragOverHandler(event)" ondragleave="dragLeaveHandler(event)"> Drop Zone ...</div>
      • display zone: <ol id="droppedFiles"></ol>

Image Files and Thumbnails