AJAX实例之股票实时信息显示

实例内容

             实例的具体内容是:服务端每隔指定时间产生股价,并计算涨幅,然后以json数据格式发送给客户端页面;客户端页面每隔指定时间重新获取服务端数据,解析json数据格式,并显示涨停。

        实例来源于王兴魁Ajax教学视频,视频中用的是NetBeans环境Java语言编写的,使用NetBeans按教程编写不是很难,所以想着用VS2010环境C#编写,代码如下。

实例代码

        Stocks.cs

        Stock.cs,股票类代码:

/// <summary>
///股票信息类
/// </summary>
public class Stock
{
	public Stock(string id,string name,double yesterday)
	{
        this.sid = id;
        this.name = name;
        this.yesterday = yesterday;
        this.today = -1;
        this.highest = yesterday;
        this.current = yesterday;
        this.lowest = yesterday;
	}
    //股票ID
    private string sid;
    //股票名
    private string name;
    //昨日股价
    private double yesterday;
    //今日股价 
    private double today;
    //最高
    private double highest;
    //最低
    private double lowest;
    //当前股价
    private double current;
    //浮动
    private string range;
    /// <summary>
    /// 获取当前股价
    /// </summary>
    /// <returns></returns>
    public double GetCurrent()
    {
        return current; 
    }
    /// <summary>
    /// 获取昨日股价
    /// </summary>
    /// <returns></returns>
    public double GetYesterday()
    {
        return yesterday;
    }
    /// <summary>
    /// 获取今日股价
    /// </summary>
    /// <returns></returns>
    public double GetToday()
    {
        return today;
    }
    /// <summary>
    /// 获取最高股价
    /// </summary>
    /// <returns></returns>
    public double GetHighest()
    {
        return highest;
    }
    /// <summary>
    /// 获取最低股价
    /// </summary>
    /// <returns></returns>
    public double GetLowest()
    {
        return lowest;
    }
    /// <summary>
    /// 获取浮动值
    /// </summary>
    /// <returns></returns>
    public string GetRange()
    {
        return range;
    }
    public void SetRange(string range)
    {
        this.range = range;
    }
    /// <summary>
    /// 设置当前股票价格
    /// </summary>
    /// <param name="current">当前股指</param>
    public void SetCurrent(double current)
    {
        //计算涨幅
        double range = (current - this.yesterday ) / this.yesterday ;
        //如果涨幅超过10%
        if (range > 0.1)
        {
            current = Math.Round(1.1 * this.yesterday * 100) / 100.0;
        }
        //如果跌幅超过10%
        if (range < -0.1)
        {
            current = Math.Round(0.9 * this.yesterday * 100) / 100.0;
        }
        this.current = current;
        //尚未开盘时,利用第一次的current设置开盘股价
        if (this.today == -1)
        {
            this.today = current;
        }
        //根据涨跌形势设置今日股价
        if (this.current > this.highest)
        {
            this.highest = this.current;
        }
        else if (this.current < this.lowest)
        {
            this.lowest = this.current;
        }
        //
        this.range = range.ToString("p");
    }
}

        xmlhttp.js          

        xmlhttp.js,自定义的MyXMLHttpRequest"类",主要负责和服务端的交互:

