# Manager that collects and handles multiple tasks that run on events like window.scroll, window.resize etc

I'm working on a website where different things can occur on resize and scroll events. I only want one event handler that comes into play, whenever something in the DOM must be changed.

So I created a TaskManager where you can register objects and callbacks, that are run, when the specific event is fired.

The TaskManager is injected into other objects, where this.taskManager.registerTask() is called to send all necessary information.

The TaskManager then executes all registered tasks, as soon as an event occurs. It also sends the current scrollTop-value to the callback.

class TaskManager {
constructor() {
this.DOM = {
html: document.getElementsByTagName('html')[0],
}

scroll: [],
resize: [],
};

window.requestAnimationFrame(timestamp => {
});
});
}

return false;
}

return true;
}

const scrollTop = window.scrollY || window.scrollTop || this.DOM.html.scrollTop;

}
}
}

class Test {
constructor(config) {

}
}

onScroll(scrollTop) {
console.log('Callback in Test with scrollTop: ' + scrollTop);
}
}

const test = new Test({taskManager: taskManager});
.test {
height: 120vh;
background: rgba(0, 0, 0, 0.2);
text-align: center;
}
<div class="test">Scroll here …</div>

Is this a good approach or could something be improved?

• I'm having difficulty understanding why you'd do this over just doing window.addEventListener('scroll', myFunc). You said that you only want one event handler, but this isn't much different from what the browser does natively. Besides, you don't have resize working in this code -- are you planning to manually create a light proxy for every event type? – Kevin Raoofi Aug 8 '18 at 15:38
• @KevinRaoofi Thanks a lot for your comment. I thought it might be problematic if I have window.addEventListener('scroll', event => {}); on multiple of these objects - like having multiple click-handler on the same button, which might get confusing at some point. I thought it might be helpful to have an overview of all functions that are called on scroll. But if you say, that it doesn't matter how many times window.addEventListener('scroll', event => {}); is set, then I can refrain from this solution and add it directly to the objects that need it. – lampshade Aug 8 '18 at 16:36
• It doesn't matter how many times you add an event listener to something. Of course, there would be overhead, but it's more or less equivalent to the overhead in your code except now it's non-standard. – Kevin Raoofi Aug 8 '18 at 16:50

Some points.

• window is the default object. You don't need to use is. It is highlighted by the fact you don't use it sometimes window.document, or window.TaskManager but then for objects you are unsure of window.addEventListener you add it.

• It is not a good idea to stack requestAnimationFrame requests.

1. Events related to mouse movements can fire at rates much higher than the display refresh rate of 60fps.

2. It introduces an up to 16ms delay on the event (and yes users will notice it as a sluggish response).

3. If used in conjunction with standard event handlers you will be handling events out of order.

4. Completely decouples the handler from the event.

• You have decoupled (ignoring above point) the event from the handler because you don't pass on the event object. If you are going to manage events you should pass on the event object so that the handler can access the event.

• registerTask will happily push events to the stack without checking if the supplied object is a valid. When you come to handling the event eg processTasksOnScroll it will throw if task.target or task.callback do not result in a function reference. If it throws none of the following events will be handled.

• If any of the tasks throws an uncaught error then all following tasks will not be called.

• Regarding requestAniamtionFrame. MDN says it's a good thing to throttle resize- and scroll-events. That's why I followed their examples - and yes, I see that I forgot to add the running-parameter - oh boy. However, do you think this is still needed at all? – lampshade Aug 8 '18 at 16:44
• My main concern is, that I end up attaching window.addEventListener('scroll', event => {}); to multiple objects. If this is something, not to worry about, I will refrain from this solution. I thought it might be problematic, if many different places attach their own event handler for global things like scroll or resize. – lampshade Aug 8 '18 at 16:47