首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >检测正在加载到DOM中的新映像,jQuery加载事件处理程序不会触发。

检测正在加载到DOM中的新映像,jQuery加载事件处理程序不会触发。
EN

Stack Overflow用户
提问于 2018-05-01 16:54:58
回答 2查看 489关注 0票数 2

我正在开发一个用户脚本,它可以处理各种图像。

问题是,有时图像在初始加载后被添加到页面中,而这些图像不是由我的userscript处理的。

我需要javascript/jQuery中的一些代码,它将在每次将新图像加载到浏览器时自动运行一个函数。

这就是我尝试过的:

代码语言:javascript
复制
$('img').on('load', function() {
    handleImgTag();
});

这不管用。当一个新图像被添加到页面中时(我正在使用chat.stackoverflow.com作为测试,并发送一条新消息,这意味着我的配置文件图片再次添加到页面中,而不是由我的代码处理),该图像没有被处理,也没有发生任何事情。

我试过四处搜索,但我似乎找不到一个方法来做到这一点,也许是因为糟糕的搜索词?

中是否有我可以使用的事件或东西?

编辑:

我不同意上面提到的副本,因为这是关于图像的,并且在Tamper猴子用户脚本中使用。此外,这些副本有5-8年的历史,可能不反映最佳做法或现有技术。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-05-01 21:15:59

$('img').on('load',...无法工作,因为它将匿名事件处理程序发送到所有现有图像上。他们从来没有连接到未来,AJAX的/动态插入的图像。

正确的形式是:$('body').on ('load', 'img', handleImgTag);,除了 事件不会泡汤

因此,您必须使用链接问题中的技术(主要是MutationObserver)或类似于waitForKeyElements()的方法。

而且,您必须动态地附加load事件(对于缓慢加载图像)。

下面的完整工作脚本演示了这个过程。注意,无论是静态加载还是动态加载,waitForKeyElements都会为每个<img>触发一次。:

代码语言:javascript
复制
// ==UserScript==
// @name     _Process select images on or after load
// @match    *://chat.stackoverflow.com/rooms/*
// @match    *://chat.stackexchange.com/rooms/*
// @match    *://chat.meta.stackexchange.com/rooms/*
// @require  https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
// @require  https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant    GM_addStyle
// @grant    GM.getValue
// ==/UserScript==
//- The @grant directives are needed to restore the proper sandbox.

waitForKeyElements ("#chat img", loadHandling);

function loadHandling (jNode) {
    if (jNode[0].complete) {
        handleImgTag (jNode);
    }
    else {
        jNode.on ('load', handleImgTag);
    }
}
function handleImgTag (jNodeOrEvent) {
    var newImg;  //  will be jQuery node
    if (jNodeOrEvent instanceof jQuery) {
        newImg = jNodeOrEvent;
    }
    else {
        newImg = $(jNodeOrEvent.target);
    }
    console.log ("Found new image with width ", newImg.width () );
}

注意:建议调优传递给waitForKeyElements的waitForKeyElements选择器,以尽可能缩小目标图像。

票数 1
EN

Stack Overflow用户

发布于 2018-05-02 01:36:17

在浏览器范围内,globalEventHandler或eventListeners是最好的选择。

但是由于用户脚本对于windowdocument有一些不同的作用域,所以它不能正常工作。这个作用域问题使用web扩展 (下一代用户.)是一样的,但至少它迫使我们处理DOM。

下面是一些用户脚本的解决方案,下面是自己的实验。通常情况下,我的实验会导致无动于衷的程序员的反对,所以不用担心,要玩得开心!

首先,不要加载事件,而是在usercript中加载带有延迟的脚本。它很脏,但是有很大帮助,至少在调试方面是这样。

代码语言:javascript
复制
setTimeout(function(){    }, 3000)

要将事件处理程序加载到主文档中,我们必须创建一个元素并将其附加到主DOM中。

在大多数情况下,出现问题仅仅是因为浏览器加载本地资源的速度要快得多,我们必须指定脚本应该在目标页面上的位置,或者它可能位于DOM的最顶端。(意思是没有事件处理程序,我们不能按他们的名字调用id,我们需要使用getElementById等等)

代码语言:javascript
复制
s = document.createElement("script")
s.innerText = "" // The events scripts
document.body.appendChild(s)

好的一点是,脚本可以是外部的。通过加载外部脚本,浏览器将注意将其附加到DOM中,如果DOM加载得很好的话。在大多数情况下,这些东西开始只对这个动作起作用。

另一种选择是直接在目标DOM的每个元素上设置一个onchange属性。

如果元素已经存在,这是有效的。(如果通过更改src来加载图像)。您可以根据以后的需要设置许多(隐藏)元素,并设置它们的属性。这有点多余,但要避免任何事件侦听器。这是一种平淡的做法。它也可以在服务器端完成。

要在所有图像标记上设置onchange,我们可以在不知道它们的id的情况下使用querySelectorAll,这在本例中非常有用,因为我们可以在其上使用forEach。(与getElementsBytagName不同)

代码语言:javascript
复制
document.querySelectorAll("img").forEach(function(element){
  element.setAttribute("onchange","handleImgTag()")
})

现在大家齐心协力:

代码语言:javascript
复制
setTimeout(function(){
  // the querySelectorAll function encoded in base64
  var all = "ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnaW1nJykuZm9yRWFjaChmdW5jdGlvbihlbGVtZW50KXsNCiAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ29ubG9hZCcsJ2FsZXJ0KCknKQ0KfSk=" 
  s = document.createElement("script")
  // The events scripts, base64 decoded
  s.innerText = atob(all) + "" 
  document.body.appendChild(s)  // End of DOM, at trigger.

}, 1000) // Onloads sets after 1s.
代码语言:javascript
复制
<img src="http://icons.iconarchive.com/icons/martin-berube/flat-animal/64/pony-icon.png"></img>

<img src="" id="more"></img>

<button onclick="more.src='http://icons.iconarchive.com/icons/martin-berube/flat-animal/64/crab-icon.png'">LOAD MORE</button>

范围是良好的用户脚本的关键。

尝试将所有脚本放在DOM末尾。祝好运!

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50120540

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档