Table of Contents for
The Modern Web

Version ebook / Retour

Cover image for bash Cookbook, 2nd Edition The Modern Web by Peter Gasston Published by No Starch Press, 2013
  1. The Modern Web
  2. Cover
  3. The Modern Web
  4. Advance Praise for
  5. Praise for Peter Gasston’s
  6. Dedication
  7. About the Author
  8. About the Technical Reviewer
  9. Acknowledgments
  10. Introduction
  11. The Device Landscape
  12. The Multi-screen World
  13. Context: What We Don’t Know
  14. What You’ll Learn
  15. A. Further Reading
  16. 1. The Web Platform
  17. A Quick Note About Terminology
  18. Who You Are and What You Need to Know
  19. Getting Our Terms Straight
  20. The Real HTML5
  21. CSS3 and Beyond
  22. Browser Support
  23. Test and Test and Test Some More
  24. Summary
  25. B. Further Reading
  26. 2. Structure and Semantics
  27. New Elements in HTML5
  28. WAI-ARIA
  29. The Importance of Semantic Markup
  30. Microformats
  31. RDFa
  32. Microdata
  33. Data Attributes
  34. Web Components: The Future of Markup?
  35. Summary
  36. C. Further Reading
  37. 3. Device-Responsive CSS
  38. Media Queries
  39. Media Queries in JavaScript
  40. Adaptive vs. Responsive Web Design
  41. Viewport-Relative Length Units
  42. Responsive Design and Replaced Objects
  43. Summary
  44. D. Further Reading
  45. 4. New Approaches to CSS Layouts
  46. Multi-columns
  47. Flexbox
  48. Grid Layout
  49. The Further Future
  50. Summary
  51. E. Further Reading
  52. 5. Modern JavaScript
  53. New in JavaScript
  54. JavaScript Libraries
  55. Polyfills and Shims
  56. Testing and Debugging
  57. Summary
  58. F. Further Reading
  59. 6. Device Apis
  60. Geolocation
  61. Orientation
  62. Fullscreen
  63. Vibration
  64. Battery Status
  65. Network Information
  66. Camera and Microphone
  67. Web Storage
  68. Drag and Drop
  69. Interacting with Files
  70. Mozilla’s Firefox OS and WebAPIs
  71. PhoneGap and Native Wrappers
  72. Summary
  73. G. Further Reading
  74. 7. Images and Graphics
  75. Comparing Vectors and Bitmaps
  76. Scalable Vector Graphics
  77. The canvas Element
  78. When to Choose SVG or Canvas
  79. Summary
  80. H. Further Reading
  81. 8. New Forms
  82. New Input Types
  83. New Attributes
  84. Datalists
  85. On-Screen Controls and Widgets
  86. Displaying Information to the User
  87. Client-side Form Validation
  88. The Constraint Validation API
  89. Forms and CSS
  90. Summary
  91. I. Further Reading
  92. 9. Multimedia
  93. The Media Elements
  94. Media Fragments
  95. The Media API
  96. Media Events
  97. Advanced Media Interaction
  98. Summary
  99. J. Further Reading
  100. 10. Web Apps
  101. Web Apps
  102. Hybrid Apps
  103. TV Apps
  104. Webinos
  105. Application Cache
  106. Summary
  107. K. Further Reading
  108. 11. The Future
  109. Web Components
  110. The Future of CSS
  111. Summary
  112. L. Further Reading
  113. M. Browser Support as of March 2013
  114. The Browsers in Question
  115. Enabling Experimental Features
  116. Chapter 1: The Web Platform
  117. Chapter 2: Structure and Semantics
  118. Chapter 3: Device-Responsive CSS
  119. Chapter 4: New Approaches to CSS Layouts
  120. Chapter 5: Modern JavaScript
  121. Chapter 6: Device APIs
  122. Chapter 7: Images and Graphics
  123. Chapter 8: New Forms
  124. Chapter 9: Multimedia
  125. Chapter 10: Web Apps
  126. Chapter 11: The Future
  127. N. Further Reading
  128. Introduction
  129. Chapter 1: The Web Platform
  130. Chapter 2: Structure and Semantics
  131. Chapter 3: Device-Responsive CSS
  132. Chapter 4: New Approaches to CSS Layouts
  133. Chapter 5: Modern JavaScript
  134. Chapter 6: Device APIs
  135. Chapter 7: Images and Graphics
  136. Chapter 8: New Forms
  137. Chapter 9: Multimedia
  138. Chapter 10: Web Apps
  139. Chapter 11: The Future
  140. Index
  141. About the Author
  142. Copyright

