2015-10-24 100 views
0

我有一個相當簡單的榆樹申請我怎麼能當我拖過一個元素髮送消息

https://github.com/chrisortman/team-player

我無法弄清楚如何實現的東西,會讓我點擊下表中的單元格並拖動到其他幾個單元格上以選擇它們。

它似乎onMouseOver是我想要的,但我不知道如何將它與Mouse.isDown信號相結合。我可以結合Mouse.isDown和Mouse.position,但是我不知道如何將位置綁定回表格單元格。

我覺得這個想法讓我靠近......

import Mouse 
import Html exposing(..) 
import Html.Attributes exposing(style) 
import Html.Events exposing(onMouseOver,onClick) 
import Signal exposing(..) 

positionWithButton2 = 
    Signal.map3 (,,) Mouse.isDown Mouse.position mouseEvents.signal 
    |> Signal.filterMap positionIfDown (0,0) 

--positionWithButton = 
-- Signal.map2 (,) Mouse.isDown Mouse.position 
-- |> Signal.map positionIfDown 

font : List (String, String) 
font = 
    [ ("font-family", "futura, sans-serif") 
    , ("color", "red") 
    , ("font-size", "2em") 
    ] 

type ElementAction 
    = Hover Int 
    | NoHover 

mouseEvents = Signal.mailbox NoHover 

background : List (String, String) 
background = 
    [ ("background-color", "rgb(245, 245, 245)") 
    ] 

positionIfDown (isDown,position,hover) = 
    case (isDown,hover) of 
    (True, Hover x) -> Just (x,x) 
    (True, NoHover) -> Just position 
    (False, Hover x) -> Just position 
    _ -> Nothing 


view pos = 
    div [ ] 
    [ p [ style (font ++ background)] [text (toString pos)] 
    , h1 [onMouseOver mouseEvents.address (Hover 10)] 
     [text "Magic"] 
    , Html.button 
     [ onClick mouseEvents.address NoHover] 
     [text "Stop"] 
    ] 

main : Signal Html 
main = 
    Signal.map view positionWithButton2 

回答

3

你會的,我擔心,需要多一點參與做一些事情。

甚至在嘗試使用elm版本之前,我們應該考慮在用戶嘗試拖動多個單元格時觸發的JavaScript事件。

___________________ 
|(0,1)|(1,1)|(2,1)| 
|_____|_____|_____| 
|(0,0)|(1,0)|(2,0)| 
|_____|_____|_____| 

比方說,有人開始從單元格(1,1)拖動。我們會收到初始mousedown事件,然後我們將開始收到mousemove事件。當我們繼續拖延,進入單元格(1,2)時會發生什麼?那麼,(1,2)不會收到「單擊」或「鼠標按下」事件,但mouseentermouseover必火,和mousemove應繼續火了,我認爲target屬性將改變是細胞(1,2)

那麼,我們需要做些什麼來確定在榆樹地區突出顯示的內容?我很容易看到你已經在使用elm-html - 我們將不得不使用它的Events部分。

N.B我把這些放在一起,沒有編譯器的幫助,所以可能會有一些錯誤;形狀雖然感覺正確。

首先,我們需要這個片段:

import Json.Decode exposing ((:=), Decoder) 
targetId : Decoder String 
targetId = ("target" := ("id" := J.string))   

這將從給定事件的目標元素的ID進行解碼。

我們需要以下事件定義

data Event = SelectStart String 
      | SelectContinue String 
      | SelectCancel 

和郵箱各地送他們

events : Signal.Mailbox (Event) 
events = Signal.mailbox SelectCancel 

每個細胞都需要被考慮到在它的座標信息(idcell-0-1,cell-1-1等)以及以下事件:

import Html.Events exposing (on) 

on 'mousedown' targetId (\id -> Signal.message events.address (SelectStart id)) 
on 'mousemove' targetId (\id -> Signal.message events.address (SelectContinue id)) 

這應該會給你足夠的信息來確定通過對events.signal上的事件進行適當的處​​理而選擇了什麼。 N.B您可能還想附加一些其他元素來取消現有選擇而不開始另一個元素;我不知道你想達到什麼樣相當,但:-)

你的模型應該有一個看起來有點像場:

type alias SelectRange = ((Int, Int), (Int, Int)) 

type alias Model = { 
    selectState : Maybe SelectRange 
} 

我們收到的第一SelectStart事件,我們的工作從id字符串中取出座標(假設它是(0,0)),並將selectState更改爲Just ((0,0), (0,0))SelectContinue事件然後開始啓動;我們會忽略他們,但他們仍然參考(0, 0),但是當到達(0,1);我們檢查現有的選擇狀態並決定它現在應該是Just ((0,0),(0,1))。總共編寫update函數是棘手的(用戶可能會向一個方向拖動然後反向拖動),但並非不可能。

假設所選單元格的渲染方式與未選中的單元格不同,我們可以將selectState指定給視圖函數,並且在渲染每個單元格時,可以檢查它是否被選中並且行爲適當。

我希望這是足夠的信息,讓你去;如果有什麼不清楚的地方,請詢問:-)

相關問題