This page looks plain and unstyled because you're using a non-standard compliant browser. To see it in its best form, please visit upgrade to a browser that supports web standards. It's free and painless.

Fillano's Learning Notes 會員登入 會員註冊

用HTML的marquee來製作的跑馬燈,會有一個問題,就是畫面會出現一段空白。

要避免這個問題,就必須用javascript搭配DHTML的方式來做出跑馬燈的效果來。

先定義一個基本的訊息輪播物件:

function messages () {
	this.msgQueue = new Array();//存放訊息的陣列
	this.msgInterval = 1;//訊息輪播的間隔
	this.msgCurrent = 0;//目前播放的訊息
	this.msgTarget = "";//顯示訊息的物件id
	this.intervalId = null;//用來存放interval或是timer的id,以便做出暫停的效果
	this.pauseState = 0;//存放播放的狀態,用來判斷是在播放或是暫停
}

messages.prototype.addMsg = function (msg) {//新增訊息到訊息陣列
	this.msgQueue.push(msg);
}

messages.prototype.getMsgInterval = function () {//取得訊息播放的間隔
	return this.msgInterval;
}

messages.prototype.setMsgInterval = function (interval) {//設定訊息播放的間隔
	this.msgInterval = interval;
}

messages.prototype.setMsgTarget = function (id) {//設定訊息播放的目標id
	this.msgTarget = id;
}

messages.prototype.getMsgTarget = function () {//取得訊息播放的目標id
	return this.msgTarget;
}

接著再延伸message物件,加入顯示及暫停等操作方法。

function dynamicMsg () {
	this.container = document.createElement("div");//訊息將在這個div中顯示
	this.roller1 = document.createElement("div");//用兩個div頭接尾做出不間斷播放的效果
	this.roller2 = document.createElement("div");
	this.currentPos = 0;//以下用來存放訊息移動的位置
	this.rollerTop = 0;
	this.rollerLeft = 0;
	this.rollerRight = 0;
	this.rollerBottom = 0;
}
dynamicMsg.prototype = new messages;//繼承messages物件

dynamicMsg.prototype.display = function (width, height, border, delay, color) {
	try{
		if (this.msgQueue.length == 0) throw "No message in queue!!!";
		if (this.msgTarget == "") throw "You must assign an object id for displaying messages!!!";
		var obj = document.getElementById(this.msgTarget);
		if (obj == null) throw "Object with the assigned id:"+this.msgTarget+" cannot be found!!!";
		var callobj = this;//把this指標存到變數,等一下才有辦法讓網頁的事件來使用
		obj.innerHTML = "";
		obj.appendChild(this.container);
		var img = document.createElement("img");//用一個透明的gif把container撐到指定的大小
		img.src = "images/blank.gif";
		img.height = height;
		img.width = width;
		img.border = "0";
		obj.appendChild(img);
		this.container.style.position = "absolute";//position必須設為absolute,clip才會發生作用
		this.container.style.width = width+"px";
		this.container.style.height = height+"px";
		this.container.style.border = "solid "+border+"px";
		this.container.style.background = color;
		this.container.style.overflow = "hidden";
		this.container.style.clip = "rect(0,"+width+","+height+",0)";
		this.container.innerHTML = "";
		this.container.onmousemove = function(){callobj.pause(1);};
		this.container.onmouseout = function(){callobj.pause(0);};
		var tmp = "";
		for (i=0;i<this.msgQueue.length;i++) {//把訊息陣列中的訊息取出,一則訊息一行來顯示
			tmp += this.msgQueue[i];
			if (i != this.msgQueue.length-1) {
				tmp += "<br>";
			}
		}
		this.roller1.style.top = "0px";
		this.roller1.innerHTML = "";
		this.roller1.innerHTML = tmp;
		this.roller1.style.position = "relative";
		this.container.appendChild(this.roller1);
		this.rollerTop = this.roller1.offsetTop;
		this.rollerLeft = this.roller1.offsetLeft;
		this.rollerRight = this.rollerLeft + this.roller1.offsetWidth;
		this.rollerBottom = this.rollerTop + this.roller1.offsetHeight;
		this.currentPos = 0;
		this.container.appendChild(this.roller2);
		this.roller2.innerHTML = "";
		this.roller2.innerHTML = tmp;
		this.roller2.style.position = "relative";
		this.roller2.style.top = "0px";
		this.msgInterval = delay;
		this.intervalId = window.setInterval(function(){callobj.rotate();},this.msgInterval*100);
	}
	catch (e) {
		alert(e);//顯示例外的訊息
	}
}