Drag and Drop

Adding a “physical” aspect to your websites that allows users to move elements around the screen is a nice option. This “drag and drop” behavior is especially useful on devices with touch interfaces.

The Drag and Drop API is probably the oldest feature I cover in this book. It was first implemented in Internet Explorer 5 back in 1999 (that’s about 150 Internet years ago) and has been adopted by other browsers for quite some time, although the effort to standardize it was only undertaken as part of the HTML5 movement. Unfortunately, Drag and Drop shows some signs of aging, being quite arcane and unintuitive at first.

By default the a and img elements can be dragged around the screen (I’ll get to other elements momentarily), but you have to set up a drop zone, an area that the elements can be dragged into. A drop zone is created when you attach two events to an element: dragover and drop. All that’s required of dragover is that you cancel its default behavior (for one of the arcane reasons I noted earlier, which you don’t need to worry about). All the hard work happens with the drop event.

That may sound a little confusing, so this example shows a very simple setup: The #target element has the dragover and drop event listeners attached to it, the callback function of dragover prevents the default behavior with preventDefault(), and the main action happens inside the callback function of the drop event.

var target = document.getElementById('target');
target.addEventListener('dragover', function (e) {
  e.preventDefault();
}, false);
target.addEventListener('drop', function (e) {
  // Do something
}, false);

All of the events in the Drag and Drop API create an object called dataTransfer, which has a series of relevant properties and methods. You want to access these when the drop event is fired. For img elements, you want to get the URL of the item, so for this you use the getData() method with a value of URL and then do something with it; in this example, I’ll create a new img element and pass the URL to the src attribute, making a copy of the existing one:

target.addEventListener('drop', function (e) {
  e.preventDefault();
  var newImg = document.createElement('img');
  newImg.setAttribute('src', e.dataTransfer.getData('URL'));
  e.currentTarget.appendChild(newImg);
}, false);

Note the use of preventDefault() again inside the function on the drop callback; using this is important, because in most (if not all) browsers the default behavior after dropping an item into a drop zone is to try to open its URL. This is part of Drag and Drop’s arcane behavior. All you really need to know is to use preventDefault() to stop this from happening.

You can see a simple example based on the previous code in the file drag-drop.html—just drag the image from its starting position to inside the box.

I said previously that, by default, only a and img elements are draggable, but you can make that true of any element in two steps. First, apply the true value to the draggable attribute of the element in question:

<div draggable="true" id="text">Drag Me</div>

Second, specify a datatype for the element. You do this with the dragstart event, using the setData() method of dataTransfer to apply a MIME type (in this case, text/plain) and a value (in this case, the text content of the element):

var txt = document.getElementById('txt');
  txt.addEventListener('dragstart', function (e) {
  e.dataTransfer.setData('text/plain', e.currentTarget.textContent);
}, false);

You can detect the type of file being dropped by using the contains() method, which is a child of the types object, itself a child of the dataTransfer object created in the callback function of the drop event. The method returns true or false if the string supplied in the argument matches a value in types; for example, to find out if a dropped element contains a plain text type, you would use this:

var foo = e.dataTransfer.types.contains('text/plain');

Using the contains() method means you can perform different actions on different files.

The example file drag-drop-2.html shows two elements, an img and a p, which can be dragged into the marked drop zone, creating a copy of each, and the following code shows how this is done: The contains() method detects if the element being dragged contains a URL; if it does, it must be an img, so it creates a new img element with the URL of the dropped element in the src attribute; if it doesn’t, it must be text, so it creates a new text node filled with the text of the dropped element.

target.addEventListener('drop', function (e) {
  var smth;
  e.preventDefault();
  if (e.dataTransfer.types.contains('text/uri-list')) {
    smth = document.createElement('img');
    smth.setAttribute('src', e.dataTransfer.getData('URL'));
  } else {
    smth = document.createTextNode(e.dataTransfer.getData('Text'));
  }
  e.currentTarget.appendChild(smth);
}, false);

Although what I’ve described in this section is more than sufficient for you to use the Drag and Drop API, the API contains plenty more that I haven’t covered. If you’re interested, a number of extra events are available: dragenter and dragleave are events for the drop zone, and dragend and drag are fired on the draggable item.