我希望能夠將鼠標懸停在網頁上的任何單詞上,並在該單詞上方顯示彈出單詞。這似乎幾乎不可能沒有巨大的性能問題,所以我試圖做雙擊而不是懸停。如何使用範圍包裝所選單詞
隨着雙擊,我可以檢測到單詞的文本,但我無法對頁面中的單詞進行任何操作。基本上,我想用span標籤包裹選定的文本,以便相對於它定位事物。我以前用熒光筆看過它,但我不知道如何。
注意:這隻需要在Firefox中工作。
我希望能夠將鼠標懸停在網頁上的任何單詞上,並在該單詞上方顯示彈出單詞。這似乎幾乎不可能沒有巨大的性能問題,所以我試圖做雙擊而不是懸停。如何使用範圍包裝所選單詞
隨着雙擊,我可以檢測到單詞的文本,但我無法對頁面中的單詞進行任何操作。基本上,我想用span標籤包裹選定的文本,以便相對於它定位事物。我以前用熒光筆看過它,但我不知道如何。
注意:這隻需要在Firefox中工作。
您可以使用這些功能:
var range = window.getSelection().getRangeAt(0);
var newNode = document.createElement("b");
range.surroundContents(newNode);
這與周圍的B標記您的選擇。
mouseover
事件並非不可能。您可以使用在Firefox 20及更高版本中標準化並支持的document.caretPositionFromPoint()
,並返回到WebKit專有的等效版本。
處理鼠標事件時的步驟如下:
document.caretPositionFromPoint()
或等效的光標座標getBoundingClientRect()
得到的範圍內字演示是非常有限的(例如,它不跨越元素的字工作邊界,這個詞的檢測非常粗糙和re有很多優化的空間),但應該足以讓你開始。它適用於當前的瀏覽器,但IE不支持document.caretPositionFromPoint()
。
這裏是關鍵代碼:
function expandToWord(str, offset) {
var start = offset;
while (start >= 1 && /\S/.test(str.charAt(start - 1))) {
--start;
}
var end = offset, len = str.length;
while (end < len && /\S/.test(str.charAt(end))) {
++end;
}
return {
start: start,
end: end,
word: str.slice(start, end)
};
}
var wordDiv = document.createElement("div");
wordDiv.className = "word";
var createRangeFromPoint = (function(doc) {
// Try standards-based method first
if (typeof doc.caretPositionFromPoint != "undefined") {
return function(x, y) {
var pos = doc.caretPositionFromPoint(x, y);
var range = null;
if (pos) {
range = doc.createRange();
range.setStart(pos.offsetNode, pos.offset);
range.collapse(true);
}
return range;
};
}
// Now try WebKit's proprietary method
else if (typeof doc.caretRangeFromPoint != "undefined") {
return function(x, y) {
return doc.caretRangeFromPoint(x, y);
};
}
// Give up
else {
return function() { return null; };
}
})(document);
function mouseEventHandler(e) {
if (wordDiv.parentNode) {
wordDiv.parentNode.removeChild(wordDiv);
}
var range = createRangeFromPoint(e.clientX, e.clientY);
if (range) {
if (range.startContainer.nodeType == 3) {
var wordInfo = expandToWord(range.startContainer.data, range.startOffset);
if (wordInfo.word) {
range.setStart(range.startContainer, wordInfo.start);
range.setEnd(range.startContainer, wordInfo.end);
var rect = range.getBoundingClientRect();
// Get the difference between client and page coordinates from the event
// for positioning the word div
var offsetX = e.clientX - e.pageX;
var offsetY = e.clientY - e.pageY;
wordDiv.style.left = (rect.left + offsetX) + "px";
wordDiv.style.top = (rect.top + offsetY - 20) + "px";
wordDiv.innerHTML = "";
wordDiv.appendChild(document.createTextNode(wordInfo.word));
document.body.appendChild(wordDiv);
}
}
}
}
document.onmousemove = mouseEventHandler;
document.onmouseover = mouseEventHandler;
document.onmouseout = mouseEventHandler;
你能解釋這段代碼嗎?我檢測到了插入位置,但是它如何檢測插入符號下的單詞? – Ian
@Ian:它從插入位置得到的範圍有一個文本節點和節點文本內的偏移量的引用,從中可以使用示例中的expandToWord()函數將其推斷爲單詞。 –
我也許可以幫助,但需要更多的細節。首先,您是否希望將此功能添加到現有網頁,或者是您自己的網頁。這當然會產生很大的差異;)另外,如果你可以發佈一個演示你正在嘗試完成的小提琴(fiddlejs.net),那也可以幫助你做很多事情。乍一看,事件代表團和延遲加載似乎是你的朋友。 –
這是爲現有的網頁(它是一個Firefox插件)。 – Ian