Reputation: 220
I'm having problems with setting caret position in a contentEditable iframe, as soon as I add an ":)" emoticon.
How would you manage?
Here is a basic template:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
var init = function () { // initialization
this.editor = $('#wysiwyg');
this.editor.curWin = this.editor.prop('contentWindow');
this.editor.curDoc = this.editor.curWin.document;
this.editor.curDoc.designMode = "On";
this.editor.curBody = $(this.curDoc).contents().find('body');
this.editor.html = function (data) { // shortcut to set innerHTML
if (typeof data == "undefined")
return this.curBody.html();
this.curBody.html(data);
return $(this);
};
var emoji = function (data) { // replace every :) by an image
return data.replace(':)', '<img src="http:\/\/dean.resplace.net\/blog\/wp-content\/uploads\/2011\/10\/wlEmoticon-smile1.png"\/>');
};
var self = this;
this.editor.contents().find('body').keypress(function (ev) { // handler on key pressed
var me = $(this);
setTimeout(function () { // timeout so that the iframe is containing the last character inputed
var sel = self.editor.curWin.getSelection();
var offset = sel.focusOffset;
me.html( emoji( me.html() ) );
var body = $(self.editor.curDoc).find('body').get(0);
sel.collapse(body, offset); //here is where i set positionning
return;
}, 100);
return true;
});
};
</script>
</head>
<body onload="init()">
<iframe id="wysiwyg"></iframe>
</body>
</html>
StackOverflow demands that i add more context to explain the code sections, but for me it seems to be clear. So sorry to add so more "cool story bro" comments but i can't see what i can explain more than this. Anyway, i'm open to any question.
Upvotes: 0
Views: 626
Reputation: 17666
Quick fix... check to see if a replacement is being made... if there is one being made then readjust the caret. otherwise leave it be.
var init = function() { // initialization
this.editor = $('#wysiwyg');
this.editor.curWin = this.editor.prop('contentWindow');
this.editor.curDoc = this.editor.curWin.document;
this.editor.curDoc.designMode = "On";
this.editor.curBody = $(this.curDoc).contents().find('body');
this.editor.html = function(data) { // shortcut to set innerHTML
if (typeof data == "undefined") return this.curBody.html();
this.curBody.html(data);
return $(this);
};
var emoji = function(data) { // replace every :) by an image
var tmp = data;
tmp = tmp.replace(':)', '<img src="http:\/\/dean.resplace.net\/blog\/wp-content\/uploads\/2011\/10\/wlEmoticon-smile1.png"\/>');
if (tmp !== data) {
return [true, tmp];
}
return [false, tmp];
};
var self = this;
this.editor.contents().find('body').keypress(function(ev) { // handler on key pressed
var me = $(this);
var res = emoji(me.html());
if (res[0]) {
setTimeout(function() { // timeout so that the iframe is containing the last character inputed
var sel = self.editor.curWin.getSelection();
var offset = sel.focusOffset;
me.html(res[1]);
var body = $(self.editor.curDoc).find('body').get(0);
sel.collapse(body, offset); //here is where i set positionning
return;
}, 100);
}
return true;
});
};
init();
Upvotes: 1