收藏本站腾讯微博新浪微博

经典论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

蓝色理想 最新研发动态 网站开通淘帖功能 - 蓝色理想插件 论坛内容导读一页看论坛 - 给官方提建议

论坛活动及任务 地图和邮件任务 请多用悬赏提问 热夏来袭,选一款蓝色理想的个性T恤吧!

手机上论坛,使用APP获得更好体验 急需前端攻城狮,获得内部推荐机会 论坛开通淘帖功能,收藏终于可以分类了!

搜索
查看: 7093|回复: 16

[求助] ajax异步加载js,总是报错,请帮助,谢谢

[复制链接]
发表于 2012-8-24 14:41:17 | 显示全部楼层 |阅读模式
100体力
主代码
  1. <script language="JavaScript">

  2. var xmlhttp;

  3. if(window.XMLHttpRequest){
  4.         xmlhttp = new XMLHttpRequest();
  5. }else{
  6.         xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  7. }

  8. function ajax(id,url){
  9.         xmlhttp.open("GET",url,true);
  10.         xmlhttp.onreadystatechange = function(){
  11.                 if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
  12.                         IncludeJS( id, url, xmlhttp.responseText );
  13.                 }
  14.         }
  15.         xmlhttp.send();
  16. }

  17. function IncludeJS(id, fileUrl, source){
  18.         if ( source != null && !document.getElementById(id)  ){
  19.                 var head = document.getElementsByTagName('head')[0];
  20.                 var script = document.createElement( "script" );
  21.                 script.language = "javascript";
  22.                 script.type = "text/javascript";
  23.                 script.id = id;
  24.                 script.defer = "defer";
  25.                 script.async = "async";
  26.                 script.text = source;
  27.                 head.appendChild( script );
  28.         }
  29. }

  30. ajax( "xh", "a.js" );
  31. setTimeout(alert(str),500);
  32. </script>
复制代码
a.js的代码
  1. var str = "蓝色理想";
复制代码
以上的写法,所有浏览器都报错,说是找不到str这个变量

我把setTimeout(alert(str),500);写在另外一个单独的script标签里,IE就能弹出"蓝色理想",但是其他非IE浏览器都报错,找不到str这个变量。

诸位,请帮忙解答下,哪里出问题,谢谢!

最佳答案

查看完整内容

保险点可以这么写
发表于 2012-8-24 14:41:18 | 显示全部楼层
保险点可以这么写
  1. <script language="JavaScript">

  2.     var xmlhttp;

  3.     if (window.XMLHttpRequest)
  4.     {
  5.         xmlhttp = new XMLHttpRequest();
  6.     } else
  7.     {
  8.         xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  9.     }

  10.     function ajax(id, url, callback)
  11.     {
  12.         xmlhttp.open("GET", url, true);
  13.         xmlhttp.onreadystatechange = function ()
  14.         {
  15.             if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
  16.             {
  17.                 IncludeJS(id, url, xmlhttp.responseText, callback);
  18.             }
  19.         }
  20.         xmlhttp.send();
  21.     }

  22.     function IncludeJS(id, fileUrl, source, callback)
  23.     {
  24.         if (source != null && !document.getElementById(id))
  25.         {
  26.             var head = document.getElementsByTagName('head')[0];
  27.             var script = document.createElement("script");
  28.             script.language = "javascript";
  29.             script.type = "text/javascript";
  30.             script.id = id;
  31.             script.defer = "defer";
  32.             script.async = "async";
  33.             script.text = source;
  34.             head.appendChild(script);
  35.             if (typeof callback === "function") { callback(); }
  36.         }
  37.     }

  38.     ajax("xh", "a.js", function () { alert(str) });
  39.     //setTimeout(function () { alert(str) }, 500);
  40. </script>
复制代码
回复

使用道具 举报

发表于 2012-8-24 15:13:58 | 显示全部楼层
既然是异步,你执行载入的时候,下面的已经执行setTimeout(alert(str),500);了

这个问题怎么解决我就不说了,我以前也弄过载入js,虽然都正确,但是总不够健壮
如果你感兴趣的话
搜索下requirejs
大体功能是js依赖管理,按需载入,AMD规范
回复

