Drag 和 Drop 在 JavaScript 中的使用

 

这一节描述了我们怎么在 JavaScript 中使用 drag and drop.

The JavaScript Drag and Drop Wrapper

在进行拖拽的时候我们也许会需要处理一些事件和传递数据,那么这个时候我们就需要用到DragDrop了。让我们简明的看一下使用方法。(对照文档有简化)

注意你需要在所用的xul页面中导入两个 chrome 路径。

<script src="chrome://global/content/nsDragAndDrop.js"   />

<script src="chrome://global/content/nsTransferable.js"   />

我们可以参考下这个例子:

<button label="Drag Me" ondraggesture="nsDragAndDrop.startDrag(event,buttonObserver);"   /> 

它的功能是在我们首次拖动这个按钮时会通过触发nsDragAndDrop.startDrag 而执行buttonObserver方法里的onDragStart事件。第一个参数是所触发的事件元素,适用于所有的事件处理。第二个参数是作为监听器的方法,一会儿再具体介绍。 同样我们也可以处理其他的情况而触发相应的方法,例如下面这个例子:

<description value="Click and drag this text."

             ondraggesture="nsDragAndDrop.startDrag(event,textObserver)"

             οndragοver="nsDragAndDrop.dragOver(event,textObserver)"

             ondragexit="nsDragAndDrop.dragExit(event,textObserver)"

             ondragdrop="nsDragAndDrop.drop(event,textObserver)"   />

通常有六个拖动触发事件,拖动是指按住鼠标并移动鼠标的时候,ondrag为有拖动操作就触发,ondraggesture为首次拖动而触发,ondragover为在区域内拖动而触发,ondragenter为拖动至区域内而触发,ondragexit为拖动至区域外而触发,ondragdrop为释放拖动而触发。

这有两种方式处理drag drop 事件。第一个是直接用nsIDragService nsIDragSessionXPCOM接口,第二个是用JavaScript wrapper 方法协助操作。

如上所述,在触发事件时候并没有什么需要特别注意的,一会让我们亲自来测试一下吧。先看一下这些事件的功能。

onDragStart(event, transferData, action) 

在拖动开始时你可以定义这个方法,它有三个参数,第一个参数event元素作为被拖动的节点事件,我们可以用event.target取得该DOM节点;第二个transferData是拖拽时候所转移的数据,我们可以在这个方法内给transferData添加数据而进行传递,具体的使用方法请查看nsITransfer接口(尚未确定);第三个是拖拽动作的类型,有四种类型供用户选择,但具体意义还不明确。

nsIDragSession.DRAGDROP_ACTION_NONE 不允许修改。

nsIDragSession.DRAGDROP_ACTION_COPY 拷贝

nsIDragSession.DRAGDROP_ACTION_MOVE 移动

nsIDragSession.DRAGDROP_ACTION_LINK 连接

 

onDragOver(event, flavour, session) 

当拖动在区域内时你可以定义这个方法,第一个参数还是event元素;第二个参数是所此次拖动所带来的传递数据类型相关,里面应该包括着数据;第三个session是会话信息,它有几个参数我个人认为很有用,比如sourceDocument可以得到被拖动的源,sourceNode可以得到被拖动的节点等等,你可以从中直接取到节点属性。

 

onDragExit(event, session) 

当拖动退出区域时你可以定义这个方法,第一个参数又是event元素,第二个是会话信息解释同上。

onDrop(event, transferData, session) 

当释放拖动后你可以定义这个方法来做一些处理,第一个依然是event;第二个是传递过来的数据;第三个session是会话信息解释同上。

 

getSupportedFlavours() 

这个方法可以返回可接受的元素类型,通常用在Drop事件中,具体使用方法请参照例子,但好像就是一个数据类型的判定,还需要研究下。

 

The type of data being dragged is stored as a set of flavours. Often, a dragged object will be available in a number of flavours. That way, a drop target can accept the flavour it finds most suitable. For example, a file may come in two flavours, the file itself and the text name of the file. If the file is dragged and dropped onto a directory, the file flavour will be used. If the file is dropped onto a textbox, the text name flavour will be used. The text is therefore used to insert the name of the file when files can't be dropped directly.

A flavour object has a name, which is a formatted like a MIME type, such as 'text/unicode'. Within the onDragStart function, you specify what flavours are available for the item being dragged. To do this, add data and flavours to the transferDataobject, which is the second argument to onDragStart.

这是mozilla技术文档的例子,在 onDragStart 方法里给transferData 元素添加数据。

var textObserver = {

  onDragStart: function (event, transferData, action) {

    var htmlText  = "<strong>Cabbage</strong>";

    var plainText = "Cabbage";

    transferData.data = new TransferData();

    transferData.data.addDataForFlavour("text/html",htmlText);

    transferData.data.addDataForFlavour("text/unicode",plainText);

  }

}

Here, an observer has been declared and stored in the variable textObserver. It has one property called onDragStart. (In JavaScript, properties can be declared with the syntax name : value). This property is a function which sets the data that is being dragged.

