Upgrade to Pro — share decks privately, control downloads, hide ads and more …

HTML 5 Native Drag

HTML 5 Native Drag

Weizhong Yang

August 26, 2012
Tweet

More Decks by Weizhong Yang

Other Decks in Technology

Transcript

  1. HTML 5 Native Drag
    楊維中(a.k.a zonble)
    [email protected]
    Sunday, August 26,

    View full-size slide

  2. 話說…
    • 有次聽了⼀一位資深 Web Developer 發表
    關於 HTML 5 的演講,裡頭提到 Native
    Drag
    • …聽完覺得完全沒搔到癢處
    • …果然要講跟 Native 有關的東⻄西,你還
    是得要玩過⼀一點 Native 的東⻄西才⾏行
    Sunday, August 26,

    View full-size slide

  3. 在 Native Drag 之前?
    • 網⾴頁上的 Drag and Drop,其實就只是讓
    某個 HTML Element 移動位置⽽而已
    • 讓某個 HTML Element 跟著滑⿏鼠跑
    • 拖拉範圍不能超過⺫⽬目前網⾴頁
    Sunday, August 26,

    View full-size slide

  4. Native Drag
    • 將要透過 Drag and Drop 交換的資料寫⼊入
    系統剪貼簿
    • Mac OS X:NSPasteboard
    • 透過系統 API 設定滑⿏鼠游標圖⽚片
    Sunday, August 26,

    View full-size slide

  5. 所以可以…
    • 瀏覽器不同網⾴頁之間拖拉資料
    • 不同瀏覽器之間拖拉資料
    • 瀏覽器與其他應⽤用程式之間拖拉資料
    Sunday, August 26,

    View full-size slide

  6. 其實…
    • 瀏覽器本來就有⼀一定程度的 Native
    Drag,但是原本僅侷限於部分種類的資
    料…
    • ⽂文字
    • 圖⽚片
    • 連結
    • 但是其他⾃自定類型的資料怎麼辦?
    Sunday, August 26,

    View full-size slide

  7. 以前的作法
    • 如果想將 HTML 中出現⼀一個可以拖拉到
    瀏覽器之外的 custom 資料,我們需要寫
    ⼀一個瀏覽器 plug-in
    • 瀏覽器 plug-in 就是在瀏覽器畫⾯面中挖出
    ⼀一塊 Native View,裡頭的實作當然就是
    Native 的,於是可以⽤用 Native ⽅方式交換
    資料
    • 但是寫 plug-in 好⿇麻煩的啊…
    Sunday, August 26,

    View full-size slide

  8. 瀏覽器 Plug-in
    • Windows:可能要寫 ActiveX Control,
    會有⼀一堆安全性問題…
    • Mac OS X:原本 WebKit Plug-in 超好寫,
    但是 10.7 Lion 之後禁⽌止 Safari 載⼊入
    WebKit Plug-in…
    Sunday, August 26,

    View full-size slide

  9. Demo
    • Sample Code:https://github.com/zonble/
    NativeDrag
    • 參考⽂文件:WebKit DOM Programming
    Topics - Using Drag and Drop From
    JavaScript
    Sunday, August 26,

    View full-size slide

  10. WebView 與 NSTableView 交換資料
    Sunday, August 26,

    View full-size slide

  11. 怎麼做
    • 先解釋怎樣從 WebView 拖資料放到
    NSTableView
    • 再解釋怎樣從 NSTableView 拖資料到
    WebView
    Sunday, August 26,

    View full-size slide

  12. 從 WebView 拖資料放
    到 NSTableView
    Sunday, August 26,

    View full-size slide

  13. JavaScript
    • 要讓⼀一個 HTML Element 變成可以⽤用
    Native Drag 拖拉
    • 加上 CSS 屬性:-webkit-user-drag:
    element;
    • 加上 ondragstart 的 handler
    • ondragstart=”dragstart(this, event)”>
    div>
    Sunday, August 26,

    View full-size slide

  14. JavaScript
    呼叫系統剪貼簿
    dragstart = function(this, event) {
    var dataTransfer = event.dataTransfer;
    dataTransfer.setData(“key”, “value
    string”);
    return true;
    };
    Sunday, August 26,

    View full-size slide

  15. Objective C
    • 註冊可以 Drop 的 Data Type
    • [self.tableView registerForDraggedTypes:@[@”key”]];
    • NSView 需要實作 NSDraggingDestination
    才能⽀支援 Drop 資料
    • NSTableView DataSource 需要實作兩個
    method
    • tableView:validateDrop:proposedRow:proposedDropOperation:
    • tableView:acceptDrop:row:dropOperation:
    Sunday, August 26,

    View full-size slide

  16. Objective C
    - (NSDragOperation)tableView:(NSTableView *)tableView
    validateDrop:(id )info proposedRow:
    (NSInteger)row proposedDropOperation:
    (NSTableViewDropOperation)dropOperation
    {

    NSPasteboard *pasteBoard = [info draggingPasteboard];

    NSString *value = [pasteBoard stringForType:@”key”];

    if (value) {


    return NSDragOperationCopy;

    }

    return NSDragOperationNone;
    }
    Sunday, August 26,

    View full-size slide

  17. setData()
    • JavaScript 會透過 dataTransfer 物件的
    setData() 與 getData() 交換資料
    • …但是裡頭的資料⺫⽬目前只能夠是字串,
    如果是 array 等物件,會變成 [object
    Object] 這類字串
    • 所以如果是複雜的資料,我們可以⼀一次
    ⽤用上很多個 Pasteboard key 設定
    • …其實很醜
    Sunday, August 26,

    View full-size slide

  18. setData()
    • 既然只能⽤用字串…
    • 把 JavaScript 物件透過 JSON.stringify()
    與 JSON.parse() 轉成字串
    • Objective C 可以⽤用 NSJSONSerialization
    或是其他第三⽅方 JSON Parser
    • Binary 資料?Base64 吧…
    Sunday, August 26,

    View full-size slide

  19. 查看全部剪貼簿內容?
    Pasteboard Peeker
    蘋果雖然說 Deprecated,但是還是很好⽤用
    Sunday, August 26,

    View full-size slide

  20. 從 NSTableView 拖資
    料放到 WebView
    Sunday, August 26,

    View full-size slide

  21. Objective C
    • NSView 只要實作⼀一個 method 就可以開
    始 Drag 東⻄西出來
    • dragImage:at:offset:event:pasteboard:sour
    ce:slideBack:
    • NSTableView DataSource 則是要實作
    tableView:writeRowsWithIndexes:toPasteb
    oard:
    Sunday, August 26,

    View full-size slide

  22. Objective C
    - (BOOL)tableView:(NSTableView *)tableView
    writeRowsWithIndexes:(NSIndexSet *)rowIndexes
    toPasteboard:(NSPasteboard *)pboard
    {

    [pboard declareTypes:@[@”key”];

    [pboard setString:@"Value String"
    forType:@”key”];

    return YES;
    }
    Sunday, August 26,

    View full-size slide

  23. JavaScript
    • 要讓⼀一個 HTML Element 變成可以接受
    Drop
    • 加上 CSS 屬性:-webkit-user-drop:
    element;
    • 加上 ondragenter、ondragover、ondrop
    等 handler
    Sunday, August 26,

    View full-size slide

  24. JavaScript
    • ⽂文件上⾯面說 ondragenter 與 ondragover 裡
    頭,⼀一定要呼叫 event.preventDefault();
    不然沒有作⽤用
    • 我們可以從 dataTransfer.getData() 拿到
    NSTableView 拖過來的資料
    Sunday, August 26,

    View full-size slide

  25. Das ist alles.
    Sunday, August 26,

    View full-size slide