// 使用封装方法的人只关心http的请求方法,url地址,数据,成功和失败的回调方法
// 类的构造方法,主要职责是新建XMLHttpRequest对象
var MyXMLHttpRequest = function(){
    var xmlhttprequest;
    if(window.XMLHttpRequest){
        xmlhttprequest = new XMLHttpRequest();
        if(xmlhttprequest.overrideMineType){
            xmlhttprequest.overrideMineType("text/xml");
        }
    }else if (window.ActiveXObject) {
        var activeName = ["XSXML2.XMLHTTP","Microsoft.XMLHTTP"];
        for (i = 0; i < activeName.length; i++) {
            try {
                xmlhttprequest = new ActiveXObject(activeName[i]);
                break;
            } catch (e) { 
                
            }
        }
    }
    if (xmlhttprequest == undefined || xmlhttprequest == null) {
        alert("xmlhttprequest对象创建失败!");
    }else{
        this.xmlhttp = xmlhttprequest;
    }
}
// 用户发送请求的方法
MyXMLHttpRequest.prototype.send = function(method,url,data,callback,failback){
    if (this.xmlhttp != undefined || this.xmlhttp != null) {
        method = method.toUpperCase();
        if (method != "GET" && method != "POST") {
            alert("HTTP请求方法必须是GET或POST");
            return ;
        }
        if (url == undefined || url == null) {
            alert("http请求地址必须设置");
            return;
        }
    
        var tempxmlhttp = this.xmlhttp;
        tempxmlhttp.onreadystatechange = function(){
            if (tempxmlhttp.readyState == 4) {
                if (tempxmlhttp.status == 200) {
                    var responseText = tempxmlhttp.responseText;
                    var responseXML = tempxmlhttp.responseXML;
                    if (callback == undefined || callback == null) {
                        alert("没有设置处理数据正确返回的方法");
                        alert("返回的数据:" + responseText);
                    }
                    else{
                        callback(responseText,responseXML);
                    }
                }else {
                    if (failback == undefined || failback == null) {
                        alert("没有设置处理数据返回失败的处理方法");
                        alert("Http响应码信息:" + tempxmlhttp.status + ",响应码文本信息:" + tempxmlhttp.statusText)
                        return ;
                    }else{
                        failback(tempxmlhttp.status,tempxmlhttp.statusText);
                    }
                }
            }
        }
        // 解决缓存的转换
        if (url.indexOf("?") >= 0) {
            url = url + "&t=" + (new Date()).valueOf();
        }else{
            url = url + "?t=" + (new Date()).valueOf();
        }
        // 解决跨域问题
        if (url.indexOf("http://") >= 0) {
            url.replace("?","&");
            url = url + "Proxy?url=";
        }
        this.xmlhttp.open(method,url,true);
    
        // 如果是POST方式,需要设置请求头
        if (method == "POST") {
            this.xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        }
        this.xmlhttp.send(data);
    }else{
        alert("XMLHttpRequest对象创建失败,无法发送数据.");
    }
}
MyXMLHttpRequest.prototype.abort = function(){
    this.xmlhttp.abort();
}

        Handler.aspx

        一般处理文件Handler.ashx,用于处理客户端的请求:

<%@ WebHandler Language="C#" Class="Handler" %>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Threading;
//StringBuilder所在命名空间
using System.Text;

public class Handler : IHttpHandler {
    //定义股票字典
    private Dictionary<string, Stock> stock;
    private System.Timers.Timer timer;
    /// <summary>
    /// 响应客户端请求
    /// </summary>
    /// <param name="context">请求信息</param>
    public void ProcessRequest (HttpContext context) {
        context.Response.ContentType = "text/html;charset=UTF-8";
        //Response.ContentType = "text/html;charset=UTF-8";
        初始化数据
        Init();
        //转换为json字符串
        Thread.Sleep(200);
        StringBuilder builder = new StringBuilder();
        builder.Append("({");
        //stockid数组
        string[] StockId = new string[stock.Count];
        //获取股票ID
        for (int i = 0; i < stock.Count; i++)
        {
            StockId[i] = stock.ElementAt(i).Key.ToString();
        }
        //根据股票ID 得到股票,拼接字符串
        for (int i = 0; i < stock.Count; i++)
        {
            string sid = StockId[i];
            Stock tempStock = stock[sid];
            builder.Append(sid).Append(":{yes:").Append(tempStock.GetYesterday()).Append(",tod:").Append(tempStock.GetToday()).Append(",high:").Append(tempStock.GetHighest()).Append(",low:").Append(tempStock.GetLowest()).Append(",cur:").Append(tempStock.GetCurrent()).Append(",ran:'").Append(tempStock.GetRange()).Append("'}");
            //每个项后面再添加“,”
            if (i < stock.Count)
            {
                builder.Append(",");
            }

        }
        //尾部添加})
        builder.Append("})");
        //回复响应
         context.Response.Write(builder);
    }
    
