Domanda

Esiste un modo per trovare il testo selezionato in un documento HTML se il testo può trovarsi all'interno di uno dei suoi frame (o iframe)?

Se il documento non ha frame è semplice:

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

Quindi funziona su più browser (anche se non molto carino).

Il problema è quando il documento contiene frame o iframe. I frame hanno il loro documento, quindi usare il codice sopra non è sufficiente. Si potrebbe potenzialmente iterare sull'albero dei frame e cercare il testo selezionato in uno di essi, tuttavia in generale i frame possono avere contenuti di domini diversi, quindi anche se dovessi iterare su tutti i frame e su tutti i sottoframe ecc del documento radice nella ricerca del testo selezionato non avrei avuto il permesso di accedere al loro HTML, giusto? Quindi non sarei in grado di ottenere il testo selezionato.

Esiste un modo (semplice) affidabile per trovare il testo selezionato su una pagina Web anche se la pagina contiene cornici?

Grazie

È stato utile?

Soluzione

Per rispondere alla mia domanda, dopo un po 'più di indagine: Quindi, se i frame sono di domini diversi, non c'è nulla che tu possa fare al riguardo poiché non hai i permessi per accedere alla loro dom. Tuttavia, nel caso comune in cui tutti i frame si trovano sullo stesso dominio (ad esempio gmail), iterare il tema come un albero. Ecco il codice che lo compie:

Il codice seguente è per un bookmarklet che conta caratteri e parole del testo selezionato:

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);
})()

Altri suggerimenti

@Ran Ottima risposta alla tua domanda. Tuttavia, se il documento iframe non è definito, la funzione ha esito negativo. Ho aggiunto un condizionale per verificarlo, ora funziona su tutti i siti che ho provato incluso Gmail. if ((! t || t == '') & amp; & amp; d) Grazie ancora per l'ottimo codice.

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();
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top