V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
eoo
V2EX  ›  JavaScript

JavaScript Ajax PHP 做异步显示问题

  •  
  •   eoo · 2015-08-15 21:41:28 +08:00 via Android · 3550 次点击
    这是一个创建于 3181 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我要实现的功能是: 按下按钮后触发 JavaScript 执行Ajax 向PHP后台查询数据 然后返回给JavaScript进行 一条一条的显示出来, 今天想了一天 蛮子都要炸了,完全不懂JavaScript 都是现学现用,JS帮我看看吧。


    带上飞机: http://v.milog.cn/ajax/
    代码如下:

    <!DOCTYPE html>
    <html>
    <head>
    <meta http-equiv="content-type" content="text/html;charset=utf-8">
    <meta name="viewport" content="width=device-width,
    initial-scale=1.0,
    maximum-scale=1.0,
    user-scalable=0" />
    <meta http-equiv=Cache-Control content=no-cache />
    <title>测试</title>
    <!--JavaScript代码-->
    <script type="text/javascript">
    i=0;

    function go(){
    //document.getElementById("txt").innerHTML="<div style='margin:50% auto;text-align:center'>努力加载中...</div>";

    if (window.XMLHttpRequest){
    xmlhttp=new XMLHttpRequest();
    }else {
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }


    <!-- Ajax POST请求-->
    var url=document.getElementById("url").value;
    var go_url = "mysqli.php";
    xmlhttp.open("POST",go_url,true);
    xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
    xmlhttp.send("url="+url);


    xmlhttp.onreadystatechange = function(){
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {



    var eoo =xmlhttp.responseText;


    type(eoo);



    }
    }
    }


    function type(eoo){

    var str = eoo.split('<>');

    //document.getElementById("str").innerHTML += '<div>'+str[i];

    txt.innerHTML += '<div>' + str[i] + '</div>';

    i++;

    if(i>=str.length) return;

    setTimeout("type(str)",100);

    }


    </script>

    <!--CSS代码-->
    <style type="text/css">
    pre{
    white-space: pre; /* CSS 2.0 */
    white-space: pre-wrap; /* CSS 2.1 */
    white-space: pre-line; /* CSS 3.0 */
    white-space: -pre-wrap; /* Opera 4-6 */
    white-space: -o-pre-wrap; /* Opera 7 */
    white-space: -moz-pre-wrap !important; /* Mozilla */
    white-space: -hp-pre-wrap; /* HP Printers */
    word-wrap: break-word;
    }

    .header {
    text-align:center;
    //width:100%;
    background-color:#FAEBD7;
    padding:10px 20px;
    margin:auto;
    }

    input {
    border: 1px dashed #666;
    }

    </style>
    </head>
    <body>
    <div class="header">
    <input type="text" id="url" value="" / >
    <button type="button" onclick="ql()">清除</button>
    <button type="button" onclick="go()">抓取</button></div>
    <div id="txt"></div>
    </body>
    </html>
    30 条回复    2015-08-16 23:28:21 +08:00
    emric
        1
    emric  
       2015-08-15 21:54:48 +08:00   ❤️ 1
    关键字: setTimeout 作用域
    bdbai
        2
    bdbai  
       2015-08-15 21:59:52 +08:00 via iPhone
    不管怎么样用原生Ajax值得表扬。
    feiyuanqiu
        3
    feiyuanqiu  
       2015-08-15 23:03:00 +08:00   ❤️ 1
    稍微改了一下,你看看能用不
    http://jsbin.cn/rufubamumo/1/edit?js,output
    jsonline
        4
    jsonline  
       2015-08-15 23:12:06 +08:00 via Android
    不用jQuey 也是彪悍
    ning1022
        5
    ning1022  
       2015-08-15 23:24:27 +08:00
    jquery 几行代码就可以搞定,为啥要写原生的代码
    eoo
        6
    eoo  
    OP
       2015-08-15 23:40:18 +08:00 via Android
    @feiyuanqiu 可以是可以 但有一些不明白。
    eoo
        7
    eoo  
    OP
       2015-08-15 23:41:53 +08:00 via Android
    @ningyuqiao456 我不是靠代码吃饭,所以我还要最求效率,所以比较喜欢原生。
    8qwe24657913
        8
    8qwe24657913  
       2015-08-15 23:48:03 +08:00
    @eoo setTimeout("type(str)",100);换成setTimeout(function(){type(str)},100);即可,见#1 关键字
    变量名叫eoo吐槽无力……
    eoo
        9
    eoo  
    OP
       2015-08-15 23:54:53 +08:00 via Android
    @8qwe24657913 不行哦,不过还是谢谢。由于是手机码代码,为了节省时间,就随便写了。
    8qwe24657913
        10
    8qwe24657913  
       2015-08-16 00:00:45 +08:00
    @eoo 刚刚看错了……以为函数直接传的str……
    function type(eoo) {
    typeStr(eoo.split('<>'));
    }
    function typeStr(str) {
    //document.getElementById("str").innerHTML += '<div>'+str[i];
    txt.innerHTML += '<div>' + str[i] + '</div>';
    i++;
    if (i >= str.length) return;
    setTimeout(function(){type(str)}, 100);
    }
    8qwe24657913
        11
    8qwe24657913  
       2015-08-16 00:02:10 +08:00
    @eoo 好吧我手残……
    function type(eoo) {
    typeStr(eoo.split('<>'));
    }
    function typeStr(str) {
    //document.getElementById("str").innerHTML += '<div>'+str[i];
    txt.innerHTML += '<div>' + str[i] + '</div>';
    i++;
    if (i >= str.length) return;
    setTimeout(function(){typeStr(str)}, 100);
    }
    eoo
        12
    eoo  
    OP
       2015-08-16 00:10:24 +08:00 via Android
    @8qwe24657913 还是不能连续输出,点测试 只能取一天数据。。。。。 感情JavaScript水好深,真是吓屎宝宝我了,学点基础果断回到原生PHP的怀抱中~~~
    8qwe24657913
        13
    8qwe24657913  
       2015-08-16 00:21:31 +08:00
    @eoo 听不懂"只能取一天数据"什么意思……是指不能点第二次测试吗……那是因为你的i是全局变量,点了一次之后i已经到7了
    eoo
        14
    eoo  
    OP
       2015-08-16 00:32:12 +08:00 via Android
    @8qwe24657913 打错字了,是一条, 其实我想要的效果就是这样的http://e.milog.cn/ 但是我又不会怎么监控echo的的状态, 所以只能把responseText返回的数据再进行二次加工。 无奈 不会JavaScript 现学现写 就是不知道哪里出了问题。
    eoo
        15
    eoo  
    OP
       2015-08-16 00:36:13 +08:00 via Android
    @8qwe24657913 可以点,就是本来应该点一次就连续输出5条记录,现在问题是点一次出一天。
    8qwe24657913
        16
    8qwe24657913  
       2015-08-16 00:49:20 +08:00
    @eoo 你确定用的是#11的代码吗……还有测试页面第43行比这边主题的代码多了个setTimeout("type(eoo)",100);删掉
    suikator
        17
    suikator  
       2015-08-16 01:14:30 +08:00 via Android
    @8qwe24657913 么么哒
    will0404
        18
    will0404  
       2015-08-16 01:23:20 +08:00
    用jquery多省事
    eoo
        19
    eoo  
    OP
       2015-08-16 08:51:39 +08:00 via Android
    @8qwe24657913 要不你直接帮我改吧 顺便测试 http://v.milog.cn/eoo/ 用户名 eoo 密码 xuchangyu 文件在ajax文件夹里面。
    eoo
        20
    eoo  
    OP
       2015-08-16 08:52:44 +08:00 via Android
    @will0404 jquery已经阻碍了人类脑细胞的发现,哈哈。
    8qwe24657913
        21
    8qwe24657913  
       2015-08-16 12:57:05 +08:00 via Android
    @eoo 起晚了……已改,个人意见如果兼容古老ie的话jq还是挺有用的,可以省掉写ie兼容的时间……
    8qwe24657913
        22
    8qwe24657913  
       2015-08-16 13:57:47 +08:00
    @eoo 不过我是本着尽量少改代码的原则的,要我重写的话估计会变成

    这样吧……

    不过这个说到底还是等数据全部加载完毕之后再延时一条一条显示,如果需要服务端echo一次输出一次的话参考https://web-tinker.com/article/20047.html
    eoo
        23
    eoo  
    OP
       2015-08-16 14:02:24 +08:00 via Android
    @8qwe24657913 你真厉害,我的偶像啊, 你扣扣多少 能加一下吗?
    8qwe24657913
        24
    8qwe24657913  
       2015-08-16 14:13:01 +08:00
    @eoo 并不厉害_(:з」∠)_而且我那张图真要用的话估计polyfill得比业务代码多不知多少倍……
    eoo
        25
    eoo  
    OP
       2015-08-16 14:21:20 +08:00 via Android
    @8qwe24657913 不过还有个小问题,就是在输出完后 再点 就会再输出 一个undefined 这个如何解决?


    你给我推荐的那篇文章就是传说中的 反Ajax吧? 这个需要在服务端做死循环 感觉普通的虚拟主机会受不鸟。
    8qwe24657913
        26
    8qwe24657913  
       2015-08-16 16:36:11 +08:00 via Android
    @eoo 所以我问过你需不需要点第二次……已改

    那个死循环只是为了演示,正确用法是echo 耗时操作 echo这样,是为了边加载边显示,不耗时就没多大意义了……

    好吧我可能是搞错了你的想法,估计你只是想做个逐行显示的效果愉♂悦一下用户:joy:

    题外话 comet和websocket乖乖交给node.js,php写=作死
    eoo
        27
    eoo  
    OP
       2015-08-16 18:22:10 +08:00 via Android
    @8qwe24657913 谢谢你的耐心解答,灰常感谢。
    21grams
        28
    21grams  
       2015-08-16 19:40:30 +08:00 via Android
    这年头没人会写野生JavaScript了吗
    eoo
        29
    eoo  
    OP
       2015-08-16 20:42:44 +08:00 via Android
    @21grams 我写的不就是了吗?
    strwei
        30
    strwei  
       2015-08-16 23:28:21 +08:00 via Android
    打酱油
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2245 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 02:35 · PVG 10:35 · LAX 19:35 · JFK 22:35
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.