JSFiddle - React, Tailwind, and code Playground
HTML
Iframe:<br />
<iframe id="text"></iframe>
<textarea style="display: none;" id="iframeDoc">
<html>
<head>
<meta charset="utf-8">
<style>
body {
margin: 0px;
padding: 0px;
font-family: 'Open Sans', 'Arial', sans-serif;
font-size: 13px;
line-height: 26px;
}
.invalid {
background-color: #CC9999;
}
</style>
</head>
<body contenteditable="true"> Какой то текст <span class="invalid">(-blabla-)</span></body>
</html>
</textarea>
CSS
.invalid {
background-color: #CC7777;
}
JavaScript
$(function(){
isIE = /*@cc_on!@*/false;
frame = $('#text').get(0);
frameDoc = isIE ? frame.contentWindow.document : frame.contentDocument;
frameDoc.open();
frameDoc.write($('#iframeDoc').text());
frameDoc.close();
frameDoc.designMode = "on";
$(frameDoc).on('keydown', 'body', function(event) {
var keyCodesList = [ 8, 35, 36, 37, 38, 39, 40, 46 ], // Список клавиш на которые не нужно реагировать
selection = frame.contentWindow.getSelection();
if ($.inArray(event.keyCode, keyCodesList) == -1) {
// Если Node уже помечен как невалидный Xslate (родитель редактируемого элемента не body)
if (selection.isCollapsed &&
selection.anchorNode.parentElement != document.body &&
selection.anchorOffset == selection.anchorNode.length) {
var curRange = selection.getRangeAt(0),
range = document.createRange(),
Span = document.createElement('span');
Span.innerHTML = " ";
$(Span).insertAfter(curRange.endContainer.parentElement);
range.selectNode(Span);
selection.removeAllRanges();
selection.addRange(range);
}
}
});
});