问题
I wrote a code to detect the end of selection using javascript, and to place a marker at the end position. See this jsfiddle: http://jsfiddle.net/vCwwN/
The above code do the following:
- It handles all LTR scripts (e.g. English) properly (showing marker at the end correctly).
- For LTR scripts (e.g. English) It handles whether the selection is forward (from left/top to right/bottom) or backward (from right/bottom to left/top) properly showing the marker where the selection stopped (using mouse or keyboard).
- It uses
getClientRects
to find all the selection rectangles boundaries, and a hack to detect the direction of selection (if backward or not). Depending on these two information, it places the marker at the end.
You can try selecting what is described above for English script without any problem. The only problem is when you try to handle RTL scripts (e.g. Arabic), then the marker show at the beginning of the selected RTL script rather than the end (where the mouse/keyboard actually stopped). These cause issues:
- Starting selection inside RTL script (Arabic), and ending selection inside RTL script (Arabic). This show the marker at the start of the selection.
- Starting selection inside LTR script (English), and ending selection inside RTL (Arabic) script. This show the marker at the start of the RTL script selection (rather than the end of it).
Basically, selection starting anywhere (LTR or RTL) and ending in RTL script is incorrect. Any other case is correctly handled (e.g. start with LTR or RTL and end with LTR, even passing by RTL scripts on the way).
The problem is that the direction of flow is flipped for RTL scripts, and therefore backward is forward, and forward is backward. This is why my code cannot handle RTL properly and the backward hack is reversed.
One solution I thought of is to detect the last character of the selection, and see whether it has RTL script or not, then based on this flip the backward flag. I already placed a function to detect whether a text ends with an RTL character (it is in the same jsfiddle unused). It might help you, help me solve it :)
回答1:
See if this is a step in the right direction.
It leverages the following code to Return HTML from a user selection posted by Tim Down:
function getSelectionHtml() {
var html = "";
if (typeof window.getSelection != "undefined") {
var sel = window.getSelection();
if (sel.rangeCount) {
var container = document.createElement("div");
for (var i = 0, len = sel.rangeCount; i < len; ++i) {
container.appendChild(sel.getRangeAt(i).cloneContents());
}
html = container.innerHTML;
}
} else if (typeof document.selection != "undefined") {
if (document.selection.type == "Text") {
html = document.selection.createRange().htmlText;
}
}
return html;
}
Once that is defined, you can call the lastCharTRL
method you defined to check whether the last character was RTL and act accordingly.
if (lastCharRTL(getSelectionHtml()))
$('#pointer').css({top: rects[n].top + 10, left: rects[n].left - 10}).show();
else if(backwards)
$('#pointer').css({top: rects[0].top + 10, left: rects[0].left - 10}).show();
else
$('#pointer').css({top: rects[n].top + 10, left: rects[n].right}).show();
DEMO
来源:https://stackoverflow.com/questions/15277253/detect-selection-end-position-using-javascript