textRange IE11的moveToPoint()方法有问题;
如果指向节点不在第一个屏幕中,它似乎不起作用;
document.addEventListener( "click", function(e) {
var x = e.clientX;
var y = e.clientY;
var range = document.body.createTextRange();
range.moveToPoint(x, y);
range.expand('word');
console.log(range);
console.log(range.text);
});
此代码从点击点获取单词,但只有在我们点击第一次滚动的节点时才会正常。
如果我们向下滚动到第一次滚动中没有的节点,我们将捕获该异常。
有人知道如何正确处理这种情况吗?
答案 0 :(得分:1)
您认为您的同事不使用stackoverflow,不是吗?在你处于试用期之前,发表检查问题并不是一个好的业力。我建议将这些信息提供给您的团队,并且您将产生一些不愉快的后果。
答案 1 :(得分:0)
您可以使用offsetX,offsetY属性。 或者,您可以使用父元素的scrollLeft和scrollTop属性将滚动位置添加到x和y变量。
答案 2 :(得分:0)
我可以确认IE11中存在这样的错误。您可以在评论中找到详细信息:http://generatedcontent.org/post/69213745095/ie11review-part1
可能的解决方案(创建范围后):
range.moveToElementText(e.target);
range.collapse(true)
range.expand("word")
现在您已选择第一个单词。您现在必须使用TextRange属性boundingHeight,boundingWidth,boundingLeft和boundingTop检查所选单词是否适合您的鼠标单击位置。如果没有,则将循环移动到下一个单词:
range.collapse(false);
range.expand("word");
答案 3 :(得分:0)
嗯,受到@dinalt和@JAYBEkster的启发,我提出了这个解决方案。也许有人会需要这个。
下面的代码(对于IE,没有检查所有版本,但它可以正常工作11+)在复杂的嵌套html中抓取单词。
逐步说明它是如何运作的:
我们为什么要做第4步和第5步?因为我们发现一些文本在该节点中结束,但它可能不是结尾或开头的,因为一些造型的原因,我的bein它自己的节点和target.node我只是中间部分的一部分。这个单词。因此,我们必须跳过节点并找到单词的结尾。
如果你确定你的HTML没有抱怨你可以跳过所有其他步骤。
是的,因为对于这样的事情,它看起来真的很像我们认为简单的任务。 但我实际上找不到更好的解决方案,有几种选择,所有这些选择并不像我需要的那样普遍。
这段代码的好处是它根本不关心html的复杂性。
我会在这里发布我的github repositiry的链接,你可以找到wordGraber的完整代码,当然这将适用于Chrome,Safari,FF和IE。
https://github.com/6graNik/wordGrabber
以下只是IE的一部分。
function getWordFromEventIE(e) {
const x = e.clientX;
const y = e.clientY;
const innerText = e.target && e.target.innerText;
const separators = /([\s&^:;,!?(){}])+/;
const IErange = global.document.body.createTextRange();
try {
IErange.moveToElementText(e.target);
IErange.collapse(true);
let wholeSentenceLength = 0;
const reqIEcharTest = () => {
do {
IErange.expand("character");
wholeSentenceLength += 1;
}
while (!separators.test(IErange.text.slice(-1)) && wholeSentenceLength <= innerText.length);
const {boundingLeft, boundingTop, boundingWidth, boundingHeight, text} = IErange;
if (boundingLeft <= x && x <= (boundingLeft + boundingWidth)
&& boundingTop <= y && y <= (boundingTop + boundingHeight)) {
if (wholeSentenceLength <= innerText.length && !separators.test(text.slice(-1)) ) {
return text;
}
return text.substr(0, text.length - 1);
}
IErange.collapse(false);
return reqIEcharTest();
};
const text = reqIEcharTest().trim();
const innerTextArr = innerText.split(text);
const innerTextLeft = innerTextArr[0].split(separators);
const innerTextRight = innerTextArr[1].split(separators);
let leftPart;
if (innerTextLeft <= 1) {
leftPart = recursionWordGet(e.target, 'left') + innerTextLeft.slice(-1)[0];
} else {
leftPart = innerTextLeft.slice(-1)[0];
}
let rightPart;
if (innerTextRight <= 1) {
rightPart = innerTextRight[0] + recursionWordGet(e.target, 'right');
} else {
rightPart = innerTextRight[0];
}
return leftPart + text + rightPart;
} catch (err) {
console.log('>>>>>>>>>>>>>>>>>> text', err);
}
}
function recursionWordGet(target, option) {
const separators = /([\s&^:;,!?(){}])+/;
const uniqString = Date.now();
target.setAttribute("data-target", uniqString);
const {parentNode} = target;
const copyNode = parentNode.cloneNode(true);
copyNode.querySelector(`[data-target="${uniqString}"]`).innerText = uniqString;
const tagName = copyNode.tagName;
const text = copyNode.innerText;
const textArr = text.split(uniqString);
const textLeftPartArr = textArr[0].split(separators);
const textRightPartArr = textArr[1].split(separators);
if (option === 'right') {
let returnText;
if (textRightPartArr.length <= 1 && tagName === 'span') {
returnText = textRightPartArr[0] + recursionWordGet(parentNode, 'right');
} else {
returnText = textRightPartArr[0];
}
return returnText;
}
if (option === 'left') {
let returnText;
if (textLeftPartArr <= 1 && tagName === 'span') {
returnText = recursionWordGet(parentNode, 'left') + textLeftPartArr.slice(-1)[0];
} else {
returnText = textLeftPartArr.slice(-1)[0];
}
return returnText;
}
return '';
}