使用道具 举报

 楼主| 发表于 2012-8-24 15:48:13 | 显示全部楼层
本帖最后由 kxm1984 于 2012-8-24 15:50 编辑
WellFrog 发表于 2012-8-24 15:13
既然是异步,你执行载入的时候,下面的已经执行setTimeout(alert(str),500);了

这个问题怎么解决我就不说 ...


JS模块化管理的那些东西(之前大概扫过一眼ControlJS),我现在还不想深研究。

关于报错原因,我也是知道的,但是,我就想知道,我上面的那个该怎么解决,怎么规避??帅蛙版主
回复

使用道具 举报

发表于 2012-8-24 15:50:29 | 显示全部楼层
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<script>
window.onload=function ()
{
        var oBtn=document.getElementById('btn1');
       
        oBtn.onclick=function ()
        {
                ajax('a.js', function (str){
                        //str->'[蓝色理想]'
                        //alert(str);
                        var arr=eval(str);
                       
                        alert(arr[0]);
                });
        };
};
function ajax(url, fnSucc, fnFaild)
{
        //1.创建Ajax对象
        var oAjax=null;
       
        if(window.XMLHttpRequest)
        {
                oAjax=new XMLHttpRequest();
        }
        else
        {
                oAjax=new ActiveXObject("Microsoft.XMLHTTP");
        }
       
        //2.连接服务器
        oAjax.open('GET', url, true);
       
        //3.发送请求
        oAjax.send();
       
        //4.接收服务器的返回
        oAjax.onreadystatechange=function ()
        {
                if(oAjax.readyState==4)        //完成
                {
                        if(oAjax.status==200)        //成功
                        {
                                fnSucc(oAjax.responseText);
                        }
                        else
                        {
                                if(fnFaild)
                                        fnFaild(oAjax.status);
                        }
                }
        };
}
</script>
</head>

<body>
请求服务器上的文件,这个文件放了一个数组<br />
<input id="btn1" type="button" value="读取数组文件" />
</body>
</html>
回复

使用道具 举报

 楼主| 发表于 2012-8-24 16:01:50 | 显示全部楼层
本帖最后由 kxm1984 于 2012-8-24 16:03 编辑
zhenxi537 发表于 2012-8-24 15:50
无标题文档

window.onload=function ()


这是个ajax的一个读取JS功能,有点异步按需加载的意思,但是也不是我想要的!!我想知道我上面的写的那个怎么才能正确弹出结果
回复

使用道具 举报

发表于 2012-8-24 16:49:17 | 显示全部楼层
我没有看到str有append到script里,但是看这个好像木有问题。等答案。
回复

使用道具 举报

发表于 2012-8-24 17:02:55 | 显示全部楼层
kxm1984 发表于 2012-8-24 16:01
这是个ajax的一个读取JS功能,有点异步按需加载的意思,但是也不是我想要的!!我想知道我上面的写的那 ...


四楼不是给你了结果么,按你的不可能正常,即然是异步了,你后来setTimeout怎么能保证在异步完成后呢?

你的alert明显应该放到ajax的回调函数里。
回复

使用道具 举报

发表于 2012-8-24 17:29:08 | 显示全部楼层
  1. setTimeout(function(){
  2. alert(str)
  3. }, 500);
复制代码
必须保证延迟的时间大于ajax返回结果的时间


