在Javascript中向“内存对象”添加事件侦听器?

时间:2010-11-24 18:46:54

标签: javascript javascript-events listener

问题的一些背景: Reverse Engineering the DOM, Javascript events & "what's going on"?

我正在撰写一些能够在实时搜索中“玩”谷歌网页预览功能的内容。本质上,我想将一个事件监听器添加到

的keyup事件中
  1. 查询页面预览结果(向谷歌发送ajax请求)
  2. 在内存中读取结果
  3. 实时将其添加到您的搜索页面
  4. 这实际上会创建google的实时页面预览搜索结果。

    公平地说,我实际上有95%的人在各种组件中工作,我正处于调整功能的阶段,以使其更加用户友好。如果您对我正在做的事情感兴趣,请随时查看我之前在http://chesser.ca发布的博文,或者查看{{3的'最新版本的代码' (目前非常多,因为我现在有点“功能之间”。

    您浏览器的书签代码位于:

     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部分(性能)我只对查询前两个元素感兴趣。我想这将很容易,唯一阻止我的是我还没有尝试过(而不是所有divs.length,只需将其设置为2)

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

    下一个问题(也是我不确定的问题)是我如何设置事件监听器并修改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);           
     } 
    

    在那里(使用事件监听器)要改变的显而易见的一点是将for(var Obj in google.vs.ha){修复为传入的单个google.vs.rs对象。

    如果你已经持续了这个问题:感谢阅读:) - 亚历克斯

    修改

    根据下面的讨论,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)
                }
            }
        };
    

2 个答案:

答案 0 :(得分:3)

google.vs.ha对象是一个基本的JavaScript对象,具有键/值对属性,并且没有可以说的功能。话虽这么说,这些简单的物体在改变时无法通知你。

我看到它的方式,你基本上有两个选择:

  • 定期检查google.vs.ha以查找您要查找的数据,并跟踪您已抓取图片的数据。这可以通过setInterval();

  • 来完成
  • 确定页面或谷歌中的哪个功能。 namespace负责执行加载数据的工作。一旦确定了数据的加载位置,以及google.vs.ha对象的更新位置,您就可以将原始函数替换为包含事件通知的自己的工具。

例如,如果我有一个如下所示的基本功能:

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),但之后会通知你。

请注意,您的新函数只能访问对象的“公共”属性,而不能访问由闭包捕获的私有元素(例如'closured'var)。我似乎记得谷歌倾向于避免私有变量作为闭包方法,因为这可能会增加内存管理的复杂性,所以这可能不是问题。

更新:我在谷歌搜索结果页面上玩了一下。我进行了全新搜索,但在点击预览之前,我在Chrome控制台中执行了以下操作:

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

google.vs.Ga = newFunc; 

点击预览后似乎触发了它。

答案 1 :(得分:1)

图像是在下载后存储的,对吧?明显。 因此,他们可以改变的唯一时刻是AJAX请求。

因此,每次AJAX请求成功时都必须运行一些检查。 jQuery具有成功的AJAX调用的全局绑定,因此即使没有它也应该是可能的。

现在,当我们知道这一点时 - 检查可能从查看响应对象中可用的某些变量或XMLHTTPRequest对象本身的调用类型开始。这可以缩小你必须更多地调用更新程序的次数。