欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

html5拖放api_使用HTML5的本机拖放API

程序员文章站 2022-05-26 20:37:16
...

html5拖放api

Everyone loves an easy-to-use and interactive user interface and ever since the introduction of smartphones there has been a jump in expectations from users; The expectation is that your website will be intuitive, will use universally understood actions, and overall proving an easy way to engage with your site.

每个人都喜欢易于使用和交互式的用户界面,并且自从引入智能手机以来,用户的期望就不断提高。 期望您的网站将是直观的,将使用普遍理解的操作,并且总体上证明了与网站互动的简便方法。

Giving your users the ability to drag, drop, and sort makes your site more intuitive as people understand how to move element X to position Y and that moving object A in front of object B makes object A come first.

由于人们了解如何将元素X移动到位置Y,并且对象B前面的移动对象A使对象A成为第一位用户,因此赋予用户用户拖放和排序的能力可使您的站点更加直观。

Handling dragging, dropping, and sorting has always been a task for JavaScript and developers have previously had the option of building their own interactions or to use a prebuilt solution. With the advent of the HTML5 Drag and Drop API, developers will be able to hook into native events and attributes to handle these interactions.

拖放,排序和排序一直是JavaScript的任务,并且开发人员以前可以选择构建自己的交互或使用预构建的解决方案 。 随着HTML5拖放API的出现 ,开发人员将能够加入本机事件和属性来处理这些交互。

简介 (A Brief Introduction)

Lets go through the API so we can get an overview of how it all works.

让我们浏览一下API,以便我们可以大致了解其工作原理。

The native API lets us define elements that are draggable by using the draggable="true" attribute on your desired elements. Some elements are by default draggable even without any modifications (such as images or text).

原生API允许我们通过在所需元素上使用draggable="true"属性来定义可拖动的元素。 默认情况下,某些元素即使未进行任何修改也可以拖动(例如图像或文本)。

html5拖放api_使用HTML5的本机拖放API

By default when draggable elements are dragged, only form elements such as input will be able to accept them as a drop. You would have seen this before; if you select some text and drag it into a textarea the text is copied into the textarea element.

默认情况下,当拖动可拖动元素时,只有诸如input form元素才能将其接受为放置。 您之前已经看过; 如果选择一些文本并将其拖动到textarea该文本将被复制到textarea元素中。

html5拖放api_使用HTML5的本机拖放API

The native API also handles drags from external areas on your OS onto your drop zones. Almost all good Content Management Systems provide drag and drop uploading of content. Since these elements are external, all you need to configure is the drop zone (and also have a compatible browser).

本机API还可以处理从操作系统外部区域到拖放区的拖动。 几乎所有好的内容管理系统都可以拖放内容。 由于这些元素是外部的,因此您只需配置拖放区(并且还具有兼容的浏览器)即可。

html5拖放api_使用HTML5的本机拖放API

关于移动设备的快速说明 (A quick note about mobile devices)

Currently the native API doesn’t support mobile devices. While this may change in the future, it’s best to view the examples from a desktop browser so you can see how it all works

当前,本机API不支持移动设备。 尽管将来可能会有所改变,但最好从桌面浏览器查看示例,以便了解其工作原理

拖放API事件 (Drag and Drop API Events)

The native API provides the following events that you can listen for. These events will apply to either the draggable item or the drop zone and will be triggered at set times.

本机API提供了以下事件 ,您可以监听。 这些事件将应用于可拖动项目放置区域 ,并将在设置的时间触发。

When these events are fired, we have access to a local object (which we will call event). This object holds more information about the event itself and will give you access to the dataTransfer object where you will set most of your methods and properties.

触发这些事件后,我们可以访问本地对象(我们将其称为event )。 该对象包含有关事件本身的更多信息,并将使您可以访问dataTransfer对象,在其中将设置大多数方法和属性。

We will need to hook a callback function onto each of the events so we can interact with the API:

我们将需要在每个事件上挂钩一个回调函数,以便我们可以与API进行交互:

// add a handler to trigger on dragstart
document.addEventListener('dragstart', function(event) {
  // add your dragstart code here
}, false);

拖曳相关事件 (Drag-related Events)

These events are triggered only on draggable items.

这些事件仅在可拖动项目上触发。

dragstart Triggered as soon as we start dragging. It’s here we will need to tell the API about what we will be dragging and set up other values. Use the setData() method to set the data you want to save, set the effectAllowed property for the draggable element, and define the draggable helper with setDragImage().

dragstart一开始拖动就触发。 在这里,我们需要告诉API我们将要拖动的内容并设置其他值。 使用setData()方法设置要保存的数据,设置可拖动元素的effectAllowed属性,并使用setDragImage()定义可拖动帮助器。

drag This event is triggered continually during dragging. The number of times it occurs depends on the browser. This is useful for determining exactly where the draggable item is.

拖动在拖动过程中会连续触发此事件。 发生次数取决于浏览器。 这对于确定可拖动项目的确切位置很有用。

