如何根据光标点击定位弹出窗口(不使用 jQuery)?
How to position a popup based on the cursor click (without using jQuery)?
我正在尝试创建一个 Firefox 扩展,我希望在双击某些文本的旁边出现一个弹出窗口。由于我将此代码作为我的扩展程序的内容脚本放置在任何网站上,因此我尝试不使用 jQuery 来完成此任务。
我已经看到并实施了链接中给出的答案:
How to position popover over a highlighted portion of text?
How to position a popup div based on the position of where the cursor clicks
不幸的是,大多数答案都在 jQuery 中。我尝试将它们替换为纯 DOM 实现,并提出了以下代码:
function doSomethingWithSelectedText(obj) {
var textObj = getSelectedTextObj();
if (textObj.toString() && textObj.toString().trim().split(" ").length <= 2) {
var NewPara = document.createElement("div");
NewPara.setAttribute("id", "infoDiv");
NewPara.setAttribute("class", "tooltipDiv");
NewPara.appendChild(document.createTextNode(textObj.toString().trim()));
if (document.getElementsByClassName("tooltipDiv").length) {
var OldPara = document.getElementById("infoDiv");
document.body.replaceChild(NewPara, OldPara);
}
else {
document.body.appendChild(NewPara);
}
document.getElementById("infoDiv").style.display = "block";
document.getElementById("infoDiv").style.width = "250px";
document.getElementById("infoDiv").style.zIndex = "101";
document.getElementById("infoDiv").style.backgroundColor = "#F5DEB3";
document.getElementById("infoDiv").style.border = "3px solid #666";
document.getElementById("infoDiv").style.padding = "12px 12px 12px 12px";
document.getElementById("infoDiv").style.borderRadius = "0px 0px 25px 0px";
document.getElementById("infoDiv").style.position = "absolute";
var oRect = textObj.getRangeAt(0).getBoundingClientRect();
var leftOffset, topOffset;
var pageWidth, pageHeight;
var w = window, d = document, e = d.documentElement, g = d.getElementsByTagName('body')[0],
pageWidth = w.innerWidth || e.clientWidth || g.clientWidth,
pageHeight = w.innerHeight|| e.clientHeight|| g.clientHeight;
leftOffset = oRect.left + oRect.width + 1 + 12;
if (300 + leftOffset > pageWidth - 12) {
leftOffset = pageWidth - 350 - 12;
}
topOffset = oRect.top;
if (topOffset + 12 > pageHeight) {
topOffset -= 12;
}
leftOffset += window.scrollX;
topOffset += window.scrollY;
document.getElementById("infoDiv").style.left = leftOffset;
document.getElementById("infoDiv").style.top = topOffset;
}
else {
document.getElementById("infoDiv").style.display = "none";
};
};
上述代码的问题是弹出窗口没有显示在双击的文本旁边,而是有时出现在屏幕下方,有时出现在屏幕上方。我试过将 div 定位在不同的地方,并将 clientX
、clientY
替换为 pageX
、pageY
,但似乎没有任何效果。我坚信问题出在节点 NewPara
及其位置上,但我无法确定它。
更新:修改了代码,但最初的问题仍然存在。
有两个主要问题将修复弹出窗口的显示位置。
首先是 document.body
应该替换为 document.documentElement
以便将范围放在 body
标签之外并进入 html
标签。
下一个主要问题是 leftOffset
和 topOffset
。它们都不会转换为 px
,因此它们永远不会被浏览器呈现。
为防止出现这种情况,请使用 String(leftOffset) + "px"
和 String(topOffset) + "px"
。
修改后的代码如下:
function doSomethingWithSelectedText(obj) {
var textObj = getSelectedTextObj();
if (textObj.toString() && textObj.toString().trim().split(" ").length <= 2) {
var NewPara = document.createElement("div");
NewPara.setAttribute("id", "infoDiv");
NewPara.setAttribute("class", "tooltipDiv");
NewPara.appendChild(document.createTextNode(textObj.toString().trim()));
if (document.getElementsByClassName("tooltipDiv").length) {
var OldPara = document.getElementById("infoDiv");
document.documentElement.replaceChild(NewPara, OldPara);
}
else {
document.documentElement.appendChild(NewPara);
}
var oRect = textObj.getRangeAt(0).getBoundingClientRect();
var leftOffset, topOffset;
var pageWidth, pageHeight;
var w = window, d = document, e = d.documentElement, g = d.getElementsByTagName('body')[0],
pageWidth = w.innerWidth || e.clientWidth || g.clientWidth,
pageHeight = w.innerHeight|| e.clientHeight|| g.clientHeight;
leftOffset = oRect.left + oRect.width + 1 + 12;
if (300 + leftOffset > pageWidth - 12) {
leftOffset = pageWidth - 350 - 12;
}
topOffset = oRect.top;
if (topOffset + 12 > pageHeight) {
topOffset -= 12;
}
leftOffset += window.scrollX;
topOffset += window.scrollY;
document.getElementById("infoDiv").style.display = "block";
document.getElementById("infoDiv").style.width = "250px";
document.getElementById("infoDiv").style.zIndex = "101";
document.getElementById("infoDiv").style.backgroundColor = "#F5DEB3";
document.getElementById("infoDiv").style.border = "3px solid #666";
document.getElementById("infoDiv").style.padding = "12px 12px 12px 12px";
document.getElementById("infoDiv").style.borderRadius = "0px 0px 25px 0px";
document.getElementById("infoDiv").style.position = "absolute";
document.getElementById("infoDiv").style.left = String(leftOffset) + "px";
document.getElementById("infoDiv").style.top = String(topOffset) + "px";
}
else {
document.getElementById("infoDiv").style.display = "none";
};
};
这解决了位置问题。
我正在尝试创建一个 Firefox 扩展,我希望在双击某些文本的旁边出现一个弹出窗口。由于我将此代码作为我的扩展程序的内容脚本放置在任何网站上,因此我尝试不使用 jQuery 来完成此任务。
我已经看到并实施了链接中给出的答案:
How to position popover over a highlighted portion of text?
How to position a popup div based on the position of where the cursor clicks
不幸的是,大多数答案都在 jQuery 中。我尝试将它们替换为纯 DOM 实现,并提出了以下代码:
function doSomethingWithSelectedText(obj) {
var textObj = getSelectedTextObj();
if (textObj.toString() && textObj.toString().trim().split(" ").length <= 2) {
var NewPara = document.createElement("div");
NewPara.setAttribute("id", "infoDiv");
NewPara.setAttribute("class", "tooltipDiv");
NewPara.appendChild(document.createTextNode(textObj.toString().trim()));
if (document.getElementsByClassName("tooltipDiv").length) {
var OldPara = document.getElementById("infoDiv");
document.body.replaceChild(NewPara, OldPara);
}
else {
document.body.appendChild(NewPara);
}
document.getElementById("infoDiv").style.display = "block";
document.getElementById("infoDiv").style.width = "250px";
document.getElementById("infoDiv").style.zIndex = "101";
document.getElementById("infoDiv").style.backgroundColor = "#F5DEB3";
document.getElementById("infoDiv").style.border = "3px solid #666";
document.getElementById("infoDiv").style.padding = "12px 12px 12px 12px";
document.getElementById("infoDiv").style.borderRadius = "0px 0px 25px 0px";
document.getElementById("infoDiv").style.position = "absolute";
var oRect = textObj.getRangeAt(0).getBoundingClientRect();
var leftOffset, topOffset;
var pageWidth, pageHeight;
var w = window, d = document, e = d.documentElement, g = d.getElementsByTagName('body')[0],
pageWidth = w.innerWidth || e.clientWidth || g.clientWidth,
pageHeight = w.innerHeight|| e.clientHeight|| g.clientHeight;
leftOffset = oRect.left + oRect.width + 1 + 12;
if (300 + leftOffset > pageWidth - 12) {
leftOffset = pageWidth - 350 - 12;
}
topOffset = oRect.top;
if (topOffset + 12 > pageHeight) {
topOffset -= 12;
}
leftOffset += window.scrollX;
topOffset += window.scrollY;
document.getElementById("infoDiv").style.left = leftOffset;
document.getElementById("infoDiv").style.top = topOffset;
}
else {
document.getElementById("infoDiv").style.display = "none";
};
};
上述代码的问题是弹出窗口没有显示在双击的文本旁边,而是有时出现在屏幕下方,有时出现在屏幕上方。我试过将 div 定位在不同的地方,并将 clientX
、clientY
替换为 pageX
、pageY
,但似乎没有任何效果。我坚信问题出在节点 NewPara
及其位置上,但我无法确定它。
更新:修改了代码,但最初的问题仍然存在。
有两个主要问题将修复弹出窗口的显示位置。
首先是 document.body
应该替换为 document.documentElement
以便将范围放在 body
标签之外并进入 html
标签。
下一个主要问题是 leftOffset
和 topOffset
。它们都不会转换为 px
,因此它们永远不会被浏览器呈现。
为防止出现这种情况,请使用 String(leftOffset) + "px"
和 String(topOffset) + "px"
。
修改后的代码如下:
function doSomethingWithSelectedText(obj) {
var textObj = getSelectedTextObj();
if (textObj.toString() && textObj.toString().trim().split(" ").length <= 2) {
var NewPara = document.createElement("div");
NewPara.setAttribute("id", "infoDiv");
NewPara.setAttribute("class", "tooltipDiv");
NewPara.appendChild(document.createTextNode(textObj.toString().trim()));
if (document.getElementsByClassName("tooltipDiv").length) {
var OldPara = document.getElementById("infoDiv");
document.documentElement.replaceChild(NewPara, OldPara);
}
else {
document.documentElement.appendChild(NewPara);
}
var oRect = textObj.getRangeAt(0).getBoundingClientRect();
var leftOffset, topOffset;
var pageWidth, pageHeight;
var w = window, d = document, e = d.documentElement, g = d.getElementsByTagName('body')[0],
pageWidth = w.innerWidth || e.clientWidth || g.clientWidth,
pageHeight = w.innerHeight|| e.clientHeight|| g.clientHeight;
leftOffset = oRect.left + oRect.width + 1 + 12;
if (300 + leftOffset > pageWidth - 12) {
leftOffset = pageWidth - 350 - 12;
}
topOffset = oRect.top;
if (topOffset + 12 > pageHeight) {
topOffset -= 12;
}
leftOffset += window.scrollX;
topOffset += window.scrollY;
document.getElementById("infoDiv").style.display = "block";
document.getElementById("infoDiv").style.width = "250px";
document.getElementById("infoDiv").style.zIndex = "101";
document.getElementById("infoDiv").style.backgroundColor = "#F5DEB3";
document.getElementById("infoDiv").style.border = "3px solid #666";
document.getElementById("infoDiv").style.padding = "12px 12px 12px 12px";
document.getElementById("infoDiv").style.borderRadius = "0px 0px 25px 0px";
document.getElementById("infoDiv").style.position = "absolute";
document.getElementById("infoDiv").style.left = String(leftOffset) + "px";
document.getElementById("infoDiv").style.top = String(topOffset) + "px";
}
else {
document.getElementById("infoDiv").style.display = "none";
};
};
这解决了位置问题。