天气预报的RSS闲置太久了,很早就想在页面上做个天气预报的东东,用JS解析,正好趁这几天把这个给解决了。编码的问题依然弄了很久,上次说的FSO可以写UTF-8文件实际上是错误的,FSO可以写Unicode文件,但是不能写UTF-8文件。Unicode与UTF-8两者还是不同的,具体区别请看这里:UTF-8 and Unicode FAQ

对于AJAX,顺便推荐HotHeart的几篇上手好文(均被蓝色理想转载):
AJAX初体验之上手篇
AJAX初体验之实战篇——打造博客无刷新搜索
一个简单的AJAX请求类

AJAX的问题我就不多讲了,上面三篇文章已经讲的很清楚,并附有详尽的代码注释。中间只碰到一个IE和Firefox下JS执行结果不一致的问题,就是那个下拉列表框的问题。下拉列表中的选项并没有初始值,而是通过JS根据XML文件中的城市名称来创建的。在创建option标签时,最开始我使用的是这样的代码:

//city[i]数组中存放的是城市名称
//下拉列表的ID为city
var option=document.createElement(‘option’);
option.setAttribute(“value”,i+1);
option.innerText=city[i];
document.getElementById(‘city’).appendChild(option);

使用这样的代码的结果是,在IE下一切正常,而在Firefox下下拉列表所有选项均为空白,但每个空白选项有不同的值。于是尝试着用下面的代码,结果就正常了。忽然想到,不知道td标签是不是也是这样?

//city[i]数组中存放的是城市名称
//下拉列表的ID为city
var option=document.createElement(‘option’);
option.setAttribute(“value”,i+1);
option.appendChild(document.createTextNode(city[i]));
document.getElementById(‘c’).appendChild(option);

下面还是说说文字缓冲效果,就如公告栏中天气预报的效果(其实首页最近更新文章使用的效果更好^_^)。

如果做过flash的缓冲效果的话,应该比较好理解这个,因为原理都是差不多的,只不过实现的方式不一样。基本原理就是每次移动的速度为剩下距离的几分之一(比如1/3)因为距离在减少,所以每次移动的速度会越来越慢,伪程序如下:

int now; //当前位置
int target; //目标位置
int speed; //当前要移动的速度(距离)
int coefficient;//缓冲系数(要求大于1,一般选3到10)
Repeat: speed=(target-now)/coefficient;
now=now+speed;
if (now

我在实现的过程中,发现用scrollLeft总是出现一些莫名奇妙的问题(网上有很多都是用表格实现的,但是把表格替换成div就不行了-_-),后来结合CSS的特性,通过设置(显示块的)外层的overflow属性为hidden,改变显示块的margin-left属性来隐藏左侧的文字,已达到移动效果。具体实现代码如下(在IE 6.0和FIrefox 1.5下测试通过):

总长度:0;已经左移:0


var lines=line.length; //得到标题的条数

var temp=""; //显示过程中用到的字符串
var nextchar=-1; //下一个字符的位置
var nextline=0; //将要显示的标题在数组中的位置
var timeout=20; //显示两个字符之间的间隔时间
var remove=true; //当前行是否已经移除,true为已经移除

var lineLength = 0; //标题的长度
var moveSpeed = 0; //每次滚动的长度,像素
var leftLength=lineLength; //剩余长度
var nowLength=0; //已经移动的长度,即margin-left的值,为负数

//移动字符串
function move() {
moveSpeed=leftLength/10; //移动速度,这里的系数选的是10
nowLength=parseInt(nowLength)-moveSpeed; //由于往左移为负数,所以用减号
document.getElementById("news").style.marginLeft = nowLength+"px"; //改变显示块的margin-left属性值
leftLength=lineLength+parseInt(nowLength); //计算剩余长度
}

//控制字符的显示和移除
function animate(){
//如果一行已经显示完
if(temp==line[nextline]&temp.length==line[nextline].length){
//判断该行是否已经移除
if(remove){
//如果已经移除,准备显示下一条
lineLength =line[nextline].length*14;
nowLength=0;
if(nextline!=lines){
nextline++;
}
else{
nextline=0;
}
remove=false;
nextchar=-1;
document.getElementById("news").innerHTML=temp;
temp="";
}
//如果一行已经显示完,过两秒再执行下一步
setTimeout("nextstep()",2000);
}
//如果没有显示完,继续显示
else{
document.getElementById("news").style.marginLeft=0;
nextstep();
}
}

//如果没有显示完毕,则逐个字符地打印要显示的标题
//如果已经显示完毕,则逐减移除标题
function nextstep(){
//如果已经显示完,且没有移除
if(!remove){
//如果移动的距离接近(由于各方面误差的存在,只能选接近)标题长度,则判断已经移动完毕,并开始显示下一条
//这里选的误差像素为10,即移动距离比实际长度小于10时,则判断移除完毕
if(nowLength<(10-lineLength)){
remove=true;
temp="";
animate();
}
//如果没有移除完毕,则继续移除
else{
move();
document.getElementById("info").innerHTML="总长度:"+lineLength+";"+"已经左移:"+(-nowLength);
//下一次移除的时间是20毫秒以后
setTimeout("animate()",20);
}
}
//如果没有显示完,继续显示下一条
else{
nextchar++;
//计算显示下一个字符的时间间隔
timeout=(line[nextline].length-nextchar)*2;
//如果间隔太大,则规定一个最大值(因为字符串太长,显示第一个字符就要很长时间)
if(timeout>20)
timeout=20;
//当前要显示的内容为已经显示的内容加上下一个字符
temp+=line[nextline].charAt(nextchar);
//显示内容
document.getElementById("news").innerHTML=temp;
//设定显示下一个字符的时间
setTimeout("animate()",timeout);
}
}

//当页面加载时开始执行
window.onload=animate;
// -->

4 Comments

  1. 呵呵,如果学Ajax,看看我推荐的那三篇文章吧,文字缓冲效果的代码和详细注释在上面,自己看咯,不理解的随便问,呵呵

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.