dragend This is event fires as soon as the draggable is dropped (regardless of where it is dropped) and generally triggered directly after the drop zone’s drop event. You can use this event to reset styles applied when dragging or to perform other cleanup actions. The dragend event has access to the draggable so you can do calculations after dragging has ended (for example seeing if the drop event was successful by looking for newly added elements and then removing the original draggable).

dragend这是事件,一旦拖放了可拖动对象(无论它放置在何处),就会触发该事件,并且通常在放置区域的drop事件之后直接触发。 您可以使用此事件来重置拖动时应用的样式,或执行其他清除操作。 dragend事件可以访问可拖动对象,因此您可以在拖动结束后进行计算(例如,通过查找新添加的元素然后删除原始可拖动对象来查看drop事件是否成功)。

掉落相关事件 (Drop-related Events)

These events are triggered only on elements that you specify as drop targets (or are already naturally drop targets, like form elements):

这些事件仅在您指定为放置目标的元素上触发(或者已经自然成为放置目标,例如表单元素):

dragenter Triggered just once as soon as a draggable enters a droppable area. This will trigger when more than 50% of the draggable is inside the drop zone.

dragenter一旦可拖动对象进入可放置区域,就会触发一次。 当超过50%的可拖动对象位于放置区域内时,这将触发。

This event sets the dropEffectof the drop zone. By default drops on non-form elements won’t do anything. You will need to manually call event.preventDefault() and event.stopPropagation() to tell the API that this drop should take place.

此事件设置放置区域的dropEffect 。 默认情况下,放置在非格式元素上不会执行任何操作。 您将需要手动调用event.preventDefault()event.stopPropagation()来告诉API应该发生此删除操作。

You can check the dataTransfer object for the effectAllowed value that has been set by the draggable and then compare it to the value your drop zone has for its dropEffect. If these values won’t work together (i.e one is copy and the other is link) then the browser won’t drop the item successfully (even if you prevented defaults and stopped propagation).

您可以在dataTransfer对象中检查可拖动对象设置的effectAllowed值,然后将其与放置区域的dropEffect值进行比较。 如果这些值不能一起使用(即一个是copy ,另一个是link ),则浏览器将不会成功删除该项目(即使您阻止了默认设置并停止了传播)。

You can use the types property to get a list of all data types that have been set in the dragstart event. You can’t see the data but you can see its type. It’s here you can use another method called contains to see if a certain type of data has been set up. This is done via the event.dataTransfer.types.contains(type) method. You could use this to ensure that something has been set to the text/html type for example.

您可以使用types属性获取在dragstart事件中设置的所有数据类型的列表。 您看不到数据,但可以看到其类型。 在这里,您可以使用另一个名为contains方法来查看是否已设置某种类型的数据。 这是通过event.dataTransfer.types.contains(type)方法完成的。 例如,您可以使用它来确保已将某些内容设置为text/html类型。

You can set classes or trigger actions now that you know your draggable has entered into the drop zone (a common theme is to style the drop zone differently to show it is being activated).

现在,您就知道您的可拖动对象已进入拖放区(您可以将拖放区设置为不同的样式以显示其已被**),就可以设置类或触发操作。

dragover This event is essentially the same as dragenter but it is called continually while the draggable item is inside the drop zone. This event is perfect if you want to determine the exact position of the draggable (because it is updated continually).

dragover此事件本质上与dragenter相同,但是在可拖动项位于放置区域内时会连续调用。 如果您想确定可拖动对象的确切位置(因为它会不断更新),则此事件是完美的。

This event sets the dropEffect of the drop zone and, like dragenter, you will need to prevent default and propagation.

此事件设置拖放区的dropEffect ,与dragenter一样,您将需要防止默认设置和传播。

dragleave This is triggered once a draggable has moved away from a drop zone. It’s generally used to remove styles added in either the dragenter or dragover events and fires once the draggable is not overlapping with the drop zone.

dragleave一旦可拖动对象从放置区域移开,就会触发该事件。 通常用于删除在dragenterdragover事件中添加的样式,并在可拖动对象与放置区域不重叠时触发。

drop This event is triggered once the draggable has been released and the drop area agrees to accept the drop. This will only fire if the draggable element and the drop area have correct dropEffect andeffectAllowed values. On drop you will need to collect the information using the getData() method.

drop一旦释放了可拖动对象并且放置区域同意接受放置,就会触发此事件。 仅当可拖动元素和放置区域具有正确的dropEffecteffectAllowed值时effectAllowed 。 拖放时,您将需要使用getData()方法收集信息。

拖放API方法 (Drag and Drop API Methods)

The dataTransfer object is the main item we will interact with when dealing with the native drag and drop API. It is exposed to us as part of the callback function for the events and gives us several functions to play with.

dataTransfer对象是在处理本机拖放API时将与之交互的主要项目。 它作为事件的回调函数的一部分提供给我们,并为我们提供了几个可以使用的函数。

