This: socket.onmessage = function (event) { if (typeof event.data == 'string') { // control frame if (event.data == 'profile is next') { socket.binaryType = Blob; socket.addEventListener('message', handleGettingProfile, false); } else if (event.data == 'game data is next') { socket.binaryType = ArrayBuffer; socket.addEventListener('message', handleGettingGameData, false); } } }; function handleGettingProfile(event) { handleGettingProfile(event.data); // passed a blob event.target.removeEventListener(event.type, handleGettingProfile, false); } function handleGettingGameData(event) { handleGettingGameData(event.data); // passed a blob event.target.removeEventListener(event.type, handleGettingGameData, false); } handles cases like: "profile is next" profile [handled] profile [gets ignored] "game data is next" "profile is next" profile [handled] ...without blinking. On the other hand, this: socket.onmessage = function (event) { if (typeof event.data == 'string') { // control frame if (event.data == 'profile is next') { socket.responseType = Blob; socket.addEventListener('message', handleGettingProfile, true); } else if (event.data == 'game data is next') { socket.responseType = ArrayBuffer; socket.addEventListener('message', handleGettingGameData, true); } } else { // happens after the other handlers because they are capture handlers and capture gets called first socket.responseType = String; } }; function handleGettingProfile(event) { handleGettingProfile(event.data); // passed a blob event.target.removeEventListener(event.type, handleGettingProfile, true); } function handleGettingGameData(event) { handleGettingGameData(event.data); // passed a blob event.target.removeEventListener(event.type, handleGettingGameData, true); } ...would result in the following: "profile is next" profile [handled] profile [gets ignored] "game data is next" "profile is next" [gets treated as game data somehow, though i'm not sure how to convert text to arraybuffer] profile [ignored]