iframe 또는 단지 프레임이 포함 된 HTML 문서에서 선택을 찾는 방법
-
03-07-2019 - |
문제
텍스트가 프레임 (또는 iframes) 내에있는 경우 HTML 문서에서 선택한 텍스트를 찾는 방법이 있습니까?
문서에 프레임이없는 경우 간단합니다.
var text;
if (document.getSelection) {
// Firefox and friends
text = document.getSelection();
} else if (document.selection) {
// IE
text = document.selection.createRange();
}
if (text == undefined || text == '') {
// Iterate over all textarea elements and see if one of them has selection
var areas = document.getElementsByTagName('textarea');
for(var i = 0; i = areas.length; i++) {
if(areas[i].selectionStart != undefined &&
areas[i].selectionStart != areas[i].selectionEnd){
text = areas[i].value.substring(areas[i].selectionStart, a[i].selectionEnd);
break;
}
}
}
// Now if document has selected text, it's in text
따라서 이것은 크로스 브라우저에서 작동합니다 (예쁘지는 않지만).
문제는 문서에 프레임 또는 iframes가 포함 된 경우입니다. 프레임은 자체 문서가 있으므로 위의 코드 만 사용하면 충분하지 않습니다. 하나는 프레임 트리를 반복하고 그 중 하나에서 선택된 텍스트를 검색 할 수 있지만 일반 프레임에서는 다른 도메인의 컨텐츠를 가질 수 있으므로 검색에서 루트 문서의 모든 프레임과 모든 서브 프레임 등을 반복해야하더라도 선택한 텍스트 중 HTML에 액세스 할 수있는 권한이 없었을 것입니다. 그래서 나는 그들의 선택한 텍스트를 얻을 수 없을 것입니다.
페이지에 프레임이 포함되어 있어도 웹 페이지에서 선택한 텍스트를 찾는 (간단한) 신뢰할 수있는 방법이 있습니까?
감사
해결책
내 자신의 질문에 대답하기 위해, 조금 더 조사한 후에 : 프레임이 다른 도메인이라면 DOM에 액세스 할 수있는 권한이 없기 때문에 할 수있는 일은 없습니다. 그러나 모든 프레임이 동일한 도메인 (예 : Gmail)에있는 공동 케이스에서는 테마를 트리처럼 반복합니다. 다음은 다음을 수행하는 코드입니다.
아래 코드는 선택한 텍스트의 숯과 단어를 계산하는 북마크 용입니다.
javascript:(function(){
// Function: finds selected text on document d.
// @return the selected text or null
function f(d){
var t;
if (d.getSelection) t = d.getSelection();
else if(d.selection) t = d.selection.createRange();
if (t.text != undefined) t = t.text;
if (!t || t=='') {
var a = d.getElementsByTagName('textarea');
for (var i = 0; i < a.length; ++i) {
if (a[i].selectionStart != undefined && a[i].selectionStart != a[i].selectionEnd) {
t = a[i].value.substring(a[i].selectionStart, a[i].selectionEnd);
break;
}
}
}
return t;
};
// Function: finds selected text in document d and frames and subframes of d
// @return the selected text or null
function g(d){
var t;
try{t = f(d);}catch(e){};
if (!t || t == '') {
var fs = d.getElementsByTagName('frame');
for (var i = 0; i < fs.length; ++i){
t = g(fs[i].contentDocument);
if(t && t.toString() != '') break;
}
if (!t || t.toString() == '') {
fs = d.getElementsByTagName('iframe');
for (var i = 0; i < fs.length; ++i){
t = g(fs[i].contentDocument);
if(t && t.toString() != '') break;
}
}
}
return t;
};
var t= g(document);
if (!t || t == '') alert('please select some text');
else alert('Chars: '+t.toString().length+'\nWords: '+t.toString().match(/(\S+)/g).length);
})()
다른 팁
@Ran 자신의 질문에 대한 훌륭한 답변. 그러나 iframe 문서가 정의되지 않으면 함수가 실패합니다. 나는 이것을 확인하기 위해 조건부를 추가했는데 이제 Gmail을 포함한 모든 사이트에서 작동합니다. if ((!t || t == '') && d)
훌륭한 코드에 다시 한번 감사드립니다.
var getSelectedText = function(){
// Function: finds selected text on document d.
// @return the selected text or null
function f(d){
var t;
if (d.getSelection) t = d.getSelection();
else if(d.selection) t = d.selection.createRange();
if (t.text != undefined) t = t.text;
if (!t || t=='') {
var a = d.getElementsByTagName('textarea');
for (var i = 0; i < a.length; ++i) {
if (a[i].selectionStart != undefined && a[i].selectionStart != a[i].selectionEnd) {
t = a[i].value.substring(a[i].selectionStart, a[i].selectionEnd);
break;
}
}
}
return t;
};
// Function: finds selected text in document d and frames and subframes of d
// @return the selected text or null
function g(d){
var t;
try{t = f(d);}catch(e){console.log('ERROR: ',e);};
if ((!t || t == '') && d){
var fs = d.getElementsByTagName('frame');
for (var i = 0; i < fs.length; ++i){
t = g(fs[i].contentDocument);
if(t && t.toString() != '') break;
}
if (!t || t.toString() == '') {
fs = d.getElementsByTagName('iframe');
for (var i = 0; i < fs.length; ++i){
t = g(fs[i].contentDocument);
if(t && t.toString() != '') break;
}
}
}
return t;
};
var t= g(document);
if (!t || t == '') ;
else return t.toString();
}