setData This method sets the data that will be collected from the draggable by calling the event.datatransfer.setData(type, data) method. You will need to pass in the type of data being saved and the data itself. This must be set in the dragstart event or it will fail. Its values can only be collected later during the drop event.

setData此方法通过调用event.datatransfer.setData(type,data)方法设置将从可拖动对象中收集的数据 。 您将需要输入要保存的数据类型和数据本身。 这必须在dragstart事件中设置,否则将失败。 它的值只能在drop事件期间稍后收集。

The type argument should be an applicable data type. You can use many different types such as text/html or text/uri-list if you are using Chrome, Safari, or Firefox. If you are using Internet Explorer you must set it as Text or URL (in exactly that way or it will cause an error).

type参数应为适用的数据类型 。 如果您使用的是Chrome,Safari或Firefox,则可以使用许多不同的类型,例如text/htmltext/uri-list 。 如果您使用的是Internet Explorer,则必须将其设置为“ Text或“ URL (否则将导致错误)。

The data argument is the data you want to save. You can save a URL, a chunk of HTML, or any other piece of data. You can set only one piece of data per type. For example if you set text/html to be some HTML, you can’t then call the setData() method again with new information as it will replace the old content.

data参数是您要保存的数据。 您可以保存一个URL,一段HTML或任何其他数据。 每个type只能设置一个数据。 例如,如果将text/html设置为某些HTML,则不setData()使用新信息再次调用setData()方法,因为它将替换旧内容。

getData This is the counterpart to the setData() method and it’s used to collect data set by the dragged element during the startdrag event. You collect your data by calling event.dataTransfer.getData(type), specifying the type of data to be collected.

getData这与setData()方法相对应,它用于在startdrag事件期间收集由拖动的元素设置的数据。 通过调用event.dataTransfer.getData(type)收集数据,指定要收集的数据类型。

You will most likely have to check what types are set using event.dataTransfer.types to see what formats have been passed. If you try and access data types that have not been set, Internet Explorer will throw an error.

您很可能必须使用event.dataTransfer.types检查设置了哪些类型,以查看已传递了哪些格式。 如果您尝试访问尚未设置的数据类型,则Internet Explorer将引发错误。

This method can be used only inside the drop event as only at that point does the API expose the values so you can collect them (this is to protect the data during transmission).

此方法只能在drop事件内部使用,因为仅在那时API会公开这些值,以便您可以收集它们(这是为了在传输期间保护数据)。

clearData This does exactly what its name implies, it clears any data set using setData and it’s written in the format: event.dataTransfer.clearData(type). You will need to specify the type of data that is being cleared (e.g. text/html or URL). This method can only be used inside the dragstart event.

clearData确实如其名称所暗示的那样,它使用setData清除任何数据集,并以以下格式编写: event.dataTransfer.clearData(type) 。 您将需要指定要清除的数据类型(例如text/htmlURL )。 此方法只能在dragstart事件中使用。

setDragImage This method sets the drag image to be displayed when dragging starts using the format: event.dataTransfer.setDragImage(). By default, when dragging, the user will see a semi-transparent image of what they are dragging. Using this method you can define your own image or element to appear during the drag. This works in all browsers except Internet Explorer and there is currently no planned work for it’s inclusion either.

setDragImage此方法设置拖动开始时使用以下格式显示的拖动图像: event.dataTransfer.setDragImage() 。 默认情况下,在拖动时,用户将看到他们正在拖动的内容的半透明图像。 使用此方法,您可以定义自己的图像或元素,以在拖动过程中显示。 这适用于Internet Explorer以外的所有浏览器,并且目前也没有计划的工作

拖放API属性 (Drag and Drop API Properties)

There are several properties that we can set for the dataTransfer object. We use our event variable that’s passed to us from the event callback to set these properties.

我们可以为dataTransfer对象设置几个属性 。 我们使用从事件回调传递给我们的事件变量来设置这些属性。

effectAllowed This is specified on the draggable item. This tells the API about the drag event and what icons will be used for the cursor (this is OS and browser dependent). It’s called by assigning a value to event.dataTransfer.effectAllowed inside the dragstart event and takes the possible values of copy, move ,link ,copyLink, copyMove, linkMove, all, none, or uninitialized.

effectAllowed在可拖动项目上指定。 这告诉API有关拖动事件以及将用于光标的图标(这取决于操作系统和浏览器)。 通过在dragstart事件中为event.dataTransfer.effectAllowed分配值来调用它,并采用copymovelinkcopyLinkcopyMovelinkMoveallnone或未uninitialized的可能值。

If this value doesn’t match dropEffect it will prevent the drop event being called (ensures only appropriate drops happen).

如果此值与dropEffect不匹配,它将阻止调用drop事件(确保仅发生适当的drop)。

dropEffect This property is specified on the drop zone and determines what drag items are allowed to drop on this zone. It should be assigned a value via event.dataTransfer.dropEffect during the dragenter or dragover events. dropEffect Takes the possible values of copy, link, move, or none.

