当用户选择不同来源的iframe中的文本时,由于跨源安全策略,在包含文档中运行的javascript调用window.getSelection()会返回None选择对象。
因此,以编程方式,我无法区分回到None选择对象,因为用户没有选择整个文档中的任何内容,而不是因为用户选择了不同来源的内容而返回None iframe,但它对我的代码没有限制。
我希望能够区分这些案例,以便向用户显示不同的错误消息。这可能吗?
var sel = window.getSelection();
if ( sel && sel.type == 'None' ) {
// Did the user not select anything in the entire document?
// Or did the user select something in a different origin
// iframe that I can't see?
// If I could tell the difference between these two cases,
// I could show my user a much better error message
alert('sel type = None, dunno what it means exactly, kthxbai');
}
完整的演示代码在此处:http://jsfiddle.net/t3bd6zy4/2/
注意:这需要与任意网站一起使用,因此更改原始策略或使用postMessage()执行某些操作对我来说不是一种可行的方法。此外,此代码仅在最近的Chrome浏览器中运行。
更新:我解决了这个问题,尽管只能在Chrome扩展程序中使用。
虽然我无法在不改变原始政策的情况下从DOM获取来自DOM的不同来源的选择文本,但Chrome API将允许您获取所选文本,即使它确实来自不同来源的iframe。 (如果您想了解更多信息,请参阅contextMenus API的示例:https://developer.chrome.com/extensions/contextMenus。)
使用此方法意味着我不需要为空选择显示特定于iframe的消息。我的用户错误消息较少:非常棒。
答案 0 :(得分:1)
这有效(jsfiddle):
var iframeClicked = false;
document.body.addEventListener('mouseup', iframe(false));
function iframe(bool) {
return function(e) {
iframeClicked = bool;
//console.log(iframeClicked);
}
}
focus();
var listener = addEventListener('blur', function() {
if(document.activeElement === document.getElementsByTagName('iframe')[0]) {
iframe(true)();
}
removeEventListener(listener);
});
document.getElementById('selbutton').addEventListener('mousedown', function() {
var sel = window.getSelection();
if (!iframeClicked) {
console.log("selection type of " + sel.type + " value is :" + sel + ":" );
} else {
console.log("did not get a selection object back from getSelection");
}
});
可以找到检查iframe
是否被点击的解决方案in this answer。我们要查找的是查看iframe
是否是最后被点击的内容(因为如您所知,如果您选择了某些内容,您单击的下一个内容将取消选择该选择...所以如果{ {1}}是最后点击的内容,我们点击“获取选择”按钮,然后我们就会知道我们尝试在iframe
内选择一些内容。)这令人困惑。
无论如何,iframe
表示之前点击用户点击的“获取选择”按钮之前的最后一件事确实是iframeClicked === true
。否则,它就在外面 iframe
。