2010-11-24 8 views
1

いくつかの背景: Reverse Engineering the DOM, Javascript events & "what's going on"?Javascriptの 'メモリオブジェクト'にイベントリスナーを追加しますか?問題へ

私は何かを書いているライブ検索にGoogleのページのプレビューの機能を持つ「遊び」でしょう。基本的に、私はメモリ

  • になり

    1. 問い合わせページプレビューの結果(GoogleにAJAXリクエストを送信)
    2. 読み出しに追加されますからkeyupイベントにイベントリスナを追加したいですあなたの検索ページをリアルタイムで

    これは本質的にはgoogleのライブページプレビューの検索結果を作成します。

    これは、実際には約95%がさまざまなコンポーネントで動作しています。私は、機能を調整してユーザーフレンドリーにする段階にあります。私がやっていることのうわさに興味があるなら、私の前のブログ記事をhttp://chesser.caでチェックしてみてください。あるいは、最新バージョンのコードをhttp://chesser.ca/gvs.marklet.0.3.jsで見ることもできます(現在、私はとてもバギーです。 。「、現時点では 『機能間の』ビットをm個

    ブラウザのブックマークレットのコードはここにある:

    javascript:(function{var head= document.getElementsByTagName('head')[0];var script= document.createElement('script');script.type= 'text/javascript';script.src= 'http://chesser.ca/gvs.marklet.0.3.js';head.appendChild(script);};)(); 
    

    (からkeyupイベントリスナーが現在、その中で動作させるために、本質的に、オフに設定されています現在の状態では、ライブプレビューでページを検索し、ブックマークレットを1回クリックして(クエリを開始するため)、2〜2回待ってからもう一度クリックしてください(ページプレビューを表示するには) は、だから私はこれにいくつかの変更を行うために持っている:

    私は最初の2つの要素を問い合わせることに興味が(パフォーマンスのための)第1部では。 I次の問題(と1

    function query_current_pages(){ 
        var all_divs = document.getElementsByTagName('div'); 
        for (i=0;i < all_divs.length; i++) { 
         if (all_divs[i].className == 'vsc') { 
          google.vs.ea(all_divs[i]); 
         } 
        } 
    } 
    

    ことが簡単になり、私を停止する唯一の事は、私は(ちょうど2に設定し、代わりにすべてのdivs.lengthの)まだ試していないということです想像私は確信していません)は、イベントリスナーを設定し、add_previews関数を変更して、リクエストが戻ったときにプレビューが追加されるようにする方法です。 google.vs.haというメモリ空間ではなく、データが存在するのを待ち受けて行動に移るようなものを作りたいと思っています。

    理由私はこれが本当にうまくいくと思うからです。それと私はそれをやりながらコーディングについての「山」を学んだ。

    ページのプレビューが「ページ上でチャックされる」方法に興味がある人には、メモリ内のすべてのイメージをループして配置する機能があります。

    function add_previews(){ 
        c=document.getElementById('ires'); 
        nli=document.createElement('div'); 
        cell = 0; 
        for(var Obj in google.vs.ha){ 
         na=document.createElement('a'); 
         na.href=Obj; 
    
         nd=document.createElement('div'); 
         cldiv=document.createElement('div'); 
         cldiv.style.clear = 'both'; 
    
         nd.style.width=google.vs.ha[Obj].data.dim[0]+'px'; 
         nd.style.height=google.vs.ha[Obj].data.dim[1]+'px'; 
         nd.style.margin = '5px'; 
         nd.style.padding = '5px'; 
         nd.style.cssFloat = 'left'; 
         nd.style.border = '1px solid #999999'; 
    
         if (google.vs.ha[Obj].data.tbts.length) { 
          nilDiv = document.createElement('div'); 
          for(i = 0; i < google.vs.ha[Obj].data.tbts.length; i++){ 
           box = google.vs.ha[Obj].data.tbts[i].box; 
           newbox = document.createElement('div'); 
           newbox.className = 'vsb vsbb'; 
           newbox.style.position = 'relative'; 
           newbox.style.top = (box.t)+'px'; 
           newbox.style.left = box.l+'px'; 
           newbox.style.height = box.h+'px'; 
           newbox.style.width = box.w+'px'; 
           nilDiv.appendChild(newbox); 
           newtext = document.createElement('div'); 
           newtext.className = 'vsb vstb'; 
           newtext.innerHTML = google.vs.ha[Obj].data.tbts[i].txt; 
           newtext.style.top = (box.t)+'px'; 
           newtext.style.position = 'relative'; 
           nilDiv.appendChild(newtext); 
          } 
          nilDiv.style.height = '0px'; 
          nd.appendChild(nilDiv); 
         } 
    
         for(i = 0; i < google.vs.ha[Obj].data.ssegs.length; i++){ 
          ni=document.createElement('img'); 
          ni.src += google.vs.ha[Obj].data.ssegs[i]; 
          ni.className+=' vsi'; 
          na.appendChild(ni); 
         } 
         nd.appendChild(na); 
         nli.appendChild(nd); 
        }; 
        c.insertBefore(nli,c.firstChild);   
    } 
    

    (イベントリスナーで)そこに変更する明白なビットが渡される単一google.vs.rs対象となるfor(var Obj in google.vs.ha){を固定することです。アレックス

    EDIT

    以下の議論を1として、google.vs.Gaが担当のようです - 読書:) に感謝:あなたがこれまで疑問にこれを続いた場合

    (回答が関数を上書きしている)データを照会する

    ここでは情報を提供するために、ここでは.Gaコードを使用します。

    google.vs.Ga = function (a, b, c) { 
         var d = google.vs.b.kfe.kfeHost, 
          g = google.vs.Ya(a), 
          i = a.getAttribute("sig"); 
         if (i) { 
          var f = google.vs.qa(a); 
          if (f) { 
           d = [d ? "http://" + d : "", google.vs.b.kfe.kfeUrlPrefix, "&d=", encodeURIComponent(f), "&b=1", "&jsonp=google.vs.r"]; 
           d.push("&a="); 
           d.push(encodeURIComponent(i)); 
           if (i = a.getAttribute("blobref")) { 
            d.push("&bl="); 
            d.push(i) 
           } 
           d.push("&rs="); 
           i = 0; 
           for (var j; j = g[i++];) { 
            d.push(encodeURIComponent(j)); 
            i < g.length && d.push("&rs=") 
           } 
           g = google.vs.m(a) || { 
            ub: a 
           }; 
           g.G = c; 
           google.vs.ha[f] = g; 
           c = d.join(""); 
           c = new google.vs.Ia(f, c, function() { 
            google.vs.P(a, h); 
            o(google.vs.k, f) 
           }); 
           b ? p(google.vs.k, c) : q(google.vs.k, c) 
          } 
         } 
        }; 
    
  • +0

    私はちょっと混乱しています。データが更新されたときにイベントが呼び出す機能は何ですか? – Matt

    +1

    プレビュー画像がいつ利用可能かを判断し、探しているイベントをトリガーしていますか? – Matt

    +0

    @matt - yes - 画像がいつ利用可能かを把握し、その時点でトリガーしようとしています。 –

    答えて

    3

    google.vs.haオブジェクトは、基本的なJavaScriptオブジェクトであり、キーと値のペア属性を持ち、話す機能はありません。つまり、これらの単純なオブジェクトは、変更されたときに通知することができません。

    • 定期すでにつかんできたものを追跡すること、あなたが探しているデータのためにgoogle.vs.haチェック:

      私はそれを見るように、あなたは基本的に2つのオプションを持っています画像。これはsetInterval()で行うことができます。

    • ページまたはGoogleの機能を特定します。ネームスペースは、データをロードする作業を行います。データがロードされる場所と、正確にgoogle.vs.haオブジェクトが更新される場所を判断したら、元の関数をイベント通知を含む独自のクラフトの1つに置き換えることができます。例えば

    私はこのようになります基本的な機能がある場合は、上記のコードで

    var Example = function(value){ 
        var closured = ' world'; 
        this.value = value; 
        this.doSomething = function(){ alert(this.value + closured); }; 
    }; 
    
    var test = new Example('hello'); 
    test.doSomething(); // will only alert 'hello world'; 
    
    var oldFunc = test.doSomething; 
    var notifyMe = function(){ alert('notified'); }; // callback function 
    
    // Update previous method to do it's normal thing, but then notify after 
    test.doSomething = function(){ 
        oldFunc.apply(this, arguments); 
        notifyMe(); 
    }; 
    
    test.doSomething(); // will alert 'hello world', and then 'notified' 
    

    を、我々は効果的に私たち自身のものと古いdoSomethingの機能を交換しました。この新しいバージョンは以前の職務(oldFunc.apply経由)を引き続き実行しますが、後で通知します。

    新しい関数はオブジェクトのpublicプロパティにのみアクセスでき、クロージャによってキャプチャされるプライベート要素( 'closured' varなど)にはアクセスできないことに注意してください。私は、閉鎖アプローチのようにGoogleがプライベート変数を避けようとしているのは、メモリ管理に複雑になる可能性があるため、どこか覚えているようだ。

    更新:私はGoogle検索結果ページでそれをちょっと遊んだ。私は新鮮な検索を実行したが、プレビューをクリックする前に、私は次のクロームコンソールで実行:

    var old = google.vs.Ga; 
    var newFunc = function(){ 
        old.apply(this, arguments); 
        console.log(arguments); 
    }; 
    
    google.vs.Ga = newFunc; 
    

    そしてプレビューをクリックした後にトリガされるように見えました。

    +1

    Googleの関数をオーバーライドするのは良い考えですが、現在の実装を変更しないままにしておくこともできます。それは私が推測する新鮮なものです。それでも、あなたがここに置くアップデートはそれを行う本当にクリーンな方法です。私の+1。 – naugtur

    +0

    はい - google.vs.eaはgoogle.vs.Gaを呼び出します.Javascriptを使用して既存のGaをコピーし、その後に独自のコード行を追加することができます。 IIRC .gaは結果セットを返すものではありませんが、近いです。私が関数を上書きする方法を知っていれば、私は正しいものを見つけることができると確信しています。私はあなたに知らせるでしょう:) –

    +1

    @naugtur trueですが、ページ上のデータを操作するためにJavaScriptを構築しているときは、それらが実装を変更するかどうかは常に依存します。いくつかのものは他のものよりも壊れやすいかもしれませんが、結局はあなたは仕事を終わらせるために前提を作らなければなりません。 – Matt

    1

    画像はダウンロードされてから保存されます。明らかです。 変更できる唯一の瞬間は、AJAXリクエストです。

    したがって、AJAXリクエストが成功するたびにチェックを行う必要があります。 jQueryはAJAX呼び出しを成功させるためのグローバルなバインディングを持っているので、それがなくても可能です。

    これを知ると、応答オブジェクトで使用可能ないくつかの変数や、XMLHTTPRequestオブジェクト自体が呼び出しのタイプであるかどうかを調べることから開始される可能性があります。これは、あなたのアップデータをさらに呼び出さなければならない回数を絞り込むことができます。

    +0

    興味深いことに - 彼らはデータURIとして来る。 'google.vs.ea(div [@ class = vsc]);'関数はデータをメモリにロードするajaxリクエストを呼び出します。視覚的な検索のブログでは、ブラウザがこのデータをどこかに集めていると言われましたが、毎回ajaxリクエストが発生するようです。以下のマットによると、私の行動の過程は、Googleの機能の1つを私自身のもので上書きすることかもしれないように見える。 –

    +1

    "データをメモリにロードするajaxリクエストを呼び出します" - なぜそれにフックしないのですか? – naugtur

    関連する問題