dropEffect在放置区域上指定此属性,并确定允许哪些拖动项放置在该区域上。 在dragenterdragover事件期间,应通过event.dataTransfer.dropEffect为其分配一个值。 dropEffect接受copylinkmovenone的可能值。

Just like effectAllowed, if this value doesn’t match effectAllowed it will prevent the drop event being called (ensures only appropriate drops happen).

就像effectAllowed一样,如果此值与effectAllowed不匹配,它将防止调用drop事件(确保仅发生适当的drop操作)。

files This property contains a list of all local files that have been set. It’s called using event.dataTransfer.files. Only called files have been dragged from the OS onto the website (e.g. images from your desktop to your website’s upload container). This property will always be empty if a regular on-site item has been dragged (e.g. if you drag an image, there will be no data set for files).

files此属性包含已设置的所有本地文件的列表。 使用event.dataTransfer.files调用。 只有被调用的文件才从操作系统拖到网站上(例如,从桌面到网站的上传容器的图像)。 如果拖动了常规的现场项目,则此属性将始终为空(例如,如果拖动图像,则将没有files数据集)。

It’s here that you can check to see if we have files. If we do have them we can read in and process the contents of the files using the fileReader object.

您可以在这里检查我们是否有文件。 如果我们有它们,我们可以使用fileReader对象读入并处理文件的内容。

types This property provides a list of all data types that have been set in the current drag. Called by using the event.dataTransfer.types method. This is useful during the dragenter and dragover events so that you can see what data types have been set.

类型此属性提供当前拖动中已设置的所有数据类型的列表。 使用event.dataTransfer.types方法调用。 这在dragenterdragover事件期间很有用,这样您可以查看已设置的数据类型。

effectAlloweddropEffect作用 (effectAllowed and dropEffect in action)

If you’re keen on seeing how you can use these properties in a practical way, have a look at the following CodePen demo:

如果您渴望看到如何以实际方式使用这些属性,请查看以下CodePen演示:

See the Pen Native Drag and Drop — the effectAllowed and the DropEffect properties by SitePoint (@SitePoint) on CodePen.

见笔本地拖放-在effectAllowed和DROPEFFECT性质由SitePoint( @SitePoint )上CodePen

Here we define different draggable items and set where they can be dropped. We also create several droppable zones and set which draggable types they will accept. Setting these properties correctly will ensure that your browser knows which draggable items are allowed to be dropped.

在这里,我们定义了不同的可拖动项目,并设置了它们可以放置的位置。 我们还创建了几个可放置区域,并设置了它们将接受的可拖动类型。 正确设置这些属性将确保您的浏览器知道允许拖放哪些可拖动项目。

Even though Internet Explorer supports both the effectAllowed and dropEffect properties, it doesn’t implement any native ability to allow only applicable drags into drop zones. Chrome, Safari, and Firefox will restrict your drag item and prevent incorrect drops, refusing to fire the drop event. On IE you will need to manually reject these drops yourself by comparing values as the drop event will still fire.

即使Internet Explorer同时支持effectAlloweddropEffect属性,它也未实现任何本机功能,仅允许将适用的拖动拖动到放置区域中。 Chrome,Safari和Firefox将限制您的拖动项目并防止不正确的放置,并拒绝触发drop事件。 在IE上,您将需要通过比较值来手动拒绝这些丢弃,因为drop事件仍然会触发。

使用本机API构建内容 (Building Something with the Native API)

There’s quite a lot of information to deal with for the API so let’s put everything together into a practical example.

有关API的信息很多,因此让我们将所有内容放到一个实际的示例中。

The native API is concerned primarily with the interactions between the draggable and droppable elements and their transmission of data. The native API doesn’t care that you are moving two elements around trying to switch their positions, the API is more concerned with its data and it’s this focus that makes it unique.

本地API主要与拖动投掷的元素和它们的数据的传输之间的相互作用有关。 本机API并不关心您是否在移动两个元素来尝试切换它们的位置,API更关心其数据,正是这种关注使其独特。

One of the best things about the native API is that it can handle different types of data and also data from multiple locations.

关于本机API的最好的事情之一是它可以处理不同类型的数据 ,也可以处理来自多个位置的数据

Data types include:

数据类型包括:

  • Plain text strings

    纯文本字符串
  • Text / HTML content

    文字/ HTML内容
  • URL lists

    网址清单
  • Single or multiple files

    单个或多个文件
  • Multiple other types / custom types

    多种其他类型/自定义类型

Data locations include:

数据位置包括:

  • Data from internal elements being dragged and dropped

    来自内部元素的数据被拖放
  • Data from draggable elements from a different tab, window, or from a different browser

    来自其他选项卡,窗口或其他浏览器中可拖动元素的数据
  • Data from a local source like your desktop

    来自本地资源(如台式机)的数据

拖放处理元素之间的数据 (Processing Data Between Elements on Drag and Drop)

