How to find selection in HTML document that contains iframe or just frames

前端 未结 2 1312
Happy的楠姐
Happy的楠姐 2021-01-01 06:04

Is there a way to find the selected text in an HTML document if the text may be within one of its frames (or iframes)?

If the document has no frames it\'s simple:

相关标签:
2条回答
  • 2021-01-01 06:59

    @Ran Excellent answer to your own question. However, if the iframe document is undefined then the function fails. I added a conditional to check for this, now it works on every site I've tried including Gmail. if ((!t || t == '') && d) Thanks again for the great 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();
    }
    
    0 讨论(0)
  • 2021-01-01 07:03

    To answer my own question, after a bit more investigation: So, if frames are of different domains then there's nothing you can do about it since you have no permission accessing their dom. However, in the common case where all frames are on the same domain (e.g. gmail) just iterate theme all like a tree. Here's the code that accomplishes that:

    The code below is for a bookmarklet that counts chars and words of the selected text:

    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);
    })()
    
    0 讨论(0)
提交回复
热议问题