I am trying to build a E pub Reader. I am able to highlight the user selected text and i am getting the x path of that particular selected text. After that i am trying to build a function which takes x path as parameter and show the user selected text by changing background color. but its not working.
Code:-
function uiWebview_restoreSelection() {
var selectionDetails = "/HTML[1]/BODY[1]/DIV[1]/text()[1]|910|/HTML[1]/BODY[1]/DIV[1]/text()[1]|930";
//alert("selectionDetails"+selectionDetails);
if (selectionDetails != null) {
selectionDetails = selectionDetails.split(/\|/g);
alert("selectionDetails" + selectionDetails);
if (typeof window.getSelection != 'undefined') {
var selection = window.getSelection();
selection.removeAllRanges();
var range = document.createRange();
var selectionDetails0 = selectionDetails[0];
alert("selectionDetails0" + selectionDetails0);
selectionDetails0 = selectionDetails0.replace(/\//g, "/h:");
selectionDetails0 = selectionDetails0.replace("h:t", "t");
alert("selectionDetails0" + selectionDetails0);
var selectionDetails2 = selectionDetails[2];
alert("selectionDetails2" + selectionDetails2);
selectionDetails2 = selectionDetails2.replace(/\//g, "/h:");
selectionDetails2 = selectionDetails2.replace("h:t", "t");
alert("selectionDetails2" + selectionDetails2);
range.setStart(document.evaluate(selectionDetails0, document, nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue, Number(selectionDetails[1]));
range.setEnd(document.evaluate(selectionDetails2, document, nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue, Number(selectionDetails[3]));
document.designMode = "on";
var newSpanMark = document.createElement("span");
document.execCommand("HiliteColor", false, "red");
range.insertNode(newSpanMark);
document.designMode = "off";
}
}
}
Please suggest for the above problem.
Thanks in Advance
Related
Is it possible to diversify the font size only in some parts of the text in a textarea with Javascript?
custom_button.onclick = function () {
// IE version
if (document.selection != undefined)
{
component_name.focus();
var sel_ie = document.selection.createRange();
textNew = sel_ie.text;
}
// Mozilla version
else
{
var startPos = document.getElementById(component_name).selectionStart;
var endPos = document.getElementById(component_name).selectionEnd;
textNew = document.getElementById(component_name).value.substring(startPos, endPos);
}
var finalText = text.substr(0,startPos) + '<font size="100">' + textNew + '</font>' + text.substr(endPos);
}
When I usually write the code above I achieve the following result into the textarea:
This <font size="100">is the</font> text
I'm facing some problem in using javascript.The scenario is like html object has one parent element paragraph and 4 child element span . when we select text we are getting text position with respect to span element , but i want to get text selecting text with respect to parent so can you please guide me how i can?
I'm using this code that each time give position with respect to selected container like
<p>I'm using this code that each time<span>give position with respect to selected container like</span></html>
i want to get text position " respect" on upper code with respect to p tag not with repect to span tag.
var sel = window.getSelection();
var selRange = sel.getRangeAt(0);
var start = selRange.startContainer;
var startElemPath = pathOfElement(start);
var startoff = selRange.parentNode.startOffset;
alert("startoff>>"+startoff);
var end = selRange.endContainer;
var endElemPath = pathOfElement(end);
var endoff = selRange.endOffset;
You can use this process to get start off set and end off set of selected text.
function getCaretCharacterOffsetWithin(objectId, win)
{
var startOffSet = 0;
var endOffset = 0;
var element = window.frames[0].document.getElementById(objectId);
var parentInnerHTML = element.innerHTML.toString();
var parentNodeArr = parentInnerHTML.split('');
if(parentInnerHTML != "null"){
var sel;
if (typeof win.getSelection != "undefined")
{
var rangeIndex = 0;
var parentIndex = 0;
var max = parentInnerHTML.length - 1;
var range = win.getSelection().toString();
var rangeNodeArr = range.split('');
var rangeLen = rangeNodeArr.length - 1;
for (parentIndex=0; parentIndex <= max; parentIndex++)
{
if(parentNodeArr[parentIndex] === rangeNodeArr[rangeIndex]){
if(rangeIndex === rangeLen){
break;
}
rangeIndex++;
}else{
rangeIndex = 0;
}
}
endOffset = parentIndex + 1;
startOffSet = parentIndex - rangeIndex;
}
console.log("startOffSet: " + startOffSet + " endOffset: " + endOffset);
return { startOffSet: startOffSet, endOffSet: endOffset };
}else{
console.log("Parent is null");
}
}
try setting the Range's start node to p
startNode = document.getElementsByTagName("p")[0];
selRange.setStart(startNode,0);
I am using document.getSelection() to select some text. I would like to know what type of element the selected range contains (I specifically want to see if it is an anchor tag).
var selection = document.getSelection();
var range = selection.getRangeAt(0);
So I can get the range, but how can I know what element is in that range? Happy to use plain js or jQuery.
EDIT:
Here is what I came up with:
var updateLink = function(url) {
var selection = document.getSelection();
var range = selection.getRangeAt(0);
if (range != 0) {
var containerElement = range.commonAncestorContainer;
if (containerElement.nodeType != 1) {
containerElement = containerElement.parentNode;
var e = $(containerElement);
e.attr('href', url);
}
}
}//end
Try this:
var obj = document.getSelection();
var parentNode = $(obj.anchorNode).parent();
Here is jsfiddle
You could use cloneContents() method:
DEMO
$(document).mouseup(function(){
var range = window.getSelection().getRangeAt(0),
selectionContents = range.cloneContents();
alert($(selectionContents.childNodes).filter('a').length);
});
I am about to implement Facebook like in integration in my contenteditable div where if i give '$' and some character like 'a' i need a auto-suggestion which should pop up near my caret position.
I need to know how to find out the last character before caret position either in JavaScript for IE and Other browsers. I have access to the Jquery library.
(function($) {
$.fn.getCursorPosition = function() {
var input = this.get(0);
if (!input) return; // No (input) element found
if ('selectionStart' in input) {
// Standard-compliant browsers
return input.selectionStart;
} else if (document.selection) {
// IE
input.focus();
var sel = document.selection.createRange();
var selLen = document.selection.createRange().text.length;
sel.moveStart('character', -input.value.length);
return sel.text.length - selLen;
}
}
})(jQuery);
eg.
var caretPosition = $("#contenteditablediv").getCursorPosition();
var lastchar = getchar(caretposition -1);???
Here's an example of how to do this. It creates a range that starts at the start of the editable element and ends immediately before the caret, gets the range's text and returns the last character of that range.
Demo: http://jsfiddle.net/MH5xX/
function getCharacterPrecedingCaret(containerEl) {
var precedingChar = "", sel, range, precedingRange;
if (window.getSelection) {
sel = window.getSelection();
if (sel.rangeCount > 0) {
range = sel.getRangeAt(0).cloneRange();
range.collapse(true);
range.setStart(containerEl, 0);
precedingChar = range.toString().slice(-1);
}
} else if ( (sel = document.selection) && sel.type != "Control") {
range = sel.createRange();
precedingRange = range.duplicate();
precedingRange.moveToElementText(containerEl);
precedingRange.setEndPoint("EndToStart", range);
precedingChar = precedingRange.text.slice(-1);
}
return precedingChar;
}
var editableEl = document.getElementById("editable");
var precedingCharEl = document.getElementById("precedingChar");
function reportCharacterPrecedingCaret() {
precedingCharEl.innerHTML = "Character preceding caret: " + getCharacterPrecedingCaret(editableEl);
}
editableEl.onmouseup = editableEl.onkeyup = reportCharacterPrecedingCaret;
<div contenteditable="true" id="editable">Here is some text. Please put the caret somewhere in here.</div>
<div id="precedingChar" style="font-weight: bold"></div>
This is the code (now is full):
HTML:
<div id="content" contentEditable="true" onkeyup="highlight(this)">This is some area to type.</div>
Javascript:
function highlight(elem){
// store cursor position
var cursorPos=document.selection.createRange().duplicate();
var clickx = cursorPos.getBoundingClientRect().left;
var clicky = cursorPos.getBoundingClientRect().top;
// copy contents of div
var content = elem.innerHTML;
var replaceStart = '';
var replaceEnd = '';
// only replace/move cursor if any matches
// note the spacebands - this prevents duplicates
if(content.match(/ test /)) {
elem.innerHTML = content.replace(/ test /g,' '+replaceStart+'test'+replaceEnd+' ');
// reset cursor and focus
cursorPos = document.body.createTextRange();
cursorPos.moveToPoint(clickx, clicky);
cursorPos.select();
}
}
Just woks on IE, unhapply.
Anyone can 'adjust' this code, to work on FF too!...
Thanks
Edit[1]:
Div Editable and More... More
This code replaces a especific word by the same word formatted...
And the caret (cursor) stay always after the word replaced! <<< "This is the big"
But just works on IE, and I like so much to rewrite this code to work on FF... but I can't do it... Its so hard...
Anyone can help?
Edit[2]:
My problem is just with this part:
// reset cursor and focus
cursorPos = document.body.createTextRange();
cursorPos.moveToPoint(clickx, clicky);
cursorPos.select();
Because, moveToPotion and select functions just works on IE... Until then it is easy...
On FF there is another set of functions that make it possible... But i don't know how to write another code that do the same things. Do you got it?
You can preserve the caret position by inserting a marker element at its current location before doing your replacement on the element's innerHTML. (Using DOM methods to traverse the text nodes and searching each for the text you want would be preferable to using innerHTML, by the way).
The following works, so long as the caret is not positioned within or adjacent to the word "text". I also added a timer to prevent calling this function every time a key is pressed and to wait for the user to stop typing for half a second.
function insertCaretMarker() {
var range;
var markerId = "sel_" + new Date() + "_" + ("" + Math.random()).substr(2);
if (window.getSelection) {
var sel = window.getSelection();
range = sel.getRangeAt(0);
range.collapse(true);
var markerEl = document.createElement("span");
markerEl.appendChild(document.createTextNode("\u00a0"));
markerEl.id = markerId;
range.insertNode(markerEl);
} else if (document.selection && document.selection.createRange) {
range = document.selection.createRange();
range.collapse(true);
if (range.pasteHTML) {
range.pasteHTML("<span id=\"" + markerId + "\"> </span>");
}
}
return markerId;
}
function restoreCaret(markerId) {
var el = document.getElementById(markerId);
var range;
if (el) {
if (window.getSelection && document.createRange) {
var sel = window.getSelection();
range = document.createRange();
range.setStartBefore(el);
sel.removeAllRanges();
sel.addRange(range);
} else if (document.body.createTextRange) {
range = document.body.createTextRange();
range.moveToElementText(el);
range.collapse(true);
range.select();
}
el.parentNode.removeChild(el);
}
}
function preserveCaretPosition(func) {
var id = insertCaretMarker();
func();
restoreCaret(id);
}
var highlightTimer;
function highlight(elem) {
if (highlightTimer) {
window.clearTimeout(highlightTimer);
}
highlightTimer = window.setTimeout(function() {
highlightTimer = null;
var replaceStart = '<b>';
var replaceEnd = '</b>';
// only replace/move cursor if any matches
// note the spacebands - this prevents duplicates
if (elem.innerHTML.match(/ test /)) {
preserveCaretPosition(function() {
elem.innerHTML = elem.innerHTML.replace(/ test /g, ' ' + replaceStart + 'test' + replaceEnd + ' ');
});
}
}, 500);
}