3

I have started playing around with the language Elm. I am making a basic web page and I would like to make my nav bar stick to the top when scrolling.

I would like to be able to make my model react to the distance scrolled down from the top of the page.

I have two problems:

  1. How to access this variable with Javascript? Ideally I would like something like JQuery's $(window).scrollTop() but without JQuery
  2. How to pass this value back to Elm? Do I have to set up a port?
Cattla
  • 3,570
  • 1
  • 13
  • 29
fayong lin
  • 304
  • 2
  • 15

1 Answers1

5

You'll need to set up a port in elm to act as a signal which provides the scrollTop distance. Since we're going to provide that value from javascript, you only need to declare the port function signature:

port scrollTop : Signal Int

On its own, that will do nothing. You have to edit the javascript which initiates your elm application to provide values for that signal. Here's the javascript to set that up:

<script type="text/javascript">
var app = Elm.fullscreen(Elm.Main, {
  scrollTop: document.body.scrollTop
});

window.onscroll = function () {
  app.ports.scrollTop.send(document.body.scrollTop);
};
</script>

Two things to note: You need an initial value for the scrollTop signal. That's what I'm sending in as the second parameter to Elm.fullscreen(). This guarantees that, when your app loads, it will start off with the correct scrollTop value right away. The window.onscroll handler then sends new scrollTop values to that signal any time the window is scrolled.

To test this out, we can write a simple little debugging port that will change the browser title bar to show the current scrollTop value. Add this to the elm file:

port title : Signal String
port title =
  Signal.map toString scrollTop

Lastly, for our test, we just need a tall page. This should do the trick:

main =
  let
    line n =
      div [] [ text <| "Line #" ++ (toString n) ]
  in
    div []
      <| List.map line [0..100]

I have the provided the full code here: Main.elm and scroll-test.html. You can compile that locally, then watch the title bar change as you scroll up and down on the page.

Chad Gilbert
  • 34,769
  • 3
  • 85
  • 96