The native API provides the basics to support dropping and dragging of elements. While the API provides you with events to hook onto to know when a successful drag has taken place, unlike jQuery UI, you will need to manually move/copy elements to adjust the API.

本机API提供了支持元素拖放的基础。 与jQuery UI不同,尽管API提供了一些事件以供您了解成功拖动的发生时间,但与jQuery UI不同,您将需要手动移动/复制元素来调整API。

This is because as you start dragging an element, you trigger its dragStart event during which you set the data you want to transfer (along with the appropriate effects you want your draggable to have, such as copy, move, link etc). When you finally drop your dragged element, ig it’s in the right place it will trigger the drop area’s drop event. It handles the data that you want to move, not the UI elements (which you will need to manually adjust with JavaScript).

这是因为在开始拖动元素时,会触发它的dragStart事件,在该事件期间设置要传输的数据(以及希望可拖动对象具有的适当效果,例如复制,移动,链接等)。 当您最终放下拖动的元素时,如果它在正确的位置,它将触发放置区域的drop事件。 它处理您要移动的数据,而不处理UI元素(您需要使用JavaScript手动进行调整)。

Let’s look at a practical example so you can see how this works.

让我们看一个实际的例子,以便您了解它是如何工作的。

示例:拖放益智游戏 (Example: A Drag-and-Drop Puzzle Game)

Take a look at the following example to see how we can use the API to transfer data between elements on the same page.

看下面的示例,看看如何使用API​​在同一页面上的元素之间传输数据。

See the Pen Native Drag & Drop – Data transfer on a single page by SitePoint (@SitePoint) on CodePen.

见笔机拖放-在单页上的数据传输由SitePoint( @SitePoint上) CodePen

What we are doing in this example is defining a series of zones. The left side will hold our main puzzle pieces while the right side has a series of empty drop zones. The ‘game’ is to drag the pieces from the left to the right, completing the puzzle.

在此示例中,我们正在定义一系列区域。 左侧将容纳我们的主要拼图碎片,而右侧则具有一系列空的放置区域。 “游戏”是将棋子从左向右拖动,完成拼图。

dragStart上设置数据 (Setting Data on dragStart)

On the dragStart event for our puzzle piece we first set the effectAllowed to tell the item that it accepts a copy based drag.

在我们的拼图块的dragStart事件中,我们首先设置effectAllowed以告知项目它接受基于copy的拖动。

We then collect the src(image source) and the outerHTML (HTML Node) and put them inside of our data transfer object as text/uri-list and text/html. If we are on Internet Explorer we just save the src of the element being dragged and save it into its text format.

然后,我们收集src (图像源)和outerHTML (HTML节点),并将它们分别作为text/uri-listtext/html放入我们的数据传输对象中。 如果我们在Internet Explorer上,则只保存要拖动的元素的src并将其保存为text格式。

var dragItem;
// triggered draggable as we start dragging
function dragStart(event) {
  drag = event.target;
  dragItem = event.target;

  // set the effectAllowed for the drag item
  event.dataTransfer.effectAllowed = 'copy';

  var imageSrc = $(dragItem).prop('src');
  var imageHTML = $(dragItem).prop('outerHTML');

  // check for IE (it supports only 'text' or 'URL')
  try {
    event.dataTransfer.setData('text/uri-list', imageSrc);
    event.dataTransfer.setData('text/html', imageHTML);
  } catch (e) {
    event.dataTransfer.setData('text', imageSrc);
  }

  $(drag).addClass('drag-active');
}

正确effectAllowed / dropEffect (Correct effectAllowed / dropEffect)

Before we even drop the puzzle piece, both the dragEnter and dragOver events will fire. Remember that for us to be able to drop we need to return false / prevent default to tell the browser it’s OK to drop. Both of these functions will set the drop zone’s dropEffect to copy which means it will accept all drag items with copy as their effectAllowed (which our items happen to have so it’s all good). I mention this here since if they didn’t match, the drop event wouldn’t fire, and the drag would be canceled.

在我们放下拼图之前, dragEnterdragOver事件都会触发。 请记住,要使我们能够删除,我们需要返回false / prevent default来告诉浏览器可以删除。 这些功能都将设置下区的dropEffectcopy ,这意味着它会接受所有的拖拽项目copy作为他们effectAllowed (其中我们的项目正好有那么这一切都很好)。 我之所以在此提及,是因为如果它们不匹配,则不会触发drop事件,并且拖动将被取消。

收集数据 (Collecting data on our drop)

When we drop over our zones to the right, we use the getData method to extract our text/uri-list and text/html data sets. If we don’t have them (if we are accessing this on Internet Explorer) we simply extract the text data.

当我们将区域拖放到右侧时,我们使用getData方法提取我们的text/uri-listtext/html数据集。 如果没有它们(如果正在Internet Explorer*问),则只需提取text数据。

