Search code examples
javascriptjquerybbcodehtml-editornodevalue

Javascript window.getSelection().focusNode.nodeValue return with HTML


Hy... i dont really want to use other poeple editor...

i want to learn "how to create" not "how to use"

so i decided to create my own editor...

My editor

its easy to create bbcode editor... but when i try to create the HTML Version ( Live Preview & Editing )

i have a little problem ( may be my biggest problem ) Of course making a question is my last hope after searching...

anyway, my english is bad, so i hope you can understand what i'm saying.

Look, My Expectation VS Really

Expectation VS Really

And this is the simplest of my editor

$(document).ready(function(){
	$(".buttonBold").click(function(){
		$(".editableDiv").focus();
		var help_me_anchorNode 			= window.getSelection().anchorNode.nodeValue;
		var help_me_anchorOffset 		= window.getSelection().anchorOffset
		var help_me_focusOffset 		= window.getSelection().focusOffset
		var help_me_focusNodeValueLength 	= window.getSelection().focusNode.nodeValue.length;
		var help_me_firstTag 			= "<b>";
		var help_me_lastTag 			= "</b>";

		if(help_me_anchorOffset > help_me_focusOffset){
			var help_me_firstTag 		= "</b>";
			var help_me_lastTag 		= "<b>";
		}
		window.getSelection().anchorNode.nodeValue = help_me_anchorNode.slice(0, help_me_anchorOffset) + help_me_firstTag + help_me_anchorNode.slice(help_me_anchorOffset);
		var help_me_focusNodeValue = window.getSelection().focusNode.nodeValue;
		if(window.getSelection().focusNode.nodeValue.length - help_me_focusNodeValueLength > 0) {
			help_me_focusOffset += window.getSelection().focusNode.nodeValue.length - help_me_focusNodeValueLength;
		}
		window.getSelection().focusNode.nodeValue = help_me_focusNodeValue.slice(0, help_me_focusOffset) + help_me_lastTag + help_me_focusNodeValue.slice(help_me_focusOffset);
	});

});
.editableDiv{
	width: 300px;
	height: 100px;
	background: #ccc;
	padding: 10px;
	}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>

<button class="buttonBold">Bold</button>
<div class="editableDiv" contenteditable="true">
Double click this : HELPME
<br />
<br />
And then, click the "Bold" Button
<br />
The result will : &lt;b&gt;HELPME&lt;/b&gt;
<br />
Not : <b>HELPME</b>
</div>


Solution

  • You can use window.getSelection() and .surroundContents()

    $(".buttonBoldHtml").click(function(){
      $(".editableDiv").focus();
    
      var highlight = window.getSelection(),
          bold = $('<b/></b>')[0],
          range = highlight.getRangeAt(0);
      range.surroundContents(bold);
    });
    

    If you select partial nodes (when the highlighted text begins or stop between an open tag), you have to use extractContents() :

    $(".buttonBoldHtml").click(function(){
      $(".editableDiv").focus();
    
      var range = window.getSelection().getRangeAt(0),
          bold = document.createElement('b');
      bold.appendChild(range.extractContents());
      range.insertNode(bold);
    });
    

    I've edited the demo and added a test with both bold and italic:

    Demo