完全可以给ajax添加一个参数用于执行回调
  1. function ajax(id,url, callback){
复制代码
依稀记得不能给内联的script标签添加defer和async属性
  1. <script defer='xxx' async='xxx'>
  2. //xxxxx
  3. </script>
复制代码
回复

使用道具 举报

发表于 2012-8-24 18:02:41 | 显示全部楼层
这个问题很复杂,不过抛开其他的不谈,你写的有问题:

  1. setTimeout(alert(str),500);
复制代码
你这句代码有错误,alert(str)会直接执行,压根就没有延迟500毫秒,你需要把它写成匿名函数:

  1. setTimeout(function() {alert(str);}, 500);
复制代码
或者用引号引起来:

  1. setTimeout('alert(str)',500);
复制代码
不过即使你这么改了,还是有问题的,参考其他人的回复吧。
回复

使用道具 举报

发表于 2012-8-24 18:13:19 | 显示全部楼层
今天看了这些,我的问题总算解决了
回复

使用道具 举报

发表于 2012-8-24 19:30:54 | 显示全部楼层
都是大神  学习到了
回复

使用道具 举报

 楼主| 发表于 2012-8-27 13:54:37 | 显示全部楼层
WellFrog 发表于 2012-8-24 14:41
保险点可以这么写

为什么这么写就可以啊???说说原因吧,谢谢,版主。

另外在说说defer和async的问题吧??

我做过实验,只要是加载外部的JS,用了defer和async,页面呈无阻塞状态。

但是,加了defer和async的内联JS,各个浏览器都表现的很诡异,不统一。
斑竹能不能再说说了,内联JS的defer和async的使用方法。(或者内联的根本不需要用??)
(一共两个问题,虚心请教)
回复

使用道具 举报

 楼主| 发表于 2012-8-27 13:55:04 | 显示全部楼层
另外,谢谢楼上的诸位,帮忙回答了那么多问题。
回复

使用道具 举报

发表于 2012-8-27 15:21:32 | 显示全部楼层
kxm1984 发表于 2012-8-27 13:54
为什么这么写就可以啊???说说原因吧,谢谢,版主。

另外在说说defer和async的问题吧??

先说说HTML5之前script标签的defer属性
defer是IE私有的属性
通俗点说就是当前页面加载完成后才执行defer="defer"的script中脚本
下面这个例子很容易明白,仅IE有效

 提示:您可以先修改部分代码再运行


上面这段代码在没有defer="defer"时,很明显是错误的,因为执行脚本时,div还没加载进来
但是加了defer="defer"后,它会在页面加载完毕后才执行脚本,所以可以正常alert出abc
强调:仅IE有效

此外,defer和async也是HTML5中的新属性
但是HTML5的defer和IE下的defer略有不同,在HTML5中defer和async仅对外部js有效
其中defer="defer"作用是IE下的defer一样的,即页面加载完成后才执行脚本
async="async"则表示页面进行剩下的解析时,脚本也在执行(异步)

所以你说加载外部的JS,用了defer和async,页面呈无阻塞状态。
因为他们都是异步加载且在页面加载完成后才执行脚本
但是这个仅仅是HTML5有效

至于内联JS的defer和async的使用方法
其实这些都可以不用考虑,包括外链
因为你只需要window.onload即可,或者domReady之类的插件也行
回复

使用道具 举报

 楼主| 发表于 2012-8-27 17:28:38 | 显示全部楼层
本帖最后由 kxm1984 于 2012-8-27 17:31 编辑
WellFrog 发表于 2012-8-27 15:21
先说说HTML5之前script标签的defer属性
defer是IE私有的属性
通俗点说就是当前页面加载完成后才执行def ...


thanks,不过两个问题,才回答一个。第一个问题,为什么回调函数去找str变量就ok,单独去找str变量就报错呢????
回复

使用道具 举报

发表于 2012-8-27 19:35:12 | 显示全部楼层
kxm1984 发表于 2012-8-27 17:28
thanks,不过两个问题,才回答一个。第一个问题,为什么回调函数去找str变量就ok,单独去找str变量就报 ...

直接去找str,因为你是异步加载,js的ajax加载和下面的程序是一起执行的。你执行alert(str)的时候,请求的js可能还没有加载完成,所以找不到。

回调就是可以保证,我是在请求的js加载完成后才执行回调中的程序

setTimeout(function () { alert(str) }, 500);
也是可以的,但是在网络比较差的时候,一样会找不到str
所以最保险的是用回调函数来解决
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|小黑屋|Archiver|手机版|blueidea.com ( 湘ICP备12001430号 )  

GMT+8, 2020-8-11 11:19 , Processed in 0.109099 second(s), 8 queries , Gzip On, Memcache On.

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表