Here is where we differ based on what data we have. If we have access to the dataHTML it means we are on a fully supported browser and we have access to the entire dragged node. If we do we add the whole item to the drop zone and the drop is done.

这是我们根据拥有的数据而有所不同的地方。 如果可以访问dataHTML则意味着我们使用的是受完全支持的浏览器,并且可以访问整个拖动的节点。 如果这样做,我们将整个项目添加到放置区域,放置完成。

If we don’t have support we need to clone the dragItem we set back in the dragStart event to get the node. We then add it to the drop zone and finish everything up.

如果我们没有支持我们需要克隆dragItem我们设置回到dragStart事件获得节点。 然后,我们将其添加到放置区并完成所有操作。

// called when draggable is dropped on droppable 
function drop(event) {

  drop = this;
  $(drop).removeClass('drop-active');

  var dataList, dataHTML, dataText;

  // collect our data (based on what browser support we have)
  try {
    dataList = event.dataTransfer.getData('text/uri-list');
    dataHTML = event.dataTransfer.getData('text/html');
  } catch (e) {
    dataText = event.dataTransfer.getData('text');
  }

  // we have access to the HTML
  if (dataHTML) {
    $(drop).empty();
    $(drop).prepend(dataHTML);

    // check if this element is in the right spot
    checkCorrectDrop(drop, dragItem);

    // see if the final image is complete
    checkCorrectFinalImage();
  }

  // only have access to text (old browsers + IE)

  else {
    $(drop).empty();
    $(drop).prepend($(dragItem).clone());

    // check if this element is in the right spot
    checkCorrectDrop(drop, dragItem);

    // see if the final image is complete
    checkCorrectFinalImage();
  }

  event.preventDefault();
  event.stopPropagation();
}

完成游戏 (Completing the game)

Both drop events call the checkCorrectDrop(drop, dragItem) and checkCorrectFinalImage() functions. These are used for our game.

这两个放置事件都调用checkCorrectDrop(drop, dragItem)checkCorrectFinalImage()函数。 这些用于我们的游戏。

The checkCorrectDrop() function checks to see if the custom attribute called data-value is the same for both the drag item and the drop zone. If both of these are the same then this piece belongs here and is highlighted with a green border (and the active class).

checkCorrectDrop()函数检查拖动项和放置区的名为data-value的自定义属性是否相同。 如果这两个都相同,则此作品属于此处,并以绿色边框(和active班级)突出显示。

The checkCorrectFinalImage() function checks to see if all of the puzzle pieces have been dropped in the correct spot. If we have as many correct items as there are items to drag, it means we’ve completed the puzzle – hooray!

checkCorrectFinalImage()函数检查所有拼图块是否都已放入正确的位置。 如果我们有正确的项目与要拖动的项目一样多,则意味着我们已经完成了难题–万岁!

从其他选项卡和桌面本地移动数据 (Moving Data from Other Tabs and Locally from the Desktop)

With the native API, you can define drop zones that will accept dragged elements. While this might sound like something jQuery UI can also do, what jQuery UI can’t do is allow us the ability to drag content from any external tab, window, or external browser directly into our drop area.

使用本机API,您可以定义将接受拖动元素的放置区域。 虽然这听起来像jQuery UI也可以完成,但是jQuery UI不能做的是使我们能够将内容从任何外部选项卡,窗口或外部浏览器直接拖动到放置区域。

There are plenty of places in which you’ve seen this already. There are several websites in which you can drag an image from one tab directly into a drop area and the receiving website will take care of the interaction.

您已经在很多地方看到了这一点。 在多个网站中,您可以将图像从一个选项卡直接拖动到放置区域,接收网站将负责交互。

To get the most out of the dragging and dropping, the drop zone has to be configured so that it knows how to handle the data it’s receiving (as basically any draggable element such as images, text, links, and content would be dropped into the drop zone).

为了充分利用拖放功能,必须对放置区域进行配置,使其知道如何处理其接收的数据(因为基本上任何可拖动的元素(例如图像,文本,链接和内容)都将放入拖放区)。

Dragging content from your desktop or local device onto a web page and automating the upload process is one of those revolutionary features that makes you wonder how we ever got anything done without it.

将内容从台式机或本地设备拖放到网页上并自动执行上传过程是这些革命性的功能之一,这使您想知道如果没有它,我们如何完成任何工作。

Most CMS’s (e.g. WordPress) have native support of content uploads via a drag-and-drop interface. Other web apps like Gmail also provide this functionality, letting you drop your content directly into a zone and automatically attach it or store it for use.

大多数CMS(例如WordPress)都具有通过拖放界面上传内容的本机支持。 Gmail等其他网络应用程序也提供了此功能,可让您将内容直接放入区域并自动附加或存储以供使用。

示例:从外部源拖动图像 (Example: Dragging Images from External Sources)

The next example will handle interactive drops from other tabs / windows, letting the drop zone collect images for display.

下一个示例将处理来自其他选项卡/窗口的交互式放置,让放置区域收集图像进行显示。

