javascript - 在 Javascript 中将事件监听器添加到 'memory objects'?

标签 javascript listener dom-events

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

我正在写一些东西来“玩”谷歌在实时搜索中的页面预览功能。本质上,我想向将

  1. 查询页面预览结果(向google发送ajax请求)
  2. 在内存中读出结果
  3. 实时将其添加到您的搜索页面

这将实质上创建一个实时页面预览搜索结果将是谷歌。

公平地说,我实际上已经在各种组件中完成了大约 95% 的工作,并且我正处于调整功能以使其更加用户友好的阶段。如果您对我正在做的事情的原因和方法感兴趣,请随时查看我以前的博客文章 http://chesser.ca甚至可以在 http://chesser.ca/gvs.marklet.0.3.js 查看“最新版本的代码” (目前非常有问题,因为我现在有点“介于功能之间”。

您的浏览器的书签代码在这里:

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

最佳答案

google.vs.ha 对象是一个基本的 JavaScript 对象,具有键/值对属性,没有任何功能可言。也就是说,这些简单的对象无法在更改时通知您。

在我看来,您基本上有 2 个选择:

  • 定期检查 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),但之后会通知您。

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

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

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

google.vs.Ga = newFunc; 

而且好像是点击预览后触发的。

关于javascript - 在 Javascript 中将事件监听器添加到 'memory objects'?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4270373/

相关文章:

javascript - React Native - 剪贴板变化的监听器

Javascript 事件处理程序引发 "error: CS1026: ) expected"异常

javascript - 按键名过滤 JSON 数据

Java MouseClick 监听器不工作

使用 Phonegap 全局数组的 Javascript 不起作用

events - AppleScript 可以监听事件吗?

javascript - 无法输入丰富的值 :inplaceInput tag on Chrome version 45. 0.2454.85 m

javascript - 如何判断某个事件是否已调用 "stopImmediatePropagation()"?

Javascript 范围(或其他)问题

javascript - Google Places Autocomplete,如何处理地址中的单元号