dynamicMsg.prototype.rotate = function () {//做出向上捲動的效果
	this.roller1.style.top = --this.currentPos + "px";
	this.roller2.style.top = this.currentPos + "px";
	if ((this.currentPos + this.roller1.offsetHeight) == 0) {
		this.currentPos = 0;
	}
}

dynamicMsg.prototype.pause = function (status) {//做出暫停/繼續播放的效果
	if (status == 1) {
		this.pauseState = status;
		clearInterval(this.intervalId);
		return;
	}
	if (status == 0) {
		this.pauseState = status;
		var callobj = this;
		this.intervalId = setInterval(function(){callobj.rotate();},this.msgInterval*100);
		return;
	}
}

使用的時候,需要用幾個步驟:

  1. 產生一個dynamicMsg物件實體
  2. 用addMsg方法加入要捲動的訊息(內含html的字串)
  3. 用setMsgTarget方法來指定要顯示的上層物件的id(字串,不是物件)
  4. 用display方法來顯示(傳入的參數依序為:寬、高、框的厚度、捲動頻率、背景顏色)
應讀者要求,以下是簡單的使用的範例,前面的程式也做了一點修改(2007/10/5):

var a = new dynamicMsg();
a.addMsg("產生一個dynamicMsg物件實體");
a.addMsg("用addMsg方法加入要捲動的訊息(內含html的字串)");
a.addMsg("用setMsgTarget方法來指定要顯示的上層物件的id(字串,不是物件)");
a.addMsg("用display方法來顯示(傳入的參數依序為:寬、高、框的厚度、捲動頻率、背景顏色)");
a.setMsgTarget("panel");
a.display(320,30,1,1,"#AABBCC");
a.container.style.fontSize = "12px";

有圖有真相:

dynamic message demo

為了方便開發者建立容易存取資料的類別,Xoops提供了兩個基礎類別:XoopsObject與XoopsObjectHanlder。

1. XoopsObject

XoopsObject提供了一些基本的屬性與方法,來建立存取物件內的變數。XoopsObject所使用的方法就是用一個工廠類別XoopsObjectHandler來負責XoopsObject的生成,並提供標準的資料庫存取方式。

基本上,$XoopsObject->vars這個屬性(一個關連陣列)會存放所有資料表欄位的資料。在使用前先要用initVar方法來初始化vars中的元素。他已經定義好了一些常數來指定變數的種類,還可以指定一些更詳細的變數設定,例如資料的長度等。接著可以用assignVar或是assignVars來指定變數的值。

XoopsObject會使用TextSanitizer類別來對變數的內容進一步處理,根據使用的狀況例如在變數有透過Get、Post、Cookie傳遞的狀況時,作一些額外的處理,過濾不合法的tags,另外還又針對bbcode還有avatar系統進來的語法作特別處理等等。

2. XoopsObjectHandler

其實這裡的方法都是空的(抽象方法,但是PHP4並沒有支援),使用他定義好的方法再來撰寫實際物件的工廠類別。這裡定義了四個方法:

  1. create
  2. get
  3. insert
  4. delete

使用create可以建立一個新的物件實體。使用get,以id為參數,可以從資料庫中取出物件的屬性,然後建立這個物件的實體。使用insert可以將物件存入資料庫中。使用delete可以從資料庫中刪除這個物件實體的資料。

如果你可以看到這篇文章,表示註冊過程已經順利完成。現在你可以開始blogging了!