上一節傳送門:《從案例中學習JavaScript》之實現對話效果(2)-- 附超簡單函數封裝技巧
本節涉及的知識點:
- div元素的 scrollHeight 和 clientHeight
- 開關變量的使用技巧
先聲明一下,這個案例是我臨時想出來的,當時覺得挺好玩的,所以開始做。算是一次嘗試吧,這不是講解真正的游戲開發,雖然H5是可以做游戲開發的,不過我還沒有去深入研究過。更何況這個案例比較基礎,還沒有用h5。
本案例的目的還是借由一個例子來講解JavaScript的知識點,沒別的意思。
繼續上一節的內容,本節實現效果:文字填滿對話框的時候,自動停住,需要用戶手動去點擊一下,然后進行下一段對話。
上一節的代碼中,我們將實現邏輯封裝成一個方法
var gameDialog = function(id,text,speed){
var innerBox = document.getElementById(id);
var text = text;
var len = text.length;
var timer = null;
var index = 0;
timer = setInterval(function(){
if(index == len){
clearInterval(timer);
}
innerBox.innerHTML += text.charAt(index++);
},speed);
}
函數的封裝極大地實現了代碼的復用,調用方法后,就可以執行我們的動畫效果了。但是,上一節中遺留了一個問題,比如我們傳入了過多的文字,就會出現這樣的情況:
gameDialog('content',
" 簡書客戶端中包含雜文時政、小說詩歌、電影評論、科技新聞,無論你的興趣如何構成,總能在這里找到志趣相投的作者與內容。"+
" 簡書始終致力于做中文世界最好的寫作與閱讀平臺,集結最優秀的創作者與文字愛好者,在嘈雜喧囂的網絡時代,重新沉淀并喚醒文字的力量。" +
" 簡書客戶端中包含雜文時政、小說詩歌、電影評論、科技新聞,無論你的興趣如何構成,總能在這里找到志趣相投的作者與內容。"+
" 簡書始終致力于做中文世界最好的寫作與閱讀平臺,集結最優秀的創作者與文字愛好者,在嘈雜喧囂的網絡時代,重新沉淀并喚醒文字的力量。"
,38);
我們輸入了這么長一段字符,原本的div肯定是裝不下的,但是因為我們給content部分的css樣式中添加了overflow : hidden,所以溢出的文字沒有顯示出來,但實際上它已經溢出了。
如圖:
在rpg游戲中,一般都是對話框被占滿后就停在那里了,然后需要玩家進行某些操作,比如按一個空格鍵,或者鼠標點擊一下,就清空掉當前的對話框,打印接下來的文字。
那么,如何判斷文字是否溢出了呢?這正是我們下一步要做的。
1. 判斷文字是否溢出
我們先把 overflow : hidden 這個屬性給去掉,看一下是什么效果。
可見,多出來的文字被擠下來了!
我們可以通過dom元素的scrollHeight屬性來獲取當前盒子的完整高度(包括溢出部分),于是在輪詢中動態打印出文字區域的scrollHeight。
代碼:
timer = setInterval(function(){
console.log(innerBox.scrollHeight);
if(index == len){
clearInterval(timer);
}
innerBox.innerHTML += text.charAt(index++);
},speed);
如圖,每溢出一行,scrollHeight就增加25px,也就是我們設定的行高。
回顧css文件:
.dialog .innerBox #content {
/*background: #E10482;*/
margin:2px 10px 10px 10px;
width:95%;
height:99%;
line-height:25px;
/*overflow: hidden;*/
font-size: 20px;
text-align:justify;
}
行高正好是25px。你可能會問,為什么第一次是從79到100,是21px而不是25px呢?
我們將圖放大:
content盒子的可見高度未必是文字行高的整數倍,這也就導致了第一次溢出是會有偏差的,如圖,第一次溢出部分的行高并沒有完全脫離content盒子,對不對?
這樣好理解了吧。
繼續。
我們已經可以動態獲取div盒子的完整高度了,那么是不是也可以獲取可視區域的高度呢?
當然可以啦,clientHeight就可以辦到!
console.log('文字可視區域的高度為:' + innerBox.clientHeight);
對了,剛才我們看到的79px正是該區域文字部分的可見高度。
那么顯而易見的,如何判斷文字是否溢出呢?
對,就是將兩個寬度進行比較,一旦發現scrollHeight超過了clientHeight,我們就認為文字溢出了。
上代碼:
timer = setInterval(function(){
console.log(box.scrollHeight + '=========' + box.clientHeight);
if(box.scrollHeight > box.clientHeight){
console.log('文字溢出啦!');
clearInterval(timer);//清除定時器
return; //返回
}
if(index == len){
clearInterval(timer);
}
box.innerHTML += text.charAt(index++);
},speed);
(為了避免和html中的innerBox混淆,我們將gameDialog方法里面的innerBox改為box。)
OK,我們再把溢出隱藏的屬性加上:
.dialog .innerBox #content {
margin:2px 10px 10px 10px;
width:95%;
height:99%;
line-height:25px;
overflow: hidden;
font-size: 20px;
text-align:justify;
}
2. 怎么少了一個字?
然后,我們將輪詢的代碼封裝起來,作為一個start函數存在,同時,給文字區域添加一個點擊事件來觸發下一段文字,代碼就成了這樣:
var gameDialog = function(id,text,speed){
var box = document.getElementById(id);
var text = text;
var len = text.length;
var timer = null;
var index = 0;
function start(){
box.innerHTML = '';
timer = setInterval(function(){
if(box.scrollHeight > box.clientHeight){
clearInterval(timer);
return;
}
if(index == len){
clearInterval(timer);
}
box.innerHTML += text.charAt(index++);
},speed);
}
start();
box.onclick = function(){
start();
}
細心的你也許已經發現了,這個代碼是有問題的。
看圖,第一段文字的末尾是這樣:
而第二段文字的開頭卻是這樣的:
沒錯,少了一個構成的“構”字。(不同電腦可能分辨率不同,在你的電腦上不一定是這個字)
這是為什么呢?
原來,我們在判斷溢出的時候,是用scrollHeight和clientHeight進行比較的,而要使scrollHeight > clientHeight,必然是在文字已經溢出的時候。
也就是說,
if(box.scrollHeight > box.clientHeight){
clearInterval(timer);
return;
}
當程序進入這一段邏輯的時候,文字就已經溢出了,不多不少,正好溢出一個字。
解決方法很簡單,我們只需要將這個多出來的字符保存下來,下一次執行start方法的時候,補上去就OK了。
var gameDialog = function(id,text,speed){
var box = document.getElementById(id);
var text = text;
var len = text.length;
var timer = null;
var index = 0;
var character = '';
function start(){
box.innerHTML = '';
timer = setInterval(function(){
if(box.scrollHeight > box.clientHeight){
//將溢出的那個字保存在下來
character = text.charAt(index - 1); //因為上一次已經 ++了,所以這里要減一
clearInterval(timer);
return;
}
if(index == len){
clearInterval(timer);
}
if(character){
box.innerHTML += character;
character = '';//重置該字符
}else{
box.innerHTML += text.charAt(index++);
}
},speed);
}
start();
box.onclick = function(){
start();
}
這樣就解決少一個字符的問題了。
3. 利用開關變量boolean值來判斷是否可以點擊
到目前為止,程序還存在一個bug,就是文字區域的點擊事件一直存在,也就是說,即便當前文字還在打印中,我們也可以觸發點擊事件,而事實上,我們希望在一段動畫結束后才允許我們點擊。
這時候就需要用到boolean值了,boolean就兩個狀態 true或者false,所以我習慣上把它稱為開關變量。
上代碼:
附上資源帖地址:http://www.lxweimin.com/p/19a7a16d66b4
本章結束 ...
剽悍一小兔,電氣自動化畢業。
參加工作后對計算機感興趣,深知初學編程之艱辛。
希望將自己所學記錄下來,給初學者一點幫助。
免責聲明: 博客中所有的圖片素材均來自百度搜索,僅供學習交流,如有問題請聯系我,侵立刪,謝謝。