4

I've given the forums a good search on this and cant find a specific answer.

I have a div which is content editable, i have 3 buttons at the top (bold, italic, underline) which apply the execCommand to the highlighted text in the div.

I also have some click events to monitor whats being clicked inside the div to highlight the relevant buttons along the top which works great (ignore the invalid xhtml and go with the theory):

$("[contenteditable]").delegate("u", "click", function (evt) {
    $("[command='underline']").addClass('on');
});

If you happen to click some underlined text in the div the underline command button gets a style of 'on'.

My issue is i now need to create a similar bit of code that monitors where the carret is that does the same job as above instead of a click, (if the user is using the arrow keys to move around the div), this could be called using this bit of code:

$("[contenteditable]").bind("keypress",function(e){
      //something about where the caret is and whats around it here
});

but thats where im stuck, i dont know how to get the parent tags or any other tags for that matter of what the carret might be inside to highlight the relevant buttons at the top.

(My thinking is if there is a solution for that problem, i could ditch the deligate click function because the new carret position function would work anyway)

Really appreciate any help people can give, been working on it for 3 days solid.

======

What a headache!!! But i worked it out!!!!!!

$('[contenteditable]').keydown(function() {
    thiselement = window.getSelection().anchorNode.parentNode;
    $(thiselement).trigger('click');
});

What that will do is trigger the correct click function i referred to earlier for the relevant tag!

Kevin S
  • 73
  • 5
  • A couple of problems there: if you need to support IE < 9, that won't work because those browsers do not support `window.getSelection()`. Another is that `anchorNode` is not guaranteed to be a text node. – Tim Down Aug 09 '11 at 17:41
  • its only being used in firefox so thats not going to be an issue, well spotted though! Could you think of an example where something is not guaranteed to be a text node? – Kevin S Aug 10 '11 at 07:54
  • It depends on the browser, but one obvious example is when you have two adjacent images and the selection boundary is between them. – Tim Down Aug 10 '11 at 12:01
  • Ah right, i understand, that shouldn't be a problem in the example we're thinking of and in the tests we've performed. I'll definitely look out for it though, thank you! – Kevin S Aug 10 '11 at 14:04

1 Answers1

4

Rather than do all this by hand, the browser has methods to tell you if the current selection or caret is bold, italic or whatever: document.queryCommandState() (MSDN), for binary commands such as a bold and italic, and document.queryCommandValue() (MSDN) for commands with a value, such as font-related commands.

This still leaves you the problem of detecting when you need to update your buttons. If you have relatively few then you may be able to get away with doing it whenever a keyup or mouseup event fires, but that won't catch everything (cut/copy/paste from Edit or context menus, drag and drop of text, for example). You could instead poll the selection and content to see if either has changed since the previous check and update your buttons if there has been a change.

Tim Down
  • 318,141
  • 75
  • 454
  • 536