Monitoring Viewport Dimensions, with Debounce

If you need to monitor viewport dimensions beyond what is available via CSS @media, you can push viewport resize event information to a .ex module.

This feature pushes viewport dimensions on both a mounted event and uses a resize listener and a 300ms debounce js function to push viewport dimensions on viewport resize events.

You need to edit app.js, use Hooks, and edit an .ex module


  • In a Hook mounted handler, add:
	    let resizeHandler


	    resizeHandler = debounce(() => {
	    }, 100)
	    window.addEventListener('resize', resizeHandler)

  • In the same Hook, below the mounted handler, add:
  pushResizeEvent () {
    console.log("viewport_resize event, width: " + window.innerWidth + ", height: " + window.innerHeight)
	this.pushEvent('viewport_resize', {
	  width: window.innerWidth,
	  height: window.innerHeight

  • Outside of Hooks section, add the following functions. I have included the debounce_leading function for reference, if you ever have a need to process the initial reported value rather than the last reported value during debounce.
function debounce(func, timeout = 300){
  let timer
  return (...args) => {
    timer = setTimeout(() => { func.apply(this, args); }, timeout)

function debounce_leading(func, timeout = 300){
  let timer;
  return (...args) => {
    if (!timer) {
      func.apply(this, args);
    timer = setTimeout(() => {
      timer = undefined;
    }, timeout);


  • Add width and height params to your socket.assigns
  • Add an event handler for the viewport_resize event
  @impl true
  def handle_event("viewport_resize", %{"width" => width, "height" => height}, socket) do
    IO.puts "GameLive viewport_resize: #{width}, #{height}"
    {:noreply, assign(socket, width: width, height: height)}

  • Add methods that examine width and height in the socket.assigns, to perform viewport based calculations