    /// <summary>
    /// 初始化配置数据
    /// </summary>
    private void Init()
    {
        //新建四支股票
        Stock szzs = new Stock("300001", "上证指数", 300);
        Stock pfyh = new Stock("600000", "浦发银行", 25);
        Stock gsyh = new Stock("601398", "工商银行", 6.5);
        Stock zgsy = new Stock("601857", "中国石油", 19.1);
        //设定股票字典
        stock = new Dictionary<string, Stock>();
        //添加股票
        stock.Add("300001", szzs);
        stock.Add("600000", pfyh);
        stock.Add("601398", gsyh);
        stock.Add("601857", zgsy);
        //设置计时器参数,不要太大
        timer = new System.Timers.Timer(50);
        timer.Enabled = true;
        //执行计时器函数theout
       Random rdm = new Random();
        //每次只去一个,防止循环执行获取随机数
       double mdr = rdm.NextDouble();
        //timer的振荡事件,采用匿名函数方式执行
        timer.Elapsed += delegate(object source, System.Timers.ElapsedEventArgs e)
        {
            //股票变动范围
            //上涨浮动
            double sz = mdr * 30;
            double pf = mdr * 0.5;
            double gs = mdr * 0.1;
            double zg = mdr * 0.3;
            //下跌浮动
            if (mdr > 0.5)
            {
                sz = 0 - sz;
            }
            if (mdr > 0.5)
            {
                pf = 0 - pf;
            }
            if (mdr > 0.5)
            {
                gs = 0 - gs;
            }
            if (mdr > 0.5)
            {
                zg = 0 - zg;
            }
            //当前股票价格
            szzs.SetCurrent(Math.Round((szzs.GetCurrent() + sz) * 100) / 100.0);
            pfyh.SetCurrent(Math.Round((pfyh.GetCurrent() + pf) * 100) / 100.0);
            gsyh.SetCurrent(Math.Round((gsyh.GetCurrent() + gs) * 100) / 100.0);
            zgsy.SetCurrent(Math.Round((zgsy.GetCurrent() + zg) * 100) / 100.0);
        };
       
    }
    /// <summary>
    /// 实现接口自带的函数
    /// </summary>
    public bool IsReusable {
        get {
            return false;
        }
    }

}

        refresh.html

        refresh.html,用于发送更新股票信息的请求:

