2011-07-20 42 views
18

我開始嘗試使用HTML5 Drag and Drop。然後,在dragstart事件處理程序,我們應該運行setData(),它接收兩個參數:格式數據我應該使用什麼格式(MIME類型)來進行HTML5拖放操作?

function dragstart_handler(ev) { 
    ev.dataTransfer.setData('text/plain', 'foobar'); 
} 

我想將某種「對象」從一個容器拖到另一個容器中,在我的web應用程序中。 「對象」是指具有多個屬性(顏色,文本,作者,日期等)的東西。

我應該使用什麼樣的格式(或MIME類型)的?

  • text/plain
  • text/x-myapp-myobjtype
  • application/x-myapp-myobjtype
  • application/x-myapp.myobjtype+json
  • 別的東西?
  • 多個?

我應該如何編碼我對象(數據參數的setData())?

  • 逗號分隔(或任何其他分隔符)鍵=值對?
  • 使用JSON序列化對象?
  • 只是一個ID,並在懸浮窗,我必須只使用ID檢索完整的對象?
  • 只發送一個對象的引用,甚至沒有序列化任何東西? (不可能的,數據參數必須是一個字符串)

(我認識到,「如何enconde對象拖放」可能是這裏的另一個問題,但它是密切相關的選擇MIME類型)


一些參考:

+0

這真的取決於你究竟在做什麼,但「應用/ JSON」和JSON序列化對象看起來體面的選擇... – Spudd86

+0

但不是'應用程序/ json'東西太普通?遵循該建議,任何OpenOffice文檔都應該有'application/zip' MIME類型,因爲它們實際上是壓縮文件。 –

+1

進一步提高我的觀點:如果我使用'application/json',那麼類推之後,所有的SVG圖像應該是'application/xml'而不是'image/svg + xml',因爲它們也是XML文檔。同樣的邏輯也適用於使用XML序列化的任何東西(比如Google Earth KML文件,目前使用'application/vnd.google-earth.kml + xml'類型;或Atom提要,使用'application/atom + xml' )。 –

回答

0

使用「應用/ JSON」作爲你可能喜歡的任何其他元數據,包括MIME類型鏈接文件的,或者你想的HTML包裝在瀏覽器中使用。

{ 'assets': [ 
     { 
     'color': 'foo', 
     'text': 'bar', 
     'uri': 'http://', // location of asset 
     'type': 'application/zip', // mime-type of asset 
     'html': '<div>html representation</div>' 
     // .. more properties 
     } 
    // ...more assets 
    ] 
} 
+1

普通'application/json'感覺不對。也許沿着'application/x-myapp.myobj + json'這行來說吧? –

5

更新:自19版此Chrome錯誤已得到修復。

如果我的目標是支持Google Chrome(現在版本12是最新版本),那麼我必須堅持text/plain

這是因爲Chrome has improperly implemented the dataTransfer object,並有一個關於dataTransfer not working with non text or url的開放bug。我已經寫了simple desmontration at jsFiddle。它在Mozilla Firefox 3.6以及Arora browser(版本0.10.2,WebKit版本533.3)中正常工作。爲了完整起見,我的Chrome版本是12.0.742.112(WebKit版本534.30)。示範代碼也可以如下:

<div id="drag" draggable="true">Drag me!</div> 
<div id="drop">Drop here!</div> 


#drag, #drop { 
    padding: 1em 2em; 
    margin: 1em 0; 
} 
#drag { 
    background: #CFC; 
} 
#drop { 
    background: #FCC; 
} 


function dragstart_handler(ev) { 
    console.log('dragstart'); 
    ev.dataTransfer.setData('text/x-example', 'Foobar'); 
} 

function dragover_handler(ev) { 
    // Accepting whatever is dragged over here 
    ev.preventDefault(); 
} 

function drop_handler(ev) { 
    console.log('drop'); 
    console.log(ev.dataTransfer.types); 

    if (ev.dataTransfer.types) { 
     var i; 
     for (i = 0; i < ev.dataTransfer.types.length; i++) { 
      var type = ev.dataTransfer.types[i]; 
      console.log(type, ev.dataTransfer.getData(type)); 
     } 
    } 

    console.log(ev.dataTransfer.getData('text/x-example')); 
} 

var drag = document.getElementById('drag'); 
drag.addEventListener('dragstart', dragstart_handler, false); 

var drop = document.getElementById('drop'); 
drop.addEventListener('dragover', dragover_handler, false); 
drop.addEventListener('drop', drop_handler, false); 
+0

Chrome版本的bug在版本19中得到修復。 –

+0

並且在22版本(可能更早)中再次遭到破壞 – rtcarlson

+1

@rtcarlson在Linux上運行Google Chrome 29.0.1547.62。在我的答案中鏈接的演示在這裏正確工作,所以我不認爲這個錯誤現在仍然存在。 (BTW,Chrome 22相當老...) –

6

HTML5規範具有一定的拖放的例子(見current working draftlatest version)。在這些示例中,使用了自定義MIME類型,並且還建議使用特定於站點的MIME類型。看到這個片段:

<p>Drop your favorite fruits below:</p> 
<ol dropzone="move s:text/x-example" ondrop="dropHandler(event)"> 
<-- don't forget to change the "text/x-example" type to something 
specific to your site --> 
</ol> 
<script> 
    var internalDNDType = 'text/x-example'; // set this to something specific to your site 
[...] 

所以,這很好,這意味着我們應該使用自定義的MIME類型! (除非我們實際上在拖動純文本,或者只是一個URL,或者已經知道類型的東西)

但是我們如何創建這樣的自定義MIME類型呢?

我沒有找到關於此的文檔,所以我查看了其他MIME類型。 list of text media types沒有什麼特別的,但list of application media types是相當有趣的。讓我從該列表中搶到一個樣本:

application/atom+xml 
application/xhtml+xml 
application/xmpp+xml 

application/vnd.google-earth.kml+xml 
application/vnd.google-earth.kmz 
application/vnd.iptc.g2.newsitem+xml 
application/vnd.iptc.g2.packageitem+xml 
application/vnd.nokia.iptv.config+xml 
application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml 
application/vnd.yamaha.openscoreformat.osfpvg+xml 

application/vnd.hal+json 
application/vnd.hal+xml 

我可以看到製作命名的模式:

  • 一個點分層分隔的多個「元素」(例如,configiptv孩子,是nokia的子項,即vnd的子項)。
  • 連字符分隔複合詞(如google-earthopenxmlformats-officedocument)。
  • 加號用於進一步指定序列化格式(在這些示例中爲+json+xml)。
  • x-前綴應該用於未向IANA註冊的MIME類型(因此,不在該列表中顯示)。

基於這些規則,我可以建議使用以下MIME類型:

應用程序/ x-mysite.myobject + JSON(或應用程序/ x-mysite.parentobject.childobject + JSON

這似乎是爲以JSON編碼的Web應用程序對象指定自定義MIME類型的最準確和最正確的方法。

+0

不應將「x-」前綴替換爲「vnd。」? – Gili

+6

x前綴將用於MIME類型沒有在IANA註冊,然而'vnd.'前綴是針對已經在IANA註冊的供應商特定的MIME類型(順便提一下,是個好問題!) –

相關問題