Perhaps "pure" events are a recipe for spaghetti code, the same way a low-level anything is a recipe for that. But if you have a framework built on top of events, then it's very maintainable.
MacOS apps, for instance, are built largely around Objective C, which borrows concepts from SmallTalk. They have delegates and other "we'll call you" concepts. Compare that with Windows apps in the past, where you had to write your own event loop and explicitly listen for events.
On the web, a library like Angular.js encourages you to put your code in one place and it "takes care of the rest". The "inversion of control" is once again very central to the whole thing. And in both cases, it makes for great declarative UI building (UI builder on the Mac, HTML on the web).
In short, if you have a framework, chances are it exposes BOTH kinds of things -- you call it to create / manipulate some objects, but it also calls YOUR code on important events.
If you don't care about mousedown/up events vs touchstart/end events - fine. All that can be abstracted into other events. But you need to respond to events -- whether user input or things coming in.
In our framework, Q, we actually strongly encourage the developer to update their views on events instead of "ajax success" callbacks. That's because Q is built to power SOCIAL apps, and when you're collaborating on a document, you can't predict when a new message will be pushed via a socket ... it may come from someone else posting it to the collaborative document!
So you can't just "avoid" events -- they have their place, especially in multi-user real time environments.