选择对象和跨源iframe?

时间:2015-06-20 18:01:24

标签: javascript iframe

当用户选择不同来源的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的消息。我的用户错误消息较少:非常棒。

1 个答案:

答案 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