I have a contenteditable div, like so:
<div id="test" contentEditable="true" style="width: 600px; height:300px;">Lorem ipsum dolor sit amet</div>
for which I use the following code:
<input type="button" value="Click me" onclick="alert(window.getSelection().focusOffset.toString());"></button>
Clicking on the button when I move the caret around in the div, returns to me the actual position (offset) of the caret within the div.
The problem is when I replace the contenteditable div with an input type=text or password control, and keep the contenteditable property=true, and click on the button, I always get a zero. Why is this?
Thanks for looking.
In most browsers, window.getSelection()
only works with selections within text nodes and elements within the document. It doesn't apply to text within <input>
and <textarea>
elements (although in WebKit window.getSelection().toString()
will return the selected text within a focussed text input or textarea. See http://jsfiddle.net/PUdaS/). To get the selection within an input, use the input's selectionStart
and selectionEnd
properties:
<input type="text" id="test" value="Some text">
<input type="button" value="Click me"
onclick="alert(document.getElementById('test').selectionEnd);">
Note that IE up to and including version 8 does not support the selectionStart
and selectionEnd
properties, and a different, more complicated solution is required. IE doesn't support window.getSelection()
either, so this code will work in all the browsers your original code does.
This will largely depend on the browser you are using, as this is a quirk of browser design and not JavaScript.
What happens in your case is when you click an <input type="button">
while having a <div>
highlighted, the <div>
remains highlighted. However, when you click an <input type="button">
while having an <input type="text">
or <textarea>
highlighted, they lose focus and the highlight is removed (thus making your code fail).
I would take a closer look at what you are trying to accomplish and consider rethinking how you are approaching this problem.
2 remarks:
<input... >
tag is not a tag and shall be closed accordingly like <input ... />
otherwise you should use the <button>
tag (but not within a for X-browser compliance reasons)
If you don't want to enter into a non-end story, you may reconsider the way to handle your point as follow : keep your <div>
as it is and fireup a DOM event on that (instead of using the onclick event on the tag). If you can read french, I have summarized plenty of examples here. This way is significant heavier as your first way, but much more powerful afterwards as you can fire up events how you want on the DOM, use callback functions and so on..
The principle is the following :
HTML page on one hand
<div id="test"...>Lorem..</div>
<script src="..."/>
Non intrusive javascript code on the other hand
// your event handler here
function Dothisorthat(e) {
// pop up the dom content or edit it or start an ajax request or whatever you need here
return false;
}
// This is read in the third place
function attacherAction() {
// Attach the action "Dothisorthat" on the event "onclick" occuring on your div "test"
id ='test'; // your div id
if (document.getElementById(id)) {
zLink = document.getElementById(id);
zLink.onclick = function() {
Dothisorthat(this); // in your case, you can write a small function to pop up or edit the div content
}
}
}
// This is read second
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
if (oldonload) {
oldonload();
}
func();
}
}
}
// This is read first
addLoadEvent(attacherAction);
Hope that helps