一旦被触发,它会拖拽的数据是“Cabbage”。当然,如果你想得到的是被点击过的元素属性,用我上面说的方法,以event.target取得该DOM节点。

我们在拖拽的时候创建一个传递数据流TransferData 元素,我们在其中添加了两个不同类型的数据,第一个是HTML类型的字符串,第二个是plain类型的字符串。如果用户拖拽的页面能够接受HTML元素的话,那页面会接受HTML类型的元素,文本就会变成粗体。否则会用plain类型的文本来进行替换。

通常你会想提供能够让更多程序接受拖拽的数据,因而你定义的flavours 的次序决定了匹配的优先级。就像上面的情况一样HTML flavour (text/html)优先于text flavour (text/unicode)

这个例子演示了当拖拽时将节点的label标签的值作为数据而进行传递。

var textObserver = {

  onDragStart: function (event) {

    var txt = event.target.getAttribute("label");

    transferData.data = new TransferData();

    transferData.data.addDataForFlavour("text/unicode",txt);

  }

}

这个在单元树上进行拖拽是非常有效果的,你可以在某个单元树取值,如果是一个模板建造树那这个值可能会来自RDF文件。假设你储存它是一个字符串,只要是字符串元素的拖拽,它就可以获取到释放过来的数据啦。

如果你想发送更多的数据(例如多选文件),你必须用 TransferDataSet ,如下所写:(但貌似我没测试成功。---chenjian

var textObserver = {

  onDragStart: function (event) {

    var txt1 = 'hello';

    var txt2 = 'there';

    transferData.data = new TransferDataSet();

 

    var tmp = new TransferData();

    tmp.addDataForFlavour("text/unicode",txt1);

    transferData.data.push(tmp);

 

    new TransferData();

    tmp.addDataForFlavour("text/unicode",txt2);

    transferData.data.push(tmp);

  }

}

//你需要开始拖拽或是接收拖拽元素时候为每一个元素添加监听

You will need to add an observer to each element that can either start a drag action or can accept dropped objects. You can reuse the same observer for multiple elements. For an element that can start a drag, onStartDrag is all that is necessary to implement.

监听器需要实现getSupportedFlavours onDragOver  onDrop这三个方法,那些元素才能够正常拖拽和接受释放,对于这种情况在拖拽元素的界面onStartDrag 方法也是有必要的。

getSupportedFlavours 方法可以传回flavours 的列表,才能够知道哪些类型的元素可以在其区域内进行释放。比如一个文件系统目录显示可以接收文件和文本类型,但他不能接收HTML text。下面的例子我们定义getSupportedFlavours 方法,我们只允许字符串类型的 flavour

var textObserver = {

  getSupportedFlavours : function () {

    var flavours = new FlavourSet();

    flavours.appendFlavour("text/unicode");

    return flavours;

  }

}

flavours list 只有一个flavour 'text/unicode'。在FlavourSet 元素中可以加入flavours。在某些情况下你必须提供XPCOM接口,如下个加文件的例子:

var textObserver = {

  getSupportedFlavours : function () {

    var flavours = new FlavourSet();

    flavours.appendFlavour("application/x-moz-file","nsIFile");

    flavours.appendFlavour("text/unicode");

    return flavours;

  }

}

在元素拖拽到区域之内会触发onDragOver 方法。You might use it to change the appearance of the element as it is being dragged over. In many cases the function can do nothing. It must be defined for elements that accept dragged data however.

之后,会触发onDrop 方法。第二个参数transferData是被传进来的数据流,与此同时,某wrapper会查看 getSupportedFlavours 来判断最佳类型flavour, 所以transferData传进来的数据只包含最佳类型选择的那个flavour

The transfer object has two properties, data which holds the data and flavour which holds the flavour of the data. Once you have the data, you can add it to the element is some way. For example, you might set the value of a textbox.

var textObserver = {

  onDrop : function (event, transferData, session) {

    event.target.setAttribute("value",transferData.data);

  }

}

The flavour system used allows multiple objects of various types to be dragged at once and also allows alternative forms of the data to be dragged. The following table describes some of the flavours you might use. You can also make up your own flavours if necessary.

text/unicode

Text data

text/html

HTML data

text/x-moz-url

A URL

application/x-moz-file

A local file

下面的这些还有待研究。而且是允许自行设置Flavor的。

Flavor

Brief Description

text/unicode

没有格式信息的两字节unicode编码版本,可以发送常用的字符。Two-byte unicode plain text with no formatting information

text/xif

An XML interchange format that includes text and its formatting similar to html

text/html

HTML

text/plain

One-byte plain text, for internal use only.

AOLMAIL

A format used by AOL/AIM for formatted text, similar to HTML

image/png

Binary PNG image data

image/jpg

Binary JPEG image data

image/gif

Binary GIF image data

application/x-moz-file

本地文件。 A file object (supporting nsIFile) for identifying a local file

text/x-moz-url

A url and title for identifying the data is a URL for platforms that care

 

·                      chenjian@ceopen.cn

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值