<!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>
    <title></title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <style type="text/css">
        #tooltip{
            display:none;
            position:absolute;
            border:1px solid black;
            background-color: white;
            z-index: 99;
            width:135px;
        }
    </style>
    <script src="Scripts/xmlhttp.js" type="text/javascript"></script>
    <script type="text/javascript"> 
            var xmlhttp;
            var stocks;
            var yesNode;
            var todNode;
            var highNode;
            var lowNode;
            var curNode;
            var ranNode;
            var tooltipNode;
            var tooltipSid;
            //获取tooltip下所有节点并交互
            function show() {
                // 获取tooltip相关的各个节点
                yesNode = document.getElementById('yes');
                todNode = document.getElementById('tod');
                highNode = document.getElementById('high');
                lowNode = document.getElementById('low');
                curNode = document.getElementById('cur');
                ranNode = document.getElementById('ran');
                tooltipNode = document.getElementById('tooltip');
                // 与服务端进行交互,获取到股票的最新消息
                getStock();
                // 以后每隔两秒再和服务端交互一次
                setInterval(getStock, 5000);
            }

            // 与服务端进行交互,获取到股票的最新消息
            function getStock() {
                // 假如xmlhttp存在,则将上一次交互终止掉(防止两个交互返回的数据相互覆盖)
                if (xmlhttp) {
                    xmlhttp.abort();
                }
                // 利用XMLHttpRequest对象和服务器进行交互
                xmlhttp = new MyXMLHttpRequest();
                xmlhttp.send('GET', 'Handler.ashx', '', callback, failback);
            }
            function callback(responseText, responseXML) {
                try {
                    // 将服务端返回的JSON数据转换成js中的对象
                    stocks = eval(responseText);
                    // 更新ToolTip内容
                    updateToolTip();
                    // 遍历所有的股票
                    for (var sid in stocks) {
                        var spanNode = document.getElementById(sid);
                        // 获取某一只股票的昨天收盘价和当前价
                        var stock = stocks[sid];
                        var cur = stock.cur;
                        var yes = stock.yes;
                        // 将当前价设置到span的节点里面
                        spanNode.innerHTML = cur;
                        // 根据当前价格设置span中的文本是红色还是绿色
                        if (cur >= yes) {
                            spanNode.style.color = 'red';
                        } else {
                            spanNode.style.color = 'green';
                        }
                    }
                } catch (exception) {
                    alert('解析服务器数据失败,错误内容为:' + exception.toString());
                }
            }
            function failback(status, statusText) {
                alert('回调函数失败:'+ statusText);
            }
            // 显示弹出框方法
            function showToolTip(aNode, event) {
                // 得到对应的股票代码
                tooltipSid = aNode.parentNode.getElementsByTagName('span')[0].id;
                // 更新ToolTip内容
                updateToolTip();
                var myevent = window.event || event;
                var mouseX = myevent.clientX;
                var mouseY = myevent.clientY;
                tooltipNode.style.left = mouseX + 5 + 'px';
                tooltipNode.style.top = mouseY + 5 + 'px';
                tooltipNode.style.display = 'block';
            }
             隐藏弹出框方法
            function clearToolTip() {
                tooltipNode.style.display = 'none';
                tooltipSid = undefined;
            }
            // 更新tooltip中的内容
            function updateToolTip() {
                if (tooltipSid) 
                {
                    // 当前股票的具体信息对象
                    var stock = stocks[tooltipSid];
                    // 设置昨收
                    var yes = stock.yes;
                    yesNode.innerHTML = yes;
                    // 设置今开
                    var tod = stock.tod;
                    todNode.innerHTML = tod;
                    if (tod >= yes) {
                        todNode.style.color = 'red';
                    } else {
                        todNode.style.color = 'green';
                    }
                    // 设置最高
                    var high = stock.high;
                    highNode.innerHTML = high;
                    // 设置最低
                    var low = stock.low;
                    lowNode.innerHTML = low;
                    if (low >= yes) {
                        todNode.style.color = 'red';
                    } else {
                        todNode.style.color = 'green';
                    }
                    // 设置当前价格和涨幅
                    var cur = stock.cur;
                    curNode.innerHTML = cur;
                    var ran = stock.ran;
                    ranNode.innerHTML = ran;
                    if (cur >= yes) {
                        curNode.style.color = 'red';
                        ranNode.style.color = 'red';
                    } 
                    else 
                    {
                        curNode.style.color = 'green';
                        ranNode.style.color = 'green';
                    }
                }
            }
    </script>
</head>
<body οnlοad="show()">
<!--每支股票各占一个div-->
    <div>
    <a href="#" οnmοuseοver="showToolTip(this,event)" οnmοuseοut="clearToolTip()" >上证指数:</a> 
    <span id="300001"></span>
 </div>
    <div>
    <a href="#" οnmοuseοver="showToolTip(this,event)" οnmοuseοut="clearToolTip()" >浦发银行:</a>
    <span id="600000"></span>
</div>
    <div>
    <a href="#" οnmοuseοver="showToolTip(this,event)" οnmοuseοut="clearToolTip()" >工商银行:</a>
    <span id="601398"></span>
</div>
    <div>
    <a href="#" οnmοuseοver="showToolTip(this,event)" οnmοuseοut="clearToolTip()" >中国石油:</a>
    <span id="601857"></span>
</div>
    <!--tooltip框-->
    <div id="tooltip">
        <div>昨收:<span id="yes"></span></div>
        <div>今开:<span id="tod"></span></div>
        <div>最高:<span id="high"></span></div>
        <div>最低:<span id="low"></span></div>
        <div>当前:<span id="cur"></span></div>
        <div>涨幅:<span id="ran"></span></div>
    </div>
</body>
</html>

        运行结果

        

        下载及预告

        因为是从NetBeans环境下的Java语言转换为VS2010下的C#语言,中间碰到不少问题,这些问题会在下篇博客介绍,另附本实例的代码下载地址:http://download.csdn.net/detail/lidaasky/4927691

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值