Wie finden Auswahl in HTML-Dokument, das iframe enthält oder nur Frames
-
03-07-2019 - |
Frage
Gibt es eine Möglichkeit, den ausgewählten Text in einem HTML-Dokument zu finden, wenn der Text innerhalb eines seiner Frames (oder iframes) sein kann?
Wenn das Dokument keine Frames hat es einfach:
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
So funktioniert dieser Cross-Browser (wenn auch nicht sehr schön).
Das Problem ist, wenn das Dokument Frames oder iFrames enthält. Frames haben ihr eigenes Dokument, also nur den Code oben verwendet, ist nicht genug. Man könnte möglicherweise über den Rahmen Baum durchlaufen und für ausgewählten Text in einem von ihnen suchen, jedoch im allgemeinen Rahmen können Inhalte aus verschiedenen Bereichen hat, so dass selbst wenn ich alle Frames iterieren war und über alle Teilrahmen usw. des Root-Dokuments auf der Suche von ausgewählten Text würde ich nicht die Erlaubnis gehabt haben, ihre HTML zugreifen, nicht wahr? Also ich würde nicht in der Lage sein, ihren ausgewählten Text zu erhalten.
Gibt es eine (einfache) zuverlässige Art und Weise den markierten Text auf einer Webseite selbst zu finden, wenn die Seite enthält Frames?
Danke
Lösung
Um meine eigene Frage zu beantworten, nach einem bisschen mehr Untersuchung: Also, wenn Rahmen unterschiedlicher Domänen sind dann gibt es nichts, was man dagegen tun kann, da Sie keine Berechtigung, den Zugriff auf ihren dom haben. Doch in der gemeinsamen Fall, in dem alle Rahmen sind auf der gleichen Domain (zum Beispiel gmail) nur Iterierte Thema alles wie ein Baum. Hier ist der Code, der erreicht, dass:
Der folgende Code ist ein Bookmarklet, die Zeichen und Wörter des ausgewählten Textes zählt:
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);
})()
Andere Tipps
@Ran Ausgezeichnete Antwort auf Ihre eigene Frage. Wenn jedoch das iframe Dokument dann nicht definiert ist die Funktion fehlschlägt. Ich fügte hinzu, ein bedingtes dafür zu überprüfen, jetzt ist es jede Seite funktioniert auf I einschließlich Gmail ausprobiert habe. if ((!t || t == '') && d)
Nochmals vielen Dank für den großen Code.
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();
}