Let's say the browser is separated in three parts: HTML, DOM and JavaScript. The DOM is the middle-man through which HTML and JS can talk.
When the JavaScript loads an element, when using document.getElementById, it tells the DOM: "Hey, I need this element!". If the DOM finds it, it returns the element in a special object called a DOM element.
When the HTML changes (you input some value into a field), it sends a message to the DOM: "Hey, my value is not the same over here.". And thus the DOM updates its DOM element.
When the JavaScript adds an event listener on keypress, it tells the DOM: "Hey, whenever a keypress event is sent, please tell me.".
So when the HTML changes (a keypress is done in an input), it tells the DOM: "Hey, there is a keypress event there!". And since the DOM knows that JS is waiting for updates on keypress events, it tells to JS: "Hey dude, an event was triggered there.".
If you run the event from JS itself, the DOM will send back right away to JS: "Hey, a keypress event was triggered, thought you might be interested.". It doesn't go to the HTML and changes it.
Why? Because the DOM doesn't trust the JS. It knows JS is a bad boy. The keyword here is "trust". As pointed out by @Benjamin, there are trusted events. Although very few of them. And there are the "trusted ones for backward compatibility".
Yes, the DOM is a mess.