This is actually possible (at least in Chromium-based browers like Chrome and Edge), it's just a pain. You can get it via the selection interface:
const input = /*...the input...*/;
input.select();
const text = getSelection().toString();
No luck on Firefox, sadly.
Live Example:
const theInput = document.getElementById("the-input");
const theButton = document.getElementById("the-btn");
function saveSelection() {
const selection = getSelection();
const range = selection.rangeCount === 0 ? null : selection.getRangeAt(0);
return range;
}
function restoreSelection(range) {
const selection = getSelection();
selection.removeAllRanges();
selection.addRange(range);
}
function getRawText(input) {
const sel = saveSelection();
input.select();
const text = getSelection().toString();
restoreSelection(sel);
return text;
}
theButton.addEventListener("click", event => {
const value = theInput.value;
const text = getRawText(theInput);
console.log(`value = "${value}", but text = "${text}"`);
});
<p>
Copy some invalid numeric text (like <code>9-9</code>) and paste it into this field:
</p>
<input type="number" id="the-input">
<p>
Then click here: <input type="button" id="the-btn" value="Go">
</p>