• AJAX应用【股票案例】


    股票案例

    我们要做的是股票的案例,它能够无刷新地更新股票的数据。当鼠标移动到具体的股票中,它会显示具体的信息。

    我们首先来看一下要做出来的效果:

    这里写图片描述

    服务器端分析

    首先,从效果图我们可以看见很多股票基本信息:昨天收盘价、今天开盘价、最高价、最低价、当前价格、涨幅。这些信息我们用一个类来描述出来。

    我们发现数据是定时刷新的,于是我们需要一个定时器。

    服务器端的数据和客户端交互,我们使用JSON吧

    服务器端代码

    Stock股票类的代码

    • 股票基本信息:
    
        private String id;
    
        private String name;
    
        private double yesterday;
    
        private double today ;
    
        private double highest;
    
        private double lowest;
    
        private double current;
    
        private String range ;
    
        //各种setter和getter
    
    • Stock的构造函数:
        /**
         * id,name,yesterday这三个参数都是固定的,其他的属性都是可变的。
         * 因此我们构造函数就传入这三个值
         * */
        public Stock(String id, String name, double yesterday) {
            this.id = id;
            this.name = name;
            this.yesterday = yesterday;
    
            //把开盘价设定为-1,后面在定时器计算出来的随机数,如果发现开盘价是-1,就设置第一次的随机数为开盘价
            this.today = -1;
    
            //把最高、最低、当前的价格都暂且设置成昨天的开盘价,后面我们可以变化的
            this.highest = yesterday;
            this.current = yesterday;
            this.lowest = yesterday;
    
        }
    
    • setCurrent()方法代码:
    
    
        /**
         * 每次设置当前价钱的时候,最高、最低、涨幅都应该随着当前价钱而变化的
         */
        public void setCurrent(double current) {
    
            //计算出涨幅或跌幅
            double range = (current - this.yesterday) / this.yesterday;
    
            //设置涨幅和跌幅不能超过10%,当前的价格只能是昨天开盘价的1.1倍或0.9倍
    
            //当前价格应该是两位小数
            DecimalFormat formatPrice = new DecimalFormat("#.00");
    
            if (range > 0.1) {
                current = Double.parseDouble(formatPrice.format(this.yesterday * 1.1));
            }
    
            if (range < -0.1) {
                current = Double.parseDouble(formatPrice.format(this.yesterday * 0.9));
            }
            this.current = current;
    
            //如果今天开盘价没设定,那么就将第一次的当前价作为今天的开盘价
            if (this.today == -1) {
                this.today = this.current;
            }
    
            //比较最大值和最小值
            if (this.current > this.highest) {
                this.highest = this.current;
            }
            if (this.current < this.lowest) {
                this.lowest = this.current;
            }
    
            //格式化涨幅的字符串,整数两位,小数两位
            DecimalFormat formatRange = new DecimalFormat("##.##%");
            this.range = formatRange.format(range);    
        }
    

    Servlet的代码

    • init()初始化代码:
    
        /**
         * 重写init()方法,加入一些配置内容
         */
        @Override
        public void init(ServletConfig config) throws ServletException {
    
            map = new HashMap<>();
    
            //新建几只固定的股票
            final Stock zhong = new Stock("1", "百度", 1110.1);
            final Stock fu = new Stock("2", "阿里", 222.2);
            final Stock cheng = new Stock("3", "腾讯", 333.3);
            final Stock ou = new Stock("4", "谷歌", 1133.5);
    
            //添加到容器中
            map.put("1", zhong);
            map.put("2", fu);
            map.put("3", cheng);
            map.put("4", ou);
    
            //生成随机数
            final Random random = new Random();
    
            //格式化生成的随机数
            final DecimalFormat format = new DecimalFormat("#.00");
    
            //Servlet被启动后1秒开始,每两秒扫描一次
    
            timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
    
                    double baidu = random.nextDouble() * 1.1;
                    double ali = random.nextDouble() * 2;
                    double tengxun = random.nextDouble() * 0.3;
                    double geogle = random.nextDouble() * 4;
    
                    //概率大致都是50%,我们用来做正负
                    if (random.nextBoolean()) {
                        baidu = 0 - baidu;
                    }
                    if (random.nextBoolean()) {
                        ali = 0 - ali;
                    }
    
                    if (random.nextBoolean()) {
                        tengxun = 0 - tengxun;
                    }
                    if (random.nextBoolean()) {
                        geogle = 0 - geogle;
                    }
    
                    //设置它们的当前价格
                    zhong.setCurrent(Double.parseDouble(format.format(zhong.getCurrent()+baidu)));
                    fu.setCurrent(Double.parseDouble(format.format(fu.getCurrent()+ali)));
                    cheng.setCurrent(Double.parseDouble(format.format(cheng.getCurrent()+tengxun)));
                    ou.setCurrent(Double.parseDouble(format.format(ou.getCurrent()+geogle)));
    
                }
            }, 1000, 2000);
    
    
        }
    • 服务器一启动就应该初始化Servlet
    
    
        <servlet>
            <servlet-name>Refresh</servlet-name>
            <servlet-class>Refresh</servlet-class>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>Refresh</servlet-name>
            <url-pattern>/Refresh</url-pattern>
        </servlet-mapping>
    
    
    • doPost()代码:
    
    
            //封装成JSON格式,返回给浏览器
            StringBuffer buffer = new StringBuffer();
    
    
            //这里我们拼接成4个对象
            buffer.append("({");
            for (Map.Entry<String, Stock> entry : map.entrySet()) {
                String id = entry.getKey();
                Stock stock = entry.getValue();
    
                buffer.append(id).append(":{yesterday:").append(stock.getYesterday()).append(",today:").append(stock.getToday()).append(",high:").append(stock.getHighest()).append(",low:").append(stock.getLowest()).append(",current:").append(stock.getCurrent()).append(",range:'").append(stock.getRange()).append("'}").append(",");
    
            }
            //消除最后一个逗号
            buffer.deleteCharAt(buffer.lastIndexOf(","));
    
            //最后补上括号
            buffer.append("})");
    
            //返回给浏览器
            response.getWriter().write(buffer.toString());
    
    • 拼接成的JSON数据:
    ({
        3:{yesterday:333.3,today:333.48,high:333.48,low:333.3,current:333.48,range:'0.05%'},
        2:{yesterday:222.2,today:223.46,high:223.46,low:222.2,current:223.46,range:'0.57%'},
        1:{yesterday:1110.1,today:1109.73,high:1110.1,low:1109.73,current:1109.73,range:'-0.03%'},
        4:{yesterday:1133.5,today:1135.49,high:1135.49,low:1133.5,current:1135.49,range:'0.18%'}
    })
    

    客户端分析之一

    客户端要做的就是显示数据,每隔两秒就和服务器进行一次交互
    - 用到Ajax和setInterval()方法

    html代码

    使用div嵌套span和a标签来进行显示,span装载的就是服务端返回json的current数据

    <body onload="show()">
    
    <div>
        <a href="#">百度:</a>
        <span id="1"></span>
    </div>
    <div>
        <a href="#">阿里巴巴:</a>
        <span id="2"></span>
    </div>
    <div>
        <a href="#">腾讯:</a>
        <span id="3"></span>
    </div>
    <div>
        <a href="#">谷歌:</a>
        <span id="4"></span>
    </div>
    
    
    </body>
    

    javaScript代码

    • 解析JSON,并设置span的内容
    
    
    
            function show() {
    
                getStock();
    
                //每两秒就取一次数据
                setInterval(getStock, 2000);
    
            }
            var httpRequest;
            function getStock() {
    
                //力求是最新的响应数据,如果存在httpRequest,那么将上次的httpRequest终止
                if(httpRequest) {
                    httpRequest.abort();
                }
    
                httpRequest= new XMLHttpRequest();
                httpRequest.open("GET", "Refresh", true);
                httpRequest.onreadystatechange = callBackFunction;
                httpRequest.send(null);
    
            }
    
            function callBackFunction() {
                if(httpRequest.readyState==4) {
                    if(httpRequest.status==200) {
    
                        //得到服务器端返回的JSON数据
                        var text = httpRequest.responseText;
    
                        //解析成JavaScript对象
                        var json = eval(text);
    
                        //遍历出每个JSON对象【也就是json的id】
                        for(var id in json) {
    
                            //得到每个stock对象
                            var stock = json[id];
    
                            //将当前的价格设置到span节点里面
                            document.getElementById(id).innerHTML = stock.current;
    
                            //比较当前价格和昨天开盘价格,如果大于就是红色,小于就是绿色
                            if(stock.current>stock.yesterday) {
                                document.getElementById(id).style.color = 'red';
                            }else {
                                document.getElementById(id).style.color = 'green';
    
                            }
                        }
    
                    }
                }
            }
    • 效果

    这里写图片描述


    客户端分析之二

    当鼠标移动到具体的股票超链接的时候,会显示具体的数据,并且数据是动态的
    - 在超链接上绑定事件
    - 取出和服务器交互的数据,显示在页面上

    html代码:

    绑定事件,只要鼠标移动到超链接上就触发事件

    
    <body onload="show()">
    
    <div>
        <a href="#" onmouseover="showTool(this)" onmouseleave="clearTool()">百度:</a>
        <span id="1"></span>
    </div>
    <div>
        <a href="#" onmouseover="showTool(this)" onmouseleave="clearTool()">阿里巴巴:</a>
        <span id="2"></span>
    </div>
    <div>
        <a href="#" onmouseover="showTool(this)" onmouseleave="clearTool()">腾讯:</a>
        <span id="3"></span>
    </div>
    <div>
        <a href="#" onmouseover="showTool(this)" onmouseleave="clearTool()">谷歌:</a>
        <span id="4"></span>
    </div>
    
    <div id="toolTip">
        <div>
            昨收:<span id="yesterday"></span>
        </div>
    
        <div>
            今收:<span id="today"></span>
        </div>
    
        <div>
            最低:<span id="low"></span>
        </div>
        <div>
            当前:<span id="current"></span>
        </div>
        <div>
            最高:<span id="high"></span>
        </div>
        <div>
            涨幅:<span id="range"></span>
        </div>
    </div>
    
    
    </body>

    css代码

    详细框的信息默认是隐藏的

        <style type="text/css">
    
            #toolTip {
                border: 1px solid #000;
                width: 150px;
                position: absolute;
                display: none;
            }
    
        </style>

    javaScript代码

    得到交互的数据,设置span里面的值

    
            function update() {
    
                var stock = json[sid];
    
                //得到相对应的控件
                var yesterday = document.getElementById("yesterday");
                var today = document.getElementById("today");
                var low = document.getElementById("low");
                var high = document.getElementById("high");
                var range = document.getElementById("range");
                var current = document.getElementById("current");
    
                //设置具体信息的值
    
                high.innerHTML = stock.high;
                range.innerHTML = stock.range;
                current.innerHTML = stock.current;
                yesterday.innerHTML = stock.yesterday;
                today.innerHTML = stock.today;
                low.innerHTML = stock.low;
    
                //如果数值比昨天开盘价低,反则就是红色
                if (stock.today > stock.yesterday) {
                    today.style.color = 'red';
                } else {
                    today.style.color = 'green';
                }
    
                if (stock.low > stock.yesterday) {
                    low.style.color = 'red';
                } else {
                    low.style.color = 'green';
                }
                if (stock.high > stock.yesterday) {
                    high.style.color = 'red';
                } else {
                    high.style.color = 'green';
                }
    
                //如果现在的价格比昨天开盘高,那么涨幅是红色
                if (stock.current > stock.yesterday) {
                    range.style.color = 'red';
                    current.style.color = 'red';
                } else {
                    range.style.color = 'green';
                    current.style.color = 'green';
                }
            }

    只有鼠标移到超链接上,才明确id的值是多少!

            function callBackFunction() {
                if (httpRequest.readyState == 4) {
                    if (httpRequest.status == 200) {
    
                        //得到服务器端返回的JSON数据
                        json= eval(httpRequest.responseText);
    
                        //更新详细框的数据,当鼠标移动到超链接上才确定有id,于是判断有没有id
                        if(sid) {
                            update();
                        }
    
                        //遍历出每个JSON对象【也就是json的id】
                        for (var id in json) {
    
                            //得到每个stock对象
                            var stock = json[id];
    
                            //将当前的价格设置到span节点里面
                            document.getElementById(id).innerHTML = stock.current;
    
                            //比较当前价格和昨天开盘价格,如果大于就是红色,小于就是绿色
                            if (stock.current > stock.yesterday) {
                                document.getElementById(id).style.color = 'red';
                            } else {
                                document.getElementById(id).style.color = 'green';
    
                            }
                        }
    
    
                    }
                }
            }
    
            function showTool(node) {
    
                //得到鼠标移动到具体股票的id
                sid = node.parentNode.getElementsByTagName("span")[0].id;
    
                //把详细框框显示出来
                document.getElementById("toolTip").style.display = 'block';
    
            }
            function clearTool() {
                document.getElementById("toolTip").style.display = 'none';
            }
    
    

    最终效果:

    这里写图片描述

    总结要点

    ①:这是由AJAX来实现的,因为它无刷新的动态交互数据。

    ②:服务器端应该保存着股票的基本信息。于是乎,我们用一个类来装载着这些信息【信息之间的关系就不一一说明了,因为每个案例用的可能都不一样】

    ③:用到了DecimalFormat类来格式化小数变为自己想要的格式

    ④:使用HashMap来装载这些股票,使用Map集合主要是在客户端中,可以通过键来访问具体的股票,只要能访问到股票了,那么一切就好说了。

    ⑤:当然啦,装载股票的任务就交给init()方法,因为只需要装载一次。

    ⑥:我们会发现,股票的信息是不断会变化的,所以我们使用定时器和Random类来不断修改股票的信息

    ⑦:JavaScript和服务端交互使用AJAX,要么使用XML,要么就是JSON,这次我们采用的是JSON

    ⑧:JavaScript使用XMLHttpRequest对象得到Servlet返回给浏览器的JSON数据,解析JSON数据,变成是JavaScript对象

    ⑨:在页面上显示服务端带过来的数据,一般都是使用div来显示【块级】,用控件绑定id,在JavaScript中得到控件,填充数据。这样就是动态地修改页面的数据了。

    ⑩:浏览器想要不断地从服务端获取股票的数据,那么就需要不断地与服务端交互,解析JSON,填充数据…..这种我们可以通过setInterval()定时器来做

    ①①:想要修改字体的颜色,只要获取它的控件再style.color就可以修改了。

    ①②:鼠标移动到具体的股票链接的时候,会出现股票的详细信息时,这明显就是为超链接绑定了事件

    ①③:股票的详细信息用一个框框装载着,那么我们就在css中初始化这个框框,它平时是不显示出来的,只用在鼠标移到它那里的时候才显示,我们把display=“none”就行了。

    ①④:在响应事件的时候,我们需要知道用户是移动到哪一个超链接上,所以要获取得到具体的超链接id。知道id以后,我们就知道用户想要知道的股票是哪一个了。

    ①⑤:股票的信息也想要及时的更新,那么我们想把它抽取成一个方法,在AJAX回调方法中加入进去就行了。当然了,id和具体股票对象应该是全局的变量【这样才能够在别的方法中用到】

    如果您觉得这篇文章帮助到了您,可以给作者一点鼓励



  • 相关阅读:
    jmeter录制
    Jmeter之逻辑控制器
    Jmeter关联
    Jmeter之HTTP请求默认值
    shell一文入门通
    Linux系统编程——基础命令总结
    前端专业方向的尽头
    锤子,技术与交互体验细节
    学习汇总 2019-12-2
    不容错过的 Babel7 知识
  • 原文地址:https://www.cnblogs.com/zhong-fucheng/p/7203014.html
Copyright © 2020-2023  润新知