2016-12-16 10 views
1

Есть ли способ узнать, расположена ли полоса прокрутки в нижней части элемента в Elm? Я использую Dom.Scroll.toBottom для прокрутки до нижней части списка при добавлении элемента списка. Это отлично работает, оставляя его в покое. Но если вы вручную немного прокрутите список, я не хочу автоматически прокручивать вниз до конца (пока вы не перейдете вручную вниз). В противном случае вы не сможете просмотреть предыдущие элементы списка.Как узнать, находится ли полоса прокрутки в нижней части элемента

+0

Есть ли какие-либо проблемы, которые не позволяют использовать [ 'Dom.Scroll.y'] (HTTP: // package.elm-lang.org/packages/elm-lang/dom/1.1.1/Dom-Scroll#y)? – lonelyelk

+0

@lonelyelk 'Dom.Scroll.y' недостаточно, чтобы узнать, находится ли полоса прокрутки в нижней части элемента. 'y' только говорит вам, как далеко вниз (в пикселях) прокрутка. Не зная, насколько далека дно **, как бы вы знали, что находитесь внизу? –

ответ

1

Я был в состоянии получить clientHeight, scrollHeight и scrollTop объектов со следующим кодом. Это было необходимо, чтобы узнать, находится ли свиток в нижней части элемента. Остальная часть кода реализует механизм автоматической прокруткой только если свиток уже на дне:

type alias Model = 
    { messages : List Message 
    , autoScrollMessages : Bool 
    } 

type Msg 
    = NoOp (Result Dom.Error()) 
    | ReceiveMessage ReceivedMessage 
    | ScrolledMessages ScrollEvent 

update : Msg -> Model -> (Model, Cmd Msg) 
update msg model = 
    case msg of 
     NoOp res -> 
      (model, Cmd.none) 
     ReceiveMessage message -> 
      ({ model | messages = model.messages ++ [ message ] } , if model.autoScrollMessages then Task.attempt NoOp (Scroll.toBottom "messages") else Cmd.none) 
     ScrolledMessages scrollEvent -> 
      ({ model | autoScrollMessages = scrollEvent.scrollPos == scrollEvent.scrollHeight - scrollEvent.visibleHeight }, Cmd.none) 

type alias ScrollEvent = 
    { scrollHeight : Int 
    , scrollPos : Int 
    , visibleHeight : Int 
    } 

onScroll : (ScrollEvent -> msg) -> Html.Attribute msg 
onScroll tagger = 
    Html.Events.on "scroll" (Decode.map tagger onScrollJsonParser) 

onScrollJsonParser : Decode.Decoder ScrollEvent 
onScrollJsonParser = 
    Decode.map3 ScrollEvent 
     (Decode.at ["target", "scrollHeight"] Decode.int) 
     (Decode.at ["target", "scrollTop"] Decode.int) 
     (Decode.at ["target", "clientHeight"] Decode.int) 

viewMessages : List Message -> Html Msg 
viewMessages messages = 
    ul 
     [ id "messages" 
     , onScroll ScrolledMessages 
     ] <| List.map viewMessage messages