In addition, the example also will handle locally dropped images. You will be able to drop photos from your desktop directly onto the dropzone and the native API will process the images and display them.

此外,该示例还将处理本地丢弃的图像。 您将能够将照片从桌面直接拖放到放置区,并且本机API将处理图像并显示它们。

html5拖放api_使用HTML5的本机拖放API

If you’re keen on seeing how this all works, here’s another CodePen demo:

如果您热衷于了解这一切的工作原理,请参见下面的另一个CodePen演示:

See the Pen Native Drag and Drop – Dragging files directly onto the website by SitePoint (@SitePoint) on CodePen.

见笔原生拖曳功能-直接拖动文件到网站由SitePoint( @SitePoint上) CodePen

What this example focuses on is processing dropped items. Unlike our other examples where we had to set data on our drag, for this one we need to only collect the data and determine how we will process it.

本示例着重于处理掉落的物品。 与我们不得不在拖动上设置数据的其他示例不同,对于此示例,我们仅需要收集数据并确定我们将如何处理它。

Inside our main drop function, we start by collecting information from our dataTransfer object using the getData(format) method.

在我们的主要drop函数内部,我们首先使用getData(format)方法从dataTransfer对象收集信息。

// get the URL of elements being dragged here
try {
  dataValue = event.dataTransfer.getData('text/uri-list');
  dataType = 'text/uri-list';
} catch (e) {
  dataValue = event.dataTransfer.getData('URL');
  dataType = 'URL';
}

We wrap this inside of a try-catch block mainly for Internet Explorer, which will throw an error and stop execution if we try and access a format inside of getData() that it doesn’t understand.

我们将其包装在主要用于Internet Explorer的try-catch块中,如果尝试在getData()中访问它无法理解的格式,则会抛出错误并停止执行。

If we are able to get our data in the text/uri-list format, we collect it; if we can’t, we fall back to using the basic URL property.

如果我们能够以text/uri-list格式获取数据,则将其收集; 如果不能,我们将退回到使用基本URL属性。

Most dragged items such as images, links, or data will come across with several data types. Since we are only interested in the URL of these items, this works well.

大多数拖动的项目(例如图像,链接或数据)会遇到几种数据类型。 由于我们只对这些项目的URL感兴趣,因此效果很好。

If we have our dataValue set, it means the user dropped something into our zone. We now need to figure out what it is. We only want to handle images, but since the API can’t differentiate between an image URL and a standard link, we need to do some checks to ensure we are dropping an image.

如果设置了dataValue ,则意味着用户将某些东西放到了我们的区域中。 现在,我们需要弄清楚它是什么。 我们只想处理图像,但是由于API无法区分图像URL和标准链接,因此我们需要做一些检查以确保我们删除图像。

// determine if our URL is an image
imageDropped = false;
var imageExtensions = ['.jpg','.jpeg','.png','.bmp','.gif'];
for (i = 0; i< imageExtensions.length; i++) { 
  if (dataValue.indexOf(imageExtensions[i]) !== -1) {
    // create our image to add
    var image = '<img src="' + dataValue + '">';
    drop.append(image);
    imageDropped = true;
    break;
  }
}

We create a list of image extensions with known image types such as .jpg and .png and check to see if one of these appears in our URL. If it does, then we can assume we have an image. We create a new image and use our collected value as its source.

