@无名啊,这不现实,我想你也看到了,在我的代码开始执行时,图片请求实际上已经发出了。如果我的代码晚于其他代码加载,浏览器就有更多机会下完整个图片。要想实现最好的效果,我的代码应该放在加载顺序的最开头,而这与
viewer.js
的要求显然是矛盾的。为了方便用户导入,我的代码不可能同时在插件列表的开头和结尾。
@老虎会游泳,开始各种卷了
不如从根头解决,只依赖用户设定的顺序?
@老虎会游泳,现在你加
setTimeout
解决了,再后来的脚本想在你之后执行,该咋办呢
@无名啊,只要添加
setTimeout
,就可以在我的$(document).ready()
先执行的情况下,让我的绑定后执行。$(document).ready(() => { // 加这个延时,就可以保证晚于任何其他插件执行,以解决和viewer.js的冲突 setTimeout(() => { document.querySelectorAll('.userimg').forEach(x => { // 替换掉虎绿林的点击查看大图事件 x._onclick = x.onclick; x.onclick = function () { this.src = this._url; // 再次点击就触发虎绿林的点击查看大图事件 x.onclick = x._onclick; // 恢复被抑制的图片外层链接 if (x.parentNode._href) { // 为了防止外层链接被立即触发,所以加个延时 setTimeout(() => x.parentNode.href = x.parentNode._href); } }; }); }); });
@老虎会游泳,感觉可以和
viewer
作者协调下,去掉$(document).ready()
你也说多个
$(document).ready()
执行顺序不定,不利于后面脚本按顺序执行
@无名啊,我的更新已经发布了,你可以看我的代码。
@老虎会游泳,不对噢,
viewer
加了defer
,那就是你先执行
$(document).ready()
,然后解析完DOM后,viewer
再执行$(document).ready()
。触发
DOMContentLoaded
后,你先绑定onclick
,再由viewer
绑定?所以,你的也应该加上
defer
?
@无名啊,这就是我一直在说的方案,并且我已经做好了。
我确实想到一个解决方法,就是用
setTimeout
推迟onclick
事件的绑定。
唯一的解决方法是在一切尘埃落定后重新绑定事件。多个
$(document).ready()
的执行顺序是未知的,但是在$(document).ready()
中使用setTimeout
,那么就一定会晚于对方执行,即使延迟是0。
@老虎会游泳,你的插件排在
viewer
之后,并且也用$(document).ready()
的话,是不是就能在viewer
绑定onclick
后执行了?
@老虎会游泳,看来也用不了
async
属性,要保证按用户设定的脚本顺序执行
@无名啊,因为我的代码不在事件监听器和
defer
内,我的代码是同步js
文件中的立即执行表达式,总是最先执行,所以不必关心执行顺序了。唯一的解决方法是在一切尘埃落定后重新绑定事件。
@无名啊,因为最开始网页插件在顶部,加载很卡。
@老虎会游泳,研究这个咋会无意义呢?
现在你的代码,还是和
viewer
冲突
@无名啊,
$(document).ready()
事件在DOMContentLoaded
事件之后发生。
@无名啊,问题好像并不是同时触发,而是
$(document).ready()
事件在DOMContentLoaded
事件之后发生。
不过现在研究这个问题无意义了,因为我的代码现在位于立即执行表达式中,总是最先执行。
我确实想到一个解决方法,就是用setTimeout
推迟onclick事件的绑定。$(document).ready(function () { document.querySelectorAll('.userimg, .userthumb').forEach(img => (img.onclick = function () { // 链接中的图片不预览 if (0 !== $(this).parents('a').length) return; let elem = document.querySelector('body'); let viewer = new Viewer(elem, { hidden: () => viewer.destroy(), filter(image) { return image.matches('.userimg, .userthumb'); } }); viewer.show() })); });
@老虎会游泳,不是,之前你的版本,最后存活的
onclick
是viewer
的,导致没法点击后加载
@无名啊,既然MDN这么说,那么问题就不是执行顺序问题,而是
onclick
和addEventListener('click')
互不影响,可以同时触发。
@老虎会游泳,我理解错了?https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/script#attr-defer
defer
布尔属性被设定用来通知浏览器该脚本将在文档完成解析后,触发DOMContentLoaded (en-US)
事件前执行。
有defer
属性的脚本会阻止DOMContentLoaded
事件,直到脚本被加载并且解析完成。
@无名啊,
defer
在DOMContentLoaded
之后执行,而且onclick
和addEventListener('click')
互不影响,可以同时触发。