问题
I need to programmatically determine the top-level X window coordinates of the text that is found by using CTRL-f in Firefox. For example, starting with this sequence:
- Open up Firefox on Linux (MS Windows is not involved here).
- Browse to some web page.
- Type CTRL-f to start finding text "foo" that exists in the page.
- Firefox then highlights the text as expected.
- Type Escape key which eliminates the find toolbar at the bottom of the page.
Now, at this point, I want to open up the Scratchpad (Shift-F4), and type some javascript that will dump out to the console the X and Y coordinates of the top left point of the text that is highlighted/selected (again, to clarify, the coordinates need to be the top-level X window coordinates). The coordinates need to be transformed into coordinates relative to the top-level X window (the Firefox window).
I would prefer not to install any Firefox extensions such as Selenium, just use straight javascript. I also do not want to modify the content of the page being loaded and viewed if possible.
The selected text and xy coordinates question seems similar to this. The window.getSelection()
method returns the text string, but I'm looking specifically for the X and Y coordinates of that string as it is on the X window.
EDIT #1: Note that the "window coordinates" given by http://javascript.info/tutorial/coordinates is not the same as the top-level X window coordinates. A viable answer to this question includes the full affine transformation javascript code to transform from Element or Node coordinates to top-level X window coordinates (even if it means intermediate transformations into "window coordinates" as given by http://javascript.info/tutorial/coordinates).
EDIT #2: Possible answer is in the works in https://stackoverflow.com/a/14119731/257924 but I am still confirming it. Confirmed via EDIT #3 below:
EDIT #3: A followup to Tim Downs answer: This is what worked, with a caveat:
var sel = window.getSelection();
var result = "no_selection";
if (sel.rangeCount) {
var range = sel.getRangeAt(0).cloneRange();
if (range.getBoundingClientRect) {
range.collapse(true);
var rect = range.getBoundingClientRect();
if (rect) {
x = rect.left;
y = rect.top;
x += window.mozInnerScreenX;
y += window.mozInnerScreenY;
result = "" + x + " " + y;
}
}
}
result
The caveat is that if the user has scaled the page by pressing CTRL-PLUS or CTRL-MINUS in the page, the x and y values will not be correct (scaling issue). But I found that if scaling is not involved, the x and y values were absolute X root window (under X11 under Linux) coordinates, not relative to the origin of the Firefox X root window, which is what I originally asked for.
I've asked a separate related issue about accessing the scaling factor during debugging.
回答1:
You can do this using the getClientRects()
method of a range obtained from the selection. See https://stackoverflow.com/a/6847328/96100
To transform the coordinates returned by the rectangle returned by getClientRects()
into coordinates relative to the "screen" in Firefox only, you can use window.mozInnerScreenX and window.mozInnerScreenY. Demo below; the results seem plausible in Firefox on Windows.
http://jsfiddle.net/timdown/gaw5W/1/
回答2:
Given that the jsfiddle.net is unresponsive (referenced in Tim's answer), I'm replying with my own solution below that also addresses the issue I described in "EDIT #3" in my question concerning getting the scaling factor.
The following Javascript code demonstrates how to obtain the properly scaled origin coordinate of the selected text. The selected text includes what is selected if you type CTRL-f, type some text that is then selected, and you type Escape.
In order for screenPixelsPerCSSPixel
to be available without
throwing exceptions, the devtools.chrome.enabled
flag in
about:config
should be set to true, and you will have to use the
Scratchpads Environment
menu to select the Browser
configuration
(See Inspecting Firefox Components.interfaces.nsIDOMWindowUtils.screenPixelsPerCSSPixel value in Javascript Scratchpad for details).
To avoid security risks, be sure to turn devtools.chrome.enabled
flag back to false after trying the code below.
After the above configuration changes are applied, type the following text into the Scratchpad, place your cursor after "result" at the very end, and type CTRL-L to see the result.
var contentWindow = window.content;
var sel = contentWindow.getSelection();
var result = "no_selection";
if (sel.rangeCount) {
var range = sel.getRangeAt(0).cloneRange();
if (range.getClientRects) {
range.collapse(true);
var rect = range.getClientRects()[0];
if (rect) {
x = rect.left;
y = rect.top;
x += contentWindow.mozInnerScreenX;
y += contentWindow.mozInnerScreenY;
var util = contentWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindowUtils);
x *= util.screenPixelsPerCSSPixel;
y *= util.screenPixelsPerCSSPixel;
result = "" + x + " " + y;
}
}
}
result
I verified that the above handles scaling properly in the
content window such that the resulting coordinate values embedded in
the result
string correspond to the absolute X root window
coordinates. I have not tested the above on MS Windows.
来源:https://stackoverflow.com/questions/14117682/finding-top-level-x-window-x-y-coordinates-of-ctrl-f-text-in-firefox