这两天做试验,给料网加上了 Google Remarketing 的代码。由于 Google 被墙的缘故,造成浏览器底部状态栏一直显示“正在连接 www.googleadservices.com ...”
无意点击了一下文章页右侧栏的文章分类 Tabs,发现切换竟然失效。依次点击文章的“bigger”和结尾处的“打赏”按钮,一样无任何反应。
点击顶部 fixed header 的 search 按钮,搜索框 slidedown 正常响应。
这期间,页面状态栏一直显示是 “正在连接 www.googleadservices.com ...”。
大概等待了 10 秒左右,状态栏显示网页加载完毕,这时再点击文章页侧栏 tabs 和打赏按钮,又一切正常了。
试着删除 Google Remarketing 代码,一切又恢复正常,状态栏无任何加载异常瞬间加载完成。
看了一下 Google Remarketing 的代码,里面调用了 google 的 conversion.js,明显是被墙了加载缓慢。
百度搜索了一遍,发现没什么内容,只有一些 Google Analytics(GA)代码的异步加载办法。关于 Google Remarketing 的代码没有任何说明。尝试了一下异步加载,没任何卵用。
把 Google Remarketing 的 conversion.js 文件存在本地主机上,每次不去从谷歌调用,应该也行。动手实验了一下,OK!
但是有个问题,万一谷歌更新了 conversion.js,而一直调用本地 JS 也不知道,可能会造成 google track 失效,这办法显然治标不治本。
这时候我又仔细想了一下,为什么搜索的按钮点击正常,其他按钮 click 事件失效呢。看了一下 JS 文件,发现搜索的按钮是写在 $(document).ready
之外,
$(document).ready(function() { ...... })
其他的按钮都是写在 $(document).ready
之内。这才回想起来,一些不需要页面加载完再写的代码,根本没必要放在 $(document).ready 之内。
尝试把 侧栏的 Tabs 和 文章结尾打赏 button 代码拿到 $(document).ready
外面来,保存覆盖 JS。
清理浏览器缓存,打赏按钮回复正常。
但仍然有问题:Tabs 按钮照旧要等到页面加载完,点击才反应。仔细看了一下代码,突然恍然大悟。Tabs 代码外面多套了一个 $(function(){ ... })
!
解决了这个问题之后,不禁思考:为什么会出现这种错误?回想一下,当初刚开始接触 Jquery 的时候没有认真系统地学,很多都是从 w3school 里查阅一下资料。而坑爹的 w3school 虽然有很多动手查看实例,但几乎所有的 Jquery 实例的代码环境永远是 $(document).ready(function() { .... }
渐渐地很多人已经有了思维定势,不管写什么代码都要写在这个代码框架内。
而这个 $(document).ready 是要等页面中所有 DOM(文档对象模型)已经加载,并且页面已经完全加载完之后才会执行,也就是说 Goole Remarketing 的代码不加载完,这里面的 Jquery 代码就还没执行生效!
即使写在 $(document).ready 之外,也要注意:能直接绑定时间的直接绑定,简单一些。
对于 Tabs 的代码,多套一个 function
纯属画蛇添足。实际上 $(function(){ ... })
!也同样是加载完成才运行。
在一般情况下,其实这么写也没问题,甚至写在 $(document).ready 内也完全没事。 我之前就这么写,因为正常情况下网页加载很快,JS 可以放到页面底部 footer 中</body>前面加载,页面 DOM 基本都已加载完毕。 真正到了特殊情况下,比如谷歌 JS 被墙,页面加载不畅始终加载未完成的状态下,以上代码的写法会出现本文所述的问题。
由此引申出一个经典问题:jQuery 中的事件放在 ready() 方法里面 和 放在外面 有什么区别?例如:
<script type="text/javascript"> $(document).ready(function(){ $("#id1").click(function(){ alert("click"); }); }); $("#id2").click(function(){ alert("click"); }); </script> 上面这两个 click 事件有什么区别吗?
很显然是有区别的。ready() 方法意思是等整个页面的 DOM 解析完毕执行;而直接绑定方法是页面流从上往下解析,页面加载到这个位置的时候就会执行。这个时候不一定 DOM 加载完毕, 所以很可能出错。再比如下面一个例子:
<div id="d1"></div> <script type="text/javascript"> $(document).ready(function(){ alert($("#d2").html()); alert("ok"); }); alert($("#d2").html()); </script> <div id="d2">test</div>
Jquery 的代码是嵌在两段 HTML 中的,当页面加载到这段 JS 代码时,在 ready 里面的 2 个 alert() 代码不会立即执行,而在外面的 alert() 代码则会马上执行,但是这个时候 div#d2 并没有加载出来,所以第一个弹出框的内容 NULL,因为 jquery 找不到还未加载出来的 DOM。等所有的代码加载好了后,ready 里面的内容会开始执行,这个时候就会依次跳出 2 个 alert:"test" 和 "ok"。
忍不住有感而发,学习选择正确的资料和途径真的是太重要了。当初学习 Jquery 为了图快,就主要参考了 w3school 。现在看来,w3school 的内容太浅了,罗列的都是最简单的知识点,缺乏连贯性。入门虽然很快,但是难以提高。
作为一名喜欢动手折腾的 code fans,学习 web 相关的 codes,我还是觉得国外的网站和资源更棒。
比如 codecademy 这个网站,我特别喜欢。用了快两年了,学习体验很棒,能学到的知识也很丰富。最主要是的,可以在线动手实践。如有你也有学习 coding 的兴趣,不妨一试。
经过两天的测试,页面一切正常,虽然仍然偶尔会加载,但 JS 都顺利执行!至此,Google Remarketing 代码引起的问题终于解决。
最后总结一下:碰到页面加载时间过长而页面 JS 功能失效,页面加载完 JS 功能又恢复时,应该检查一下 JS 代码中的 ready 事件。注意两个问题:
- ready 事件的代码在页面所有 DOM 加载完之后执行
- ready 事件有三个语法写法,
$(function(){ ... })
也是其中之一
ready 事件的三种语法:
- 语法 1:$(document).ready(function)
- 语法 2:$().ready(function)
- 语法 3:$(function)
估计大家不会碰到我这样的问题,估计即使有人要做网络营销,估计也没几个需要在自己的博客网站放 GA/ GR 代码的。多数可能还是布置在企业英文网站上,面向国外用户浏览的,也不存在 Google JS 被墙体验不佳的问题,因此可能真的没人碰到过我这样的问题,所以写下这篇文章,就当作为自己的记录吧!
有时候我会写写我感兴趣的话题,不一定都是写外贸类文章。写文章这件事,本来就很主观。见谅!
2015/12/13 update: 刚发现由于加载谷歌 JS,音乐频道的播放器的 JS 加载缓慢,音乐要等页面加载完才能播放。诶,真烦,懒得改播放器 JS,打算先把 conversion.js 存在本地先用着了。以后在看看有没有更好的解决办法。
本站所有文章除注明“转载”的文章之外,均为原创。未经本站允许,请勿随意转载或用作任何商业用途,否则依法追究侵权者法律责任的权利。
料哥的书出了吗
把代码都从 dom ready 里拿出来~ 真这么做的?这是个没啥 js 代码的页面么?
不才虽然表示感兴趣,但是对小白来说看的云山雾罩的
生命不息,折腾不止!
小白来看一下