我们创建具有已知图像类型(例如.jpg.png的图像扩展名列表,并检查其中是否有一个出现在我们的URL中。 如果是这样,那么我们可以假设我们有一个图像。 我们创建一个新图像并将收集的值用作其来源。

处理本地掉落的物品 (Processing locally dropped items)

Locally dropped elements are a little different. We don’t use the getData(format) method to get these, we use the files() method. This will get us a list of all elements that have been dropped so we can iterate through them.

局部删除的元素有些不同。 我们不使用getData(format)方法来获取这些,而是​​使用files()方法。 这将为我们提供已删除的所有元素的列表,以便我们可以遍历它们。

var dataFiles = event.dataTransfer.files;
var dataOutput = []; 
if (dataFiles) {
  for (i =0; i < dataFiles.length; i++) {
    // do processing here
  } 
}

For our example we want to go through all dropped files and check to see if there is an image. When we are iterating through each file we can access a range of properties, including the type property, which lists the mime type of the item.

对于我们的示例,我们要浏览所有删除的文件,并检查是否有图像。 当我们遍历每个文件时,我们可以访问一系列属性,包括type属性,该属性列出了该项目的mime类型。

// check if this is an image
if (dataType.match('image.*')) {
  // it's an image, process further
}

If we match an image type, we create a new fileReader object that we will use to read the file into memory. We use the readAsDataURL(item) method to read in our file and when it’s ready it will trigger its onload event where we will process further.

如果匹配图像类型,则创建一个新的fileReader对象,该对象将用于将文件读入内存。 我们使用readAsDataURL(item)方法读取文件,当文件准备就绪时,它将触发其onload事件,在此我们将进一步处理。

// read into memory
var reader = new FileReader();

// load element
reader.readAsDataURL(dataItem);

All we do now is collect the result of the file reader and add it the DOM. We have successfully dragged an image from our desktop to our site!

我们现在要做的就是收集文件阅读器的结果,并将其添加到DOM中。 我们已成功将图像从桌面拖动到我们的网站!

// when our image is loaded
reader.onload = (function(theFile) {
  return function(e) {
    var url = e.target.result;

    drop.append('<img src="' + url + '" title="' + dataName + '"/>');
    messageContainer.append('
      <p><strong>Successfully dropped an image from your desktop</strong></p>
    ');
  };
})(dataItem);

浏览器支持概述 (Overview of Browser Support)

Exactly as its name suggests, this API provides developers with a set of events and methods they can use to provide UI interactions without the need for a third party JavaScript library.

顾名思义,该API为开发人员提供了一组事件和方法,可以使用它们来提供UI交互,而无需第三方JavaScript库。

Overall browsers have strong desktop support and almost non existent mobile support, so it will work well in most modern desktop browsers following the specification. Internet Explorer though has its own set of unique issues.

总体而言,浏览器具有强大的桌面支持,几乎不存在移动支持,因此它将在遵循该规范的大多数现代桌面浏览器中正常运行。 Internet Explorer虽然有其自己的一系列独特问题。

Desktop support is surprisingly good with Chrome, Firefox, Safari and Opera all having comprehensive support. Internet Explorer on the other hand handles the API differently, supporting different aspects depending on what version you are on. For example:

桌面支持非常好,Chrome,Firefox,Safari和Opera都具有全面的支持。 另一方面,Internet Explorer对API的处理方式不同,根据您所使用的版本,它支持不同的方面。 例如:

  • No support in IE7, IE8, and IE9 for the dataTransfer.files or .types objects. This means up to IE9 you won’t be able to use native drag and drop to allow users to drag files from the desktop to a web page.

    IE7,IE8和IE9中不支持dataTransfer.files.types对象。 这意味着在IE9之前,您将无法使用本机拖放功能来允许用户将文件从桌面拖放到网页上。

  • Limited supported formats for dataTransfer.setData/getData In practice when we drag items, we need to store data in our drag that can be accessed in our drop. In other browsers you can store this in a variety of types (e.g. text/html or text/uri-list) along with your own custom types. IE will only support the Text or URL type, which means you’re limited to how you will handle your data.

    dataTransfer.setData/getData受支持有限格式在实践中,当我们拖动项目时,我们需要将数据存储在拖放中的数据中,以便在拖放操作中进行访问。 在其他浏览器中,您可以将其存储为多种类型(例如text/htmltext/uri-list )以及自己的自定义类型。 IE仅支持TextURL类型,这意味着您只能处理数据。

  • No support in any version of IE or Edge for the dataTransfer.setDragImage() method. Basically there is no ability to set a custom drag image or element. You will always get the browser default (which most of the time will be a copy of the element that is semi-transparent).

    IE或Edge的任何版本均不支持dataTransfer.setDragImage()方法。 基本上,无法设置自定义拖动图像或元素。 您将始终获得浏览器的默认值(大多数情况下,它是半透明元素的副本)。

For mobile, there is basically no practical support for the API (as of October 2015). This probably has to do with how mobile browsers will handle the interactions themselves as normally you need to drag and scroll to move around. IE11 is the only mobile browser that will support it.

对于移动设备,基本上没有对该API的实际支持(截至2015年10月)。 这可能与移动浏览器如何自行处理交互有关,因为通常您需要拖动和滚动才能移动。 IE11是唯一支持它的移动浏览器。

其他资源 (Additional Resources)

There are plenty of great resources to get more details on the Drag and Drop API. Some of them discuss the methods available and events you can hook into while others detail browser inconsistencies or outline great examples.

有很多很棒的资源可以获取有关拖放API的更多详细信息。 其中一些讨论了可用的方法和您可以挂接的事件,而另一些则详细介绍了浏览器不一致或概述了出色的示例。

Start with these links, which helped me when I was first looking into native drag and drop:

从这些链接开始,这在我第一次研究本机拖放时对我有帮助:

结语 (Wrapping Up)

At this point, you should now have a good fundamental understanding of the native Drag and Drop API and how you can leverage it to provide an interactive interface. You’ll likely have to do a lot of experimenting to really start to understand much of what I’ve discussed here.

至此,您现在应该对本地的拖放API以及如何利用它提供交互式界面有了很好的基本了解。 您可能需要做很多试验才能真正理解我在这里讨论的很多内容。

Even with the lack of mobile support, browser support is pretty strong so there’s good reason to consider using the native API in new projects.

即使缺少移动支持,浏览器的支持也非常强大,因此有充分的理由考虑在新项目中使用本机API。

翻译自: https://www.sitepoint.com/html5-native-drag-and-drop-api/

html5拖放api