ChinaStock全程解析
插件http://www.zeali.net/ffexts/chinastock/chinastock.xpi
调试以下部分,采用venkman
chrome://chinastock/content/detail.xul
:lol
[ 本帖最后由 faunus 于 2008-12-13 15:32 编辑 ] 入口函数:
=》chinastock_detail_init();
=》gZealChinaStock.m_prefs = XPComponent;
=》gZealChinaStock.initLogHandler();
=》stockstrs = gZealChinaStock.get_stockstrs();
//"000960,600291,600367,600196"
=》gZealChinaStock.parse_stockinfo(stockstrs);
=》zealParseRURL();
=》ElE('tradeDetailLink').href = 'javascript:chinastock_goto_with(\'http://bill.finance.sina.com.cn/bill/trade_item.php?stock_code=%stockfixid%\')';
=》ElE('tradeBigLink').href = 'javascript:chinastock_goto_with(\'http://bill.finance.sina.com.cn/bill/detail.php?bill_size=40000&stock_code=%stockfixid%\')';
=》sNamecache = "";
=》sNamecache = sNamecache.split("##");
//"!\x1A\xA1\xFD##\x7F4\xA1\xFD##\xA2\x1F\xD1U##\r\x1F;o"
=》switcherBox = ElE('stocklistswitcher');
=》for(var i=0;i<gZealChinaStock.m_stock_list.length;i++){
//4
=》if(i >= sNamecache.length){
=》sNamecache = "";
=》 if(sNamecache.length < 1) sNamecache = gZealChinaStock.m_stock_list.m_sFixid;
=》switcherBox.appendItem(gZealChinaStock.m_stock_list.m_sId+" ("+sNamecache+")",i);
=》}//end of forloop
=》sNamecache = null;
=》switcherBox.selectedIndex = detailPosToDealNow;
=》switcherBox = null;
=》chinastock_detail_switchpos();
//0
[ 本帖最后由 faunus 于 2008-12-8 22:21 编辑 ] 在DTD中,还可以声明一些称为Entity的东西,让DTD和XML文件使用。我们可以把Entity看作是一个常量,它有一定的值。在DTD中,Entity的声明语法为:〈!ENTITY entity-name entity-definition〉。例如:我们在DTD中声明〈!ENTITY PC "(#PCDATA)"〉 ,那么在后面的元素设定中,就可以使用这个Entity来代替“(#PCDATA)”这个字符串,如:〈!ELEMENT 作者 (#PCDATA)〉可以写成〈!ELEMENT 作者 &&PC;〉。引用Entity的时候,必须要在Entity名称前面加上“&&”符号,后面加上“;”符号。
gZealChinaStock对像
gZealChinaStock对像让Firefox插件有属性
为程序添加属性单。1。要启用Firefox或者说Mozilla的[属性,高级,或者说preferences ],必须提到如下三个:
nsIPrefService, nsIPrefBranch and nsIPrefBranch2.
注:nsIPref 被放弃了。
2。启用:
var pref =
Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService)
.getBranch("");
从而获得nsIPrefBranch 对象实例。
3。nsIPrefBranch 有如下 成对的函数:
针对:stringinteger boolean
getBoolPref(), setBoolPref();
getCharPref(), setCharPref();
getIntPref(),setIntPref();
setComplexValue(),getComplexValue();
4。存取:
var value = prefs.getBoolPref("accessibility.typeaheadfind"); // get a pref
prefs.setBoolPref("accessibility.typeaheadfind", !value); // set a pref
void getComplexValue(in string aPrefName, in nsIIDRef aType,
out nsQIResult aValue);
void setComplexValue(in string aPrefName, in nsIIDRef aType, in nsISupports aValue);
aType : nsISupportsString:处理宽字符的字符窜。
// prefs is an nsIPrefBranch
// Example 1: getting Unicode value
var value = prefs.getComplexValue("preference.with.non.ascii.value",
Components.interfaces.nsISupportsString).data;
// Example 2: setting Unicode value
var str = Components.classes["@mozilla.org/supports-string;1"]
.createInstance(Components.interfaces.nsISupportsString);
str.data = "some non-ascii text";
prefs.setComplexValue("preference.with.non.ascii.value",
Components.interfaces.nsISupportsString, str);
nsIPrefLocalizedString:处理宽字符的字符窜,但是也有特别情况,比如本地化。
extensions.myext.welcomemessage=Localized default value
pref("extensions.myext.welcomemessage", "chrome://myext/locale/defaults.properties");
var prefs = Components.classes["@mozilla.org/preferences-service;1"].
getService(Components.interfaces.nsIPrefService);
var branch = prefs.getBranch("extensions.myext.");
var value = branch.getComplexValue("welcomemessage",
Components.interfaces.nsIPrefLocalizedString).data;
Mozilla的解释:
The code in step 3 will read the default value from
chrome://myext/locale/defaults.properties when no user value is set,
and will behave exactly the same as if nsISupportsString was passed as aType otherwise.nsILocalFile :处理一般绝对目录。
nsIRelativeFilePref:处理操作系统特殊目录,业内人士应该都知道。
关于onreadystatechange应用
JavaScript来创建XMLHttpRequest类向服务器发送一个HTTP请求后,接下来要决定当收到服务器的响应后,需要做什么。这需要告诉HTTP请求对象用哪一个JavaScript函数处理这个响应。
可以将对象的onreadystatechange属性设置为要使用的JavaScript的函数名,如下所示:
[*]xmlhttp_request.onreadystatechange =FunctionName;
FunctionName是用JavaScript创建的函数名,注意不要写成FunctionName(),当然我们也可以直接将JavaScript代码创建在onreadystatechange之后,例如: [*]xmlhttp_request.onreadystatechange = function(){[*]// JavaScript代码段[*]};
在这个函数中。首先要检查请求的状态。只有当一个完整的服务器响应已经收到了,函数才可以处理该响应。XMLHttpRequest 提供了readyState属性来对服务器响应进行判断。
readyState的取值如下:
0 (未初始化)
1 (正在装载)
2 (装载完毕)
3 (交互中)
4 (完成)
所以只有当readyState=4时,一个完整的服务器响应已经收到了,函数才可以处理该响应。具体代码如下: [*]if (http_request.readyState == 4)[*]{[*]// 收到完整的服务器响应[*]}[*]else[*]{[*]// 没有收到完整的服务器响应[*]}
当readyState=4时,一个完整的服务器响应已经收到了,接着,函数会检查HTTP服务器响应的状态值。完整的状态取值可参见W3C文档。当HTTP服务器响应的值为200时,表示状态正常。
在检查完请求的状态值和响应的HTTP状态值后,就可以处理从服务器得到的数据了。有两种方式可以得到这些数据:
(1)以文本字符串的方式返回服务器的响应
(2)以XMLDocument对象方式返回响应 gZealChinaStock.m_ajaxRequest.open( "GET", 'http://finance.sina.com.cn/realstock/company/'+curStock.m_sFixid+'/nc.shtml' );
http://finance.sina.com.cn/realstock/company/sz000960/nc.shtml
var picpat = new RegExp('<td width="50%" align="center"><img src="(*\\.sinaimg\\.cn/cj/realstock/company/]http://i*\\.sinaimg\\.cn/cj/realstock/company/'+curStock.m_sFixid+'/[^\\.]+\\.jpg)" border="0" /></td>','g');
<td width="50%" align="center"><img src="http://i1.sinaimg.cn/cj/realstock/company/sz000960/1228840455_uBmBKl.jpg" border="0" />
<td width="50%" align="center"><img src="http://i0.sinaimg.cn/cj/realstock/company/sz000960/1228840455_JOdfdq.jpg" border="0" /> 下面的这些配置可以使开发调试扩展更加方便。
查看 Editing Configuration Files 了解更多信息。
下面的这些选项,默认是不会在about:config中列出来的,所以需要手工添加它们。
browser.dom.window.dump.enabled = true. 允许使用dump() 命令输出信息到标准控制台
-792 log: function(nLevel, sMsg) {
-793 if (!this.m_debug) return;
794
-795 var rDate = new Date();
-796 if (this.m_csk_logger) {
-797 this.m_csk_logger.log(nLevel, rDate.getTime()+': '+sMsg);
798 } else {
-799 window.dump(rDate.getTime()+': '+sMsg+"\n");
800 } var globalStockBase = {
lta: 0.0,
lastfive: 0.0,
flag: 0, //判断标志
totalcapital: 0.0, //总股本
currcapital: 0.0, //流通股本
curracapital: 0, //流通A股
currbcapital: 0, //流通B股
currbLast: 0.00, //流通B股当前价
curraLast: 0.00, //流通A股当前价
exchangerate: 0.00 //汇率
};
var fullcode="sz000960";
var stockname="锡业股份";
var chart_img_alt = "锡业股份 000960 行情图";
var lta = 25711.0581;
var lastfive = 85.167503;
var flag = 1; //判断标志
var totalcapital = 65072.032; //总股本
var currcapital = 31502.5817; //流通股本
var curracapital = 0; //流通A股
var currbcapital = 0; //流通B股
var currbLast = 0.00; //流通B股当前价
var curraLast = 0.00; //流通A股当前价
var exchangerate = 0.00; //汇率
var detailcache = new Array();
var relative_stocks_sz000960= {sh600459 : '',sh600432 : '',sh600456 : '',sz000612 : '',sz000751 : '',sz000831 : ''};
var corr_future = ['cu0901'];
---code here---
-158 for(var basekey in globalStockBase){
-159 var stockpattern = new RegExp('var '+basekey+' = ([^;]+);','g');
-160 var matches = stockpattern.exec(gZealChinaStock.m_ajaxRequest.responseText);
-161 if(null != matches && matches.length >= 2){
-162 globalStockBase = matches;
-163 gZealChinaStock.log(5, 'getshtml bingo for '+stockpattern+' = '+globalStockBase);
164 }
165 else{
-166 bmatched = false;
167 }
[ 本帖最后由 faunus 于 2008-12-10 22:46 编辑 ]
setTimeout和setInterval的使用
这两个方法都可以用来实现在一个固定时间段之后去执行JavaScript。不过两者各有各的应用场景。方 法实际上,setTimeout和setInterval的语法相同。它们都有两个参数,一个是将要执行的代码字符串,还有一个是以毫秒为单位的时间间隔,当过了那个时间段之后就将执行那段代码。
不过这两个函数还是有区别的,setInterval在执行完一次代码之后,经过了那个固定的时间间隔,它还会自动重复执行代码,而setTimeout只执行一次那段代码。
虽然表面上看来setTimeout只能应用在on-off方式的动作上,不过可以通过创建一个函数循环重复调用setTimeout,以实现重复的操作:
File: settimeout_setinterval.js
showTime();
function showTime()
{
var today = new Date();
alert("The time is: " + today.toString());
setTimeout("showTime()", 5000);
}
一旦调用了这个函数,那么就会每隔5秒钟就显示一次时间。如果使用setInterval,则相应的代码如下所示:
File: settimeout_setinterval2.js
setInterval("showTime()", 5000);
function showTime()
{
var today = new Date();
alert("The time is: " + today.toString());
}
这两种方法可能看起来非常像,而且显示的结果也会很相似,不过两者的最大区别就是,setTimeout方法不会每隔5秒钟就执行一次showTime函数,它是在每次调用setTimeout后过5秒钟再去执行showTime函数。这意味着如果showTime函数的主体部分需要2秒钟执行完,那么整个函数则要每7秒钟才执行一次。而setInterval却没有被自己所调用的函数所束缚,它只是简单地每隔一定时间就重复执行一次那个函数。
如果要求在每隔一个固定的时间间隔后就精确地执行某动作,那么最好使用setInterval,而如果不想由于连续调用产生互相干扰的问题,尤其是每次函数的调用需要繁重的计算以及很长的处理时间,那么最好使用setTimeout。
---code here---
if(bmatched) setTimeout(chinastock_detail_getinfo,20);