Forum Moderators: open
<div id="foo">
<font face="Arial"><font size="7"><b>This is <i>a</i> test</b></font></font>
</div>
var text;
$('#foo').on('mouseup', function() {
if (window.getSelection) {
var div = document.createElement('div');
div.appendChild(window.getSelection().getRangeAt(0).cloneContents());
text = div.innerHTML;
}
alert(text); // use this to expand the selection, forcing it to pick up the next word boundary
function expand(range) {
if (range.collapsed)
return;
while (range.toString()[0].match(/\w/))
range.setStart(range.startContainer, range.startOffset - 1);
while (range.toString()[range.toString().length - 1].match(/\w/))
range.setEnd(range.endContainer, range.endOffset + 1);
}
$('#foo').on('mouseup', function() {
var sel = window.getSelection();
var cont = document.createElement("div");
var selectionRange, selection;
if (sel.rangeCount) {
// I know it's probably overkill to put it in a loop, but since I'm
// still in production, why not...
for (var i = 0; i < sel.rangeCount; i++) {
selectionRange = sel.getRangeAt(i);
var start = selectionRange.startOffset;
// this works, and expands the selection like expected
expand(selectionRange);
// if I double-click then this alerts, but if I click and drag it doesn't
alert('yeah?');
cont.appendChild(selectionRange.cloneContents());
}
selection = cont.innerHTML;
}
// either way, selection is always empty
if (selection)
alert(selection);
else alert('no selection');
}); <span style="font-size: 220%"><span style="font-size: 100%"><span style="font-size: 160%">This is <i>a</i> test</span></span></span> <span style="font-size: 100%">Hey you, <span style="font-size: 160%">This is <i>a</i> test</span></span>
I am not going to work with "font elements" and neither should you.
Try instead this example...
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,height=device-height,initial-scale=1">
<title>untitled document</title>
<link rel="stylesheet" href="screen.css" media="screen">
<style media="screen">
body {
background-color: #f9f9f9;
font: 100% / 162% verdana, arial, helvetica, sans-serif;
}
#foo {
padding: 0.5em 0;
font-family: arial;
text-align: center;
}
.two-em {
font-size:2em;
}
.three-em {
font-size:3em;
}
</style>
</head>
<body>
<div id="foo" class="three-em">
<b>This is <i>a</i> test</b>
</div>
<script>
( function( d ) {
'use strict';
var sp, foo = d.getElementById( 'foo' ),
b = d.getElementsByTagName( 'b' )[0],
parent = b.parentNode;
foo.addEventListener( 'mouseup',
function() {
foo.classList.remove( 'three-em' );
foo.classList.add( 'two-em' );
sp = document.createElement( 'span' );
sp.appendChild(document.createTextNode( 'Hey you, '));
parent.insertBefore( sp, b )
}, false );
}( document ) );
</script>
</body>
</html>
I forgot to mention that the "mouseup" event handler could be replaced
by "click", if preferred, as the code is not now dependent upon selection. ;)
# this is the code for the contenteditable element
<div contenteditable="true" style="font-size: 2em">
# this is what's entered by the user
<span style="font-size: 220%">Getting the surrounding tags of selection</span><br><br><span style="font-size: 120%">I've been working on this for 3 days, so now I guess it's time to turn to the pros again :-(</span>
</div> Failed to execute 'setEnd' on 'Range': The offset 6 is larger than the node's length (5).
while (
selectionRange.toString()[selectionRange.toString().length - 1].match(/\w/) &&
# sometimes this is NaN
selectionRange.endOffset &&
!isNaN(selectionRange.endOffset) &&
# how do I get the node length?
(selectionRange.endOffset + 1) <= [NODE LENGTH]
) {
selectionRange.setEnd(selectionRange.endContainer, selectionRange.endOffset + 1);
}
if you are going to have "contenteditable",
then you will not be able to use "mouseup".
Here is a possible solution...
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,height=device-height,initial-scale=1">
<title>untitled document</title>
<link rel="stylesheet" href="screen.css" media="screen">
<style media="screen">
body {
background-color: #f9f9f9;
font: 100% / 162% verdana, arial, helvetica, sans-serif;
}
#foo {
max-width: 40em;
padding: 1em;
margin: auto;
border: 1px solid #999;
background-color: #fff;
}
</style>
</head>
<body>
<div id="foo" contenteditable> </div>
<button id="but">manipulate input</button>
<script>
(function( d ) {
'use strict';
var foo = d.getElementById( 'foo' ),
but = d.getElementById( 'but' );
but.addEventListener( 'click',
function(){
foo.innerHTML = foo.textContent
.replace( /\ /, '' )
.replace( /\</g, '<' )
.replace( /\>/g, '>' ) ;
}, false );
}( document ));
</script>
</body>
</html>