顯示具有 JavaScript 標籤的文章。 顯示所有文章
顯示具有 JavaScript 標籤的文章。 顯示所有文章

2014年1月3日 星期五

取得 Google Maps 的觸發事件

當可以在頁面上顯示地圖之後,接著會更想瞭解如何收集使用者的操作行為,這時候就需要取得使用者在地圖上的任何動作的觸發事件。而 Google Maps 允許我們存取以下使用者的動作:

click:當用滑鼠點選地圖時會被觸發。但如果是點在地圖標記上(Marker)則不會觸發。
dblclick:用滑鼠連續點選地圖兩次時被觸發。但如果畫面上也有攔截 click 事件,則 click 事件會優先被觸發。經實作後發現,當地圖上同時攔截 click 與 dblclick 事件時,只會取得 click 事件。
mouseup:滑鼠點下去,被放開的那一刻觸發。
mousedown:滑鼠點下去被觸發。
mouseover:滑鼠移到地圖上時被觸發。
mouseout:滑鼠離開地圖時被觸發。

接下來如何把這些事件與程式綁在一起呢?可以透過下面的語法:

2014年1月2日 星期四

ASP.Net 實作 Google Maps Ver.3

看了  Google Maps JavaScript API 出到第三版,發現以前使用 Google Map 來開發都需要申請 API 金鑰,在第三版之後就不需要了。聽起來便民了許多,而且看網站上所介紹的範例,也還蠻簡單的,於是就想用 ASP.Net 練習一下,但我什麼跑不出來,空白一片。

2013年12月26日 星期四

JavaScript 使用 Math.random 取得隨機變數值

一個亂數值夠不夠亂,分佈的是否平均,是決定機率值公不公平的關鍵。

在 JavaScript 裡要產生一個亂數,首推的就是 Math.random() 這函數了。而這個函數值所分佈的範圍是 0 ~ 0.9999... 之間,可以用一個數學式來表示   0≦ X < 1

2012年6月15日 星期五

preventDefault 與 returnValue



記得剛開始認識 「event.preventDefault();」 的時候,感覺在程式裡面有機會把它找幾個位置擺放,是一件很幸福的事情,這種感覺就好像能在家裡擺個花瓶是一樣的(沒多大用處,就好看而已)。沒多久,我又認識了「event.returnValue=false;」,雖然不缺,但內心深處還是有個寂寞的影子,於是我踰越了道德的那條線。表面上看似春風如意,直到有一天,我發現 IE容不下「event.preventDefault();」,FireFox 與「event.returnValue=false;」互為水火,讓我開始重新思考,誰才是我最後的選擇。後來我發現,探究到最核心,其實,只有回到最初錯誤的開始:「return false;」,才能真正見容於 IE 與 FireFox !

多年後的今天,我終於領悟,從頭到尾,愛我與接受我的,只有 Chrome 與 Opera,這些日子他們一直都在,一直都在我身邊不離不棄,只能說:人間自有真情在啊!!

語法/瀏灠器支援情況IEFireFoxChromeOpera
event.preventDefault(); X
event.returnValue=false; X
return false;

瀏灠器測試版本:
IE:8.0.7601.17514
FireFox:13.0
Chrome:19.0.1084.56
Opera:11.62

Ref:
01:解决firefox不支持window.event.returnValue = false
02:JavaScript 中的attachEvent与addEventListener方法
03:createEvent-dispatchEvent and preventDefault example

2012年3月7日 星期三

自動調整 iframe 高度


以前使用 iframe 時,總是無可避免當 iframe 裡的資料過長時,就得透過 scroll bar 來捲動,如果刻意將 iframe 的高度設很高,則又擔心有些時候會太浪費網頁版面,如果能夠讓 iframe 依據內容而調整高度,似乎是個比較有彈性的作法。


關於這個想法,在網路上找到兩種類似的作法。


一、Lost-In-Code
在這個網站,提供了一個方便你外掛的 javascript,jquery.autoheight.js。日後只需要將 iframe 的 class 設定為 『autoHeight』,就能夠自動調整 iframe 的高度了。雖然他取名為 jquery,但仔細去觀察 jquery.autoheight.js 這隻程式,裡面並沒有用到 jquery 的語法。作者雖然在他的網頁上註明要引用 jquery 函式庫,但我發現,不引用也是可以的。但實際操作上,自己有遇到一個問題,就是去點選瀏覽器右上方的「最大化/往下還原」時,因為不會重算父親的高度而因此破功。所以自己再加上 $(window).resize() 去重算就可以解決。也因為如此,我還是把 jquery 引用進去好了。


    <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
    <script src="Scripts/jquery.autoheight.js" type="text/javascript"></script>
    <script>
        $(function () {
            //攔 resize 事件,並呼叫 jquery.autoheight.js 的 doIframe() 方法
            $(window).resize(function () {               
                doIframe();                
            });
        });
    </script>

<body>
    <form id="form1" runat="server">
    <div>
    <div class="dean_ch">這是父親頁面</div>
    以下是 iframe <br />
    <iframe width="100%" src="FrameA.aspx"  scrolling="auto" frameborder="0"  class="autoHeight" id="ifA"></iframe>    
    </div>
    </form>
</body>

另外 『91』與 『梅問題』 也針對這方法做了介紹,可以參考。


二、Phine Solutions
這個方式適用於每個 iframe,自己去控制呼叫者(父親)所設定的高度。此外,為了處理「最大化/往下還原」的問題,也加上 $(window).resize() 的處理。

    <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
    <script>
        function DoAdjHeight() {
            var theFrame = $("iframe", parent.document.body);
            theFrame.each(function () {
                $(this).height($(document.body).height() + 35);
            });
        }
        $(function () {

            DoAdjHeight();

            $(window).resize(function () {
                DoAdjHeight();
            });


        });
    </script>



以上兩種方法,發現它們都會在程式裡面加上一個特別數字 35,似乎是一種最適切的高度位置吧!自己曾經刻意將瀏覽器的縮放比例任意變大變小,的確在有些情況,上述的兩種方式也會突然冒出 scroll bar ,但這種特殊的操作行為,或許可以當成例外,畢竟會這樣使用的人不多;但果真要去處理的話,可能就要去調整這特別的數字。目前,我將他設定為100,幾乎任何縮放比例都可以顯示正常。所以這地方,如果有需要時才去調整這參數會比較適當。

測試程式下載 】
於測試程式中,TestA.aspx 是使用 Lost-In-Code 的方法,而 TestB.aspx 則是使用 Phine Solutions。



參考:
01:http://www.lost-in-code.com/programming/jquery-auto-iframe-height/ (lost-in-code)
02:http://www.dotblogs.com.tw/hatelove/archive/2010/08/12/javascript-iframe-autoheight.aspx (91)
03:http://www.phinesolutions.com/use-jquery-to-adjust-the-iframe-height.html (Phine Solutions)
04:http://www.minwt.com/?p=2425

2012年2月23日 星期四

javascript 上的 reverse()


字串的反轉,在 SQL、C# 使用 Reverse 就可以輕鬆完成。但同樣的需求發生在 javascript 上,卻有點不一樣。在 javascript 裡,並非不支援 Reverse,而是 Reverse 的對象不是字串,而是陣列。所以在使用上,就不能直接呼叫使用,必須稍微做些調整。

看了網路上所介紹到方法,大約可分成兩類:

第一種:透過迴圈方式,將字串由後往前抓一遍
String.prototype.reverse = function() {
    var s = "";
    var i = this.length;
    while (i>0) {
        s += this.substring(i-1,i);
        i--;
    }
    return s;
}

var s="paladin";
alert(s.reverse());
 

第二種:把字串轉成陣列,並將陣列反轉後再組成字串
String.prototype.reverse=function(){return this.split("").reverse().join("");}

var s="paladin";
alert(s.reverse());

個人還蠻喜歡第二種寫法,太簡潔了。日後只需要用:


alert("paladin".split('').reverse().join(''));

就可以把名字倒過來寫了。

此外,還有一個很少使用到的 html 標籤 <bdo>,它可以不透過 javascript 就直接將字串反轉,甚至 <bdo> 標籤裡頭所包含的物件呈現順序也是可以自行設定為由右至左或由左至右,只需去設定 dir 屬性即可(rtl:由右至左,ltr:由左至右)。
<div><bdo dir="rtl">paladin <img alt="1" /> <img alt="2" /></bdo></div>
參考:
01:Reverse-a-txet
02:How do you reverse a string in place in JavaScript?
03:HTML <bdo> Tag

2012年1月4日 星期三

判斷輸入的數值是否是到小數點第二位

如果想要去檢查使用者所輸入的數字,是否真的乖乖符合「到小數點第二位」的要求,使用 javascript 來檢查,算是蠻直覺的。在程式設計師俱樂部,找到一篇很簡潔的寫法,主要是透過 Regular Expression 來完成。


function checkDecimal2(v_compare) 
{    
    re =/^[0-9]+(\.[0-9]{1,2})?$/;
    if(!re.test(v_compare )) 
     { 
        return false
     }
     
     return true; 
}

根據石頭閒語裡所介紹的 Regular Expression(寫的超級詳細的,很值得多讀幾遍,找時間拿回家護貝裱框好了),節錄出有關判斷小數點第二位的語法介紹如下:


 /^[0-9]+(\.[0-9]{1,2})?$/


  1. ^
    寫在 pattern 第一個位置時,表示其後一符號必須出現在字串開頭的位置。寫在 pattern 中間位置時則為否定之意,表示字串中不可有 ^ 之後一符號的內容。
  2. $
    寫在 pattern 最後一個位置時,表示其前一符號必須出現在字串尾端的位置。寫在 pattern 中時無特別意義。
  3. [ ]
    表示字串含有括號中任一字元的內容。可以 - 表示一組連續字元,例如 /[a-z]/, /[0-9]/ 。注意, [] 僅代表一個字元,例如 /[abc]/ 表示 'a' 或 'b' 或 'c' ,而不是 'abc' 。
  4. +
    表示字串中有 1 到無數個其前一符號的內容。
  5. ( )
    表示一個 sub pattern ,符合 sub pattern 的字串內容會被存放在匹配陣列中,並依序指派數字代表此 sub pattern 。可以此數字在 pattern 的其他地方引用內容,例如 /The h([0-9]) means Title (\1)/ 表示第 1 個 sub pattern 是 0 到 9 的任一字元,而 \1 表示匹配的內容。故 'The h1 means Title 1', 'The h2 means Title 2' 到 'The h9 means Title 9' 符合規則。
  6. \
    表示轉義 (escaping) ,將其後的字元視為一般字元。例如要表示字串中含有 '/' 字元時,就必須寫作 /\// 。
  7. { }
    表示前一符號在字串中的重覆次數。例如 /A{2}/ 表示 'A' 重覆兩次 (即 'AA') ;/A{2,}/ 表示字串含有 2 到無數多個 'A' ;/A{2,5}/ 表示含有 2 到 5 個 'A' 。
  8. ?
    表示字串中有 0 到 1個其前一符號的內容。

瞭解 Regular Expression 所代表的意思之後,如果要寫「判斷輸入的數值是否是到小數點第一位」,就很簡單了,只要修改一個地方就可以,至於要到小數點第 N 位,依此類推就是了。

/^[0-9]+(\.[0-9]{1,1})?$/

如果您一時技癢,可以到 Rubular 去解解饞。該網站提供 Regular Expression 的線上測試服務。


參考:
01:請問如何限制使用者如果有輸入小數點,最多只能輸2位(程式設計師俱樂部)
02:Regular Expression (RegExp) in JavaScript(石頭閒語)
03:Rubular

2011年5月27日 星期五

縮小我的 javascript 大小

近日看好幾個 open source 的程式,他們不約而同的都習慣將 xxx_src.js 另外再寫一支 xxx.js 。理由何在,就是要縮小 javascript 的檔案大小,這樣一來,使用者在讀取網頁時,也會因為所需下載的 javascript 檔比較小,而加快網頁傳送速度。xxx.js 是經過壓縮後的檔案,對於 javascript 檔而言,所謂的「壓縮」,僅僅去除多餘的空白甚至是註解而已,用以減少檔案的大小。但是,經過壓縮過後的 javascript,相對也會造成「閱讀不易」的缺點,所以這幾個 open source 的作法,就是同時保留原始的程式 xxx_src.js 與 壓縮過的 xxx.js 。而程式實際上的運行,當然是使用 xxx.js 。只是日後有任何修改需求時,需要先去修改 xxx_src.js ,然後再將他進行壓縮後,把結果放到 xxx.js 。

在網路上,目前有看到兩個不錯的線上壓縮 javascript 的網站,經過測試後,效果都還不錯。分別是 javascriptcompressor 與 YUI Compressor。

javascriptcompressor:預設的處理方式,會將原始程式多餘的空白、註解都刪除。但如果你還想進一步縮小的話,他有一個 「Shrink variables」選項可以勾選,打勾後你會發現,他連程式裡面函數的參數名稱,都會用最簡單的方式來取代。譬如說,你有個函式: function iNeed(woman,lady,spicy_girl) ,壓縮後的結果,就會變成 function iNeed(a,b,c) ,由原本 37 個字元變成 21 個字元。


YUI Compressor:預設的處理方式,會將原始程式多餘的空白、註解都刪除,並將函數的參數名稱,用最簡單的方式來取代。但如果你不希望函數裡的變數被取代時,可以將 JavaScript Options 裡的 「Minify only, no symbol obfuscation.」這選項打勾,這樣就可以避免變數名稱被替換。

參考:
01:http://javascriptcompressor.com/
02:http://refresh-sf.com/yui/

2011年5月17日 星期二

javascript 抓取 web.config 的 appSettings

在 aspx 頁面的 javascript 程式裡,如果想要能夠抓取 web.config 裡的設定資訊時,可以使用 Literal 這個伺服器控制項來完成。當您想以程式設計方式設定文字且不要加入額外的 HTML 標記時,可將 Literal Web 伺服器控制項加入網頁。Literal 控制項十分實用,因為這個控制項可以在不加入不屬於動態文字的項目下,將文字動態加入網頁。舉例來說,當你使用 Label 控制項時,網頁輸出的結果就會是 <span>xxx</span>,但如果是使用 Literal 控制項,則只會輸出 xxx 而已。

假設我目前的 web.config 設定了 TestEmpNo 如下
<appSettings>
  <add key="TestEmpNo" value="526275" />
</appSettings>

在 .aspx 頁面裡,我的 javascript 就可以寫成如下:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ConTest.aspx.cs" Inherits="ConTest" %>

<!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 runat="server">
    <title></title>
    <script>
        alert('Admin Empno:' + '<asp:Literal runat="server" Text="<%$ appSettings:TestEmpNo%>" />');
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    
    </div>
    </form>
</body>
</html>

這裡是搭配以前所提到「SqlDataSource 使用 web.config 的 appSettings」的文章,透過<%$ appSettings:TestEmpNo%> 去抓取 Web.config 內容。

如果你有很多的 javascript 都有共用資訊的需求時,統一放在 web.config 裡也不失為一個好方法。但前提必須是沒有機密性的資料才行,不然你只要檢視網頁原始碼,就....就被看光光了啦~

參考:
01:HOW TO:將 Literal Web 伺服器控制項加入至 Web Form 網頁
02:ASP:Literal控件用法
03:SqlDataSource 使用 web.config 的 appSettings

2011年5月10日 星期二

用 javascript 選取 class name 物件

習慣了 jQuery 所提供的選擇器 (Selectors),可以很方便的選取頁面上有相同 class name 的物件。但當你在沒有辦法使用 jQuery 的情況下,就得事事都要親力而為了。或許,以後的以後,像是 HTML 5 的標準裡,已經新增了  getElementsByClassName() 這方法,但我目前還沒有勇氣告訴使用者,本網站拒絕不支援 HTML5 的瀏覽器參訪。

但這問題還好,其實可以在 google 上找到各式各樣的範例來參考,也不用擔心你會找不到。只是自己將測試過、合用的範本記錄下來,方便日後 Copy ...

我在 anyexample 網站找到一段適用於目前各主要瀏覽器都可正常使用的程式 getElementsByClass():

<html>
<head>
<script>
function getElementsByClass( searchClass, domNode, tagName) { 
 if (domNode == null) domNode = document;
 if (tagName == null) tagName = '*';
 var el = new Array();
 var tags = domNode.getElementsByTagName(tagName);
 var tcl = " "+searchClass+" ";
 for(i=0,j=0; i<tags.length; i++) { 
  var test = " " + tags[i].className + " ";
  if (test.indexOf(tcl) != -1) 
   el[j++] = tags[i];
 } 
 return el;
} 

function SearchClassSwitch()
{

 var cssArray=getElementsByClass('dv');

 for(i=0; i<cssArray.length; i++) 
 {
  if (cssArray[i].style.display=='')
   cssArray[i].style.display = 'none';
  else
   cssArray[i].style.display = '';
 }
}


</script>
</head>
<div class="dv">讓我藏起來</div>
<div class="dv">看不見</div>
<input type="button" value="隱藏切換" onclick="SearchClassSwitch();" />
</html>

他執行的結果就會如下圖:


既然先前有提到, HTML 5 會開始支援 getElementsByClassName() 方法,趁這機會也來測試一下:

<html>
<head>
<script>
function getElementsByClass( searchClass, domNode, tagName) { 
 if (domNode == null) domNode = document;
 if (tagName == null) tagName = '*';
 var el = new Array();
 var tags = domNode.getElementsByTagName(tagName);
 var tcl = " "+searchClass+" ";
 for(i=0,j=0; i<tags.length; i++) { 
  var test = " " + tags[i].className + " ";
  if (test.indexOf(tcl) != -1) 
   el[j++] = tags[i];
 } 
 return el;
} 

function SearchClassSwitch()
{

 var cssArray=getElementsByClass('dv');

 for(i=0; i<cssArray.length; i++) 
 {
  if (cssArray[i].style.display=='')
   cssArray[i].style.display = 'none';
  else
   cssArray[i].style.display = '';
 }
}

function Html_5()
{
 var cssArray=document.getElementsByClassName('dv');
 for(i=0; i<cssArray.length; i++) 
 {
  if (cssArray[i].style.display=='')
   cssArray[i].style.display = 'none';
  else
   cssArray[i].style.display = '';
 }
}

</script>
</head>
<div class="dv">讓我藏起來</div>
<div class="dv">看不見</div>
<input type="button" value="隱藏切換" onclick="SearchClassSwitch();" />
<input type="button" value="隱藏切換 Html5" onclick="Html_5();" />
</html>

結果是:

IE8   不行
FireFox 3.6 OK
Chrome 11.x OK
Opera 11.x OK



參考:
01.HTML5 技術體系中的 JavaScript
02.JavaScript getElementsByClass function

2011年1月6日 星期四

強迫使用者輸入大寫或小寫字母

讓使用者乖乖在輸入方塊上敲大寫或小寫字母,似乎是不可能的事,那要如何霸凌使用者所輸入的資料呢?目前我整理了兩種前端的使用方法。

第一種方式,是透過 jQuery 與 javascript。在 javascript 裡有兩個 function: toUpperCase() 、toLowerCase(),分別是將字串轉為大寫或小寫。我攔截使用者敲鍵盤的 keyup 事件,並在這事件裡進行轉換的動作。最後用 jQuery 尋找所有有定義 class 名稱為 upper 或 lower 的物件,可以適用這次的調整。

第二種方式,是透過 style 屬性裡的 text-transform 來產生大寫或小寫的效果,舉例來說,標記為 style="text-transform: uppercase",則你輸入的文字都會自動被轉成大寫,而 style="text-transform: lowercase" 則是小寫。

以上兩種方式都能符合自己的需求,但使用 style 的作法相較之下,真的簡單多了。


<html>
<head>
<script src="http://code.jquery.com/jquery-1.4.4.js"></script> 
<script>

  $(function(){

       $(".upper").keyup(function(evt){
          var vOri=$(this).val();
          var vNew=vOri.toUpperCase();
          $(this).val(vNew);
       });

       $(".lower").keyup(function(evt){
          var vOri=$(this).val();
          var vNew=vOri.toLowerCase();
          $(this).val(vNew);
       });
   });

</script>
</head>
<body>
ToUpper(JQuery):<input type="text" id="tbxTest1" class="upper" ><br>
ToLower(JQuery):<input type="text" id="tbxTest2" class="lower" ><br>
ToUpper(Style):<input type="text" id="tbxTest3" style="text-transform: uppercase" ><br>
ToLower(Style):<input type="text" id="tbxTest4" style="text-transform: lowercase" ><br>

</body>
</html>


補充:20110106

經過實際專案的測試,發現上述兩種方式,實際上是有點差異的。我先說透過 style 屬性的方式,這方式只是讓你的結果看起來像是已經轉換成大寫或小寫,但實際不是。所以如果你不介意儲存資料時是否一定要是大寫或小寫,那使用 style 屬性的方式並無太大問題。反之,如果你很在意存入資料庫時必須是大寫或小寫,那就不可以用 style 屬性方式了,得採用 jquery + javascript。


在上圖中,我每個輸入方塊都是輸入 aaaaa  ,壓下 btn 按鈕並將畫面上的值印出來。可以發現 ToUpper(JQuery) 的值是符合我的期待,但 ToUpper(Style)就不同了,畫面上顯示 AAAAA,但它裡面的結果卻還是我原先輸入的 aaaaa。所以,在使用這轉大小寫功能時,得留意這兩者用法的差別了。



Ref:
01.JavaScript toUpperCase() Method
http://www.w3schools.com/jsref/jsref_touppercase.asp
02.How can I force input to uppercase in an asp.net textbox?
http://stackoverflow.com/questions/202368/how-can-i-force-input-to-uppercase-in-an-asp-net-textbox

2010年12月30日 星期四

你的網頁已經下載完畢了?

在撰寫 JavaScript 時,我們可能會透過 getElemnetById 或 getElemnetByName 來取得頁面上的物件,或者你想去呼叫某個已經事先定義好的函數。可是,如果網頁上的 DOM 尚未完全載入完畢時,你所執行的 JavaScript 語法,就很有可能會出現錯誤。我參考「Are you ready for this」這篇文章,作者提了一個問題,「你怎麼確定你的網頁已經下載完畢了?」

對於這個問題,首先要清楚網頁對於「下載完畢」的定義有分兩種:第一種:window.onready,是真的所有東西都下載完畢,包括:頁面所參考引用的所有 CSS、Script、Image、Flash。第二種:DOM-ready,則是網頁的DOM階層樹建置完畢,包括頁面上所引用的 CSS、Script。可想而知,第一種 window.onready 是所謂網頁真正完全下載完畢,但是目前的網頁越來越花俏,可能你的頁面有一個非常巨大的圖片連結,而要達到 window.onready 的地步,勢必要花不少時間。比較合適的作法,是第二種 DOM-ready,只需要確保我們執行的 JavaScript 所需的 DOM 階層架構都已經完整,就可以先執行了,不需要去等待圖片或是 flash 的下載。


在我們常見的一個 JavaScript 語法, window.onload=function(){ //Do something. };
他的效果比像上面所提到的第一種 window.onready,所以在我們使用它用的很開心的時候,應該好好想想,這種寫法會不會讓你的程式效能或是給使用者的感觀受影響。「jQuery in Action」一書的作者,在他書裡的第一章節,也提到為了避免讓使用者長時間的等待頁面圖片的下載,建議使用:

$(document).ready(function(){ // Do something. });

因為 jQuery.ready( )的效果,是我們介紹的第二種 DOM-ready 模式 ,可以讓使用者減少等待的時間。不過附帶一提的是, 作者認為使用 window.onload 的另一個缺點,就是他只能使用一次,如果被除重複呼叫或是你程式裡還有其他 third party 函式庫也使用了 window.onload ,就會造成被蓋來蓋去的問題。其實,這部份可以參考「JavaScript 小陷阱 (5) – window.onload()」這篇文章,透過一個小技巧,也是可以讓你重複呼叫多次的 window.onload 。

以下程式碼節錄自JavaScript 小陷阱 (5) – window.onload()

var oldOnload = window.onload || function () {};
window.onload = function ()
{
oldOnload();
// Do Something...
}

透過事先將舊的 onload 事件存放在一個變數,並於自行定義的 onload 事件中,找個適當位置觸發舊的事件。

在上一篇紀錄:「Internet Explorer 無法開啟網際網路網站」,除了使用者自己的瀏覽器問題之外,程式撰寫本身也是有可能會造成這問題。程式的部份,就是 DOM 有沒有完全下載完畢所導致。透過比較清楚的瞭解後,至少下次發生問題時,可以降低因為程式撰寫不良而讓系統出錯的機率。

參考:


01.Are you ready for this
http://www.hunlock.com/blogs/Are_you_ready_for_this
02.JavaScript 小陷阱 (5) – window.onload()
http://www.jaceju.net/blog/archives/160
03.Internet Explorer 無法開啟網際網路網站
http://paladinprogram.blogspot.com/2010/12/internet-explorer.html
04.The window.onload Problem
http://peter.michaux.ca/articles/the-window-onload-problem-still

2010年8月24日 星期二

在 JavaScript 裡,知道 === 與 == 的區別嗎?

印象中,以前有遇過這問題,但當下認為他們是一樣的,所以也就沒有很認真去區分他們間的差別。但今天在看 jQuery 的原始碼時,發現這些老外都喜歡用 ===  而不用 ==,難到,真的只是因為老外比較長這原因而已嗎?

而我在 devguru 找到老外比較長的原因了。

一般在寫 JavaScript 時,我們「等號運算子(==)」的左右兩邊,你可能偶而會發現,如果有一個變數,他的值是整數,但如果在等號運算子的另一邊用字串來比較,有可能會通過。舉個例子來說:

var v=5;
if ( v=="5")
  alert('the same');
else
  alert('not the same');

這程式執行的結果,會跑出 「the same」出來。原因是你使用 == 運算子時,他會試圖自動去幫你作轉型的動作,以符合懶人的期望。但這一懶,卻也跑出了些潛在的問題。

第一,雖然程式幫你作了自動轉型來比較,但你可能已經誤用或誤會了這個變數他原本所宣告的變數型態,現在他包容了你,但不保證當你的程式變肥之後,日後在型態處理上吃了一記悶棍。

第二,是效能問題。如果要讓程式去幫你作自動轉型的動作,則他必須要多花一些額外的時間將所有型態一一去跟你目前的變數比較,這動作會比你一開始就直接講明兩邊都是要同樣型態會來得花時間。

所以,如果要讓自己程式寫得嚴謹,使用嚴格的等號運算子(===)是比較建議的。而他的雙胞胎兄弟,則是 !==,就請大家自個兒舉一反三了。

個人在 stackoverflow 論壇看到一篇很詳盡的介紹,很推薦去看他那篇說明,或找關鍵字 strict equal operator 搜尋更多其他文章。

參考:
01:http://www.devguru.com/Technologies/ecmascript/quickref/comparison_operators.html
02:http://stackoverflow.com/questions/359494/javascript-vs-does-it-matter-which-equal-operator-i-use
03:http://www.webreference.com/js/column26/stricteq.html

2010年7月8日 星期四

IE 不支援 array.indexOf

今天在一篇介紹 JavaScript: array.indexOf 的文章,將他的程式碼下載執行一下,發現奇怪的問題,在 Chreom & FireFox 都可以正常執行,唯獨 IE 不可以。後來拜讀了 Colin Pear 的文章後,順利找到解法。

日後如果要使用 array.indexOf ,要在呼叫前,先引用一段來處理支援各家瀏覽器的方法:

if(!Array.indexOf){
  Array.prototype.indexOf = function(obj){
   for(var i=0; i<this.length; i++){
 if(this[i]==obj){
  return i;
 }
   }
   return -1;
  }
}

完整範例:

<html>
    <head><h1>JavaScript Array indexof </h1>
        <title>JavaScript array indexof </title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <body>
        <script language="javascript" type="text/javascript">
            var array=new Array();
            array[0]="Rose";
            array[1]="India";
            array[2]=".net";
            array[3]="Rohini";
            document.write("<b>"+"Element in the array are "+"</b>"+ "<br />");
            document.write("================="+ "<br />");
            for(var i=0;i<array.length;i++){
                document.write(array[i]+"<br>")
            }
            document.write("================="+ "<br />");


   if(!Array.indexOf){
     Array.prototype.indexOf = function(obj){
      for(var i=0; i<this.length; i++){
    if(this[i]==obj){
     return i;
    }
      }
      return -1;
     }
   }


            var index = array.indexOf("India");
            document.write("<b>"+"Index of India on the array is: "+"</b>"+index);
        </script> 
    </body>
</html>
參考:
http://www.roseindia.net/java/javascript-array/javascript-array-index-of.shtml
http://www.pearweb.com/javascript/array-index-of.html

2010年6月22日 星期二

給我一個圓角的框框

對於四四方方的按鈕或表格,如果可以讓它的邊邊角角圓滑一點,似乎會比較好看些。在 css3 ,其實早已提供相關的設定,但...這些的好處,偏偏 IE 都不支援;而工程師的難處,偏偏老闆都不知道。

最近看到 IE-CSS3 讓 IE 支援 CSS3  這篇文章的介紹,提到了 IE-CSS3 可以解決這問題。下載後,自己改寫了一下程式,讓原本四四方方的按鈕有了弧度。


先到 http://fetchak.com/ie-css3/ 去下載 ie-css3.htc
接著定義了樣式內容:

.button {   
 background-color:#3961CA;
 color:White;
 cursor:pointer;
 height: 22px; 
 border: 1px solid #c6ac6c;
 position: relative;
 padding: 1px 5px 1px 5px; 
 -moz-border-radius: 6px;
 -webkit-border-radius: 6px;
 border-radius: 6px;

 behavior: url(ie-css3.htc);
}


然後直接讓該按鈕  的 class 套用 button 。這樣就可以呈現出圓角按鈕了。

實作後發現,因為我的按鈕是使用伺服器控制項拉的,只要一按,頁面就會 postback 且重新載入一次頁面,這時,就會很明顯的看到我的圓弧按鈕變成正正方方,最後又在變成圓弧。對於這樣的變化,總是覺得有點怪,心裡頭似乎不大滿意這樣的效果。

於是另外又比較了一個可以產生圓弧的 JavaScript : DD_roundies 。他只會處理針對 IE 瀏覽器的圓弧效果,但這也還好,因為其他瀏覽器幾乎都支援 css3,可以很容易的達成我所需的效果。

實作 DD_roundies,首先要到 http://www.dillerdesign.com/experiment/DD_roundies/  下載 0.0.2a-min.js,因為我並不打算去改寫作者寫好的 code,所以直接下載壓縮後的檔案即可。

而使用方式,則是將符合您所要套用的物件放進 DD_roundies.addRule( ) 裡,而非 IE 的部份,則自行定義在 Style 裡面。

以下是完整的測試程式碼:

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
  <title>未命名頁面</title>
  <script type="text/javascript" src="DD_roundies_0.0.2a-min.js"></script>
  <script>
  DD_roundies.addRule('.button', '6px');
  </script>
  <style>
  .button {  
  background-color:#3961CA; color:White; cursor:pointer;padding: 1px 5px 1px 5px; 
  /* Do rounding (native in Safari, Firefox and Chrome) */
  -webkit-border-radius: 6px;
  -moz-border-radius: 6px;    
  }
  </style>
</head>
<body>
  <form id="form1" runat="server">
  <div>    
  <asp:Button ID="btnSearch" CssClass="button"  Text="存檔" runat="server" />
  </div>
  </form>
</body>
</html>


經過這兩個範例,自己比較欣賞 DD_roundies ,因為即便是網頁發生 postback 重新載入,圓弧的按鈕都不會有任何變化,這正也是我想要的結果。

參考頁面:
01. CSS3 support for Internet Explorer 6, 7, and 8
02. DD_roundies
03. CSS 3 的新玩意
04. IE-CSS3 讓 IE 支援 CSS3

2010年4月7日 星期三

FireFox showModalDialog()

近來發現,在 FireFox 3.0 以後的版本已經開始支援 showModalDialog()的語法了。在3.0以前的 FireFox 使用,都會發生關閉後,無法更新原來頁面上資料的問題。我目前 FireFox 版本是3.6,實際測試,發現使用 showModalDialog( ) 也會有「獨占」的效果。不像以前彷彿只是用 window.open( ) 的樣式。

另外關注的一點,就是 google 自家瀏覽器 chrome。在 chrome 4.1 版,使用 showModalDialog( ) 在關閉彈跳視窗後,也能更新原來頁面,但是「獨占」效果,卻依然尚未支援。

參考:
https://developer.mozilla.org/en/DOM/window.showModalDialog
http://virendradugar.wordpress.com/2009/01/06/firefox-30-supports-showmodaldialog/

2010年4月2日 星期五

js 取得 TextArea 的換行控制碼

可能是年紀大了,竟然為了找一個很簡單的東西,卻花了好久的時間。

我有一個 TextArea 的控制項,需要將裡面的內容存到另一個 Div 裡。如下圖所示:
可以很明顯發現,原本在 TextArea 裡有換行的內容,卻在 Div 裡全部擠在一起了。這問題的解法,就是要抓到 TextArea 的換行控制碼,並將這控制碼用 <BR> 來取代。

關鍵的指令就是: replace(/\n/g,"<br>")

/ ... / :是指正規表示式
g : 一直替換到最後

說穿了沒甚麼,但要是忘了,就要找好久。

將測試的程式整理如下:

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>未命名頁面</title>
    <script type="text/javascript" src="js/jquery-1.3.2.js"></script>
    <script>
    function ShowMsg()
    {
        var vMsg=document.getElementById("tbxInput").value;       
        $("#divContent").html($("#tbxInput").html().replace(/\n/g,"<br>"));
    }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        TextBox:<br />
        <asp:TextBox ID="tbxInput" runat="server" Rows="5" TextMode="MultiLine" style="width:250px"></asp:TextBox>
        <input id="btnShow" type="button" value="轉入" onclick="ShowMsg();" /></div>
        <br />
        DIV:
    <div id="divContent" style="border-width:1; border-color:Black; background-color:Aqua; width:250px"></div>
    </form>
</body>
</html>

完成後的結果:

參考文章:http://www.xue163.com/html/2009121/2522346.html

2010年3月3日 星期三

網頁除錯工具 firebug

FireFox 提供了一個外掛的 plug-in 軟體:firebug 。可以透過它對網頁上的 javascript 進行除錯工作,甚至可支援 javascript 的單步執行除錯。在除錯過程中,也可以隨時顯示每個變數目前的數值狀況。相信對於網頁上複雜的 javascript 撰寫會有很大的幫助。


推薦幾個不錯的介紹網址:

http://blog.wu-boy.com/2010/01/05/1943/

http://caterpillar.onlyfun.net/Gossip/AjaxGossip/FireBug.html

http://getfirebug.com/enable

自己實際下載後,試著執行一段簡單的 code :

<script>
var a = "test";
console.log("a is %s ", a);
</script>

沒想到就出現 『主控台 panel is disabled』的訊息。


還好,原來是 firebug 預設就會關閉 主控台 的功能。只要去將主控台的下拉點選下去,並挑選 Enabled ,就可以正常執行了。


常用指令:
1. console.log();   將變數的值輸出到主控台
2. debugger;  開始 單步除錯

2009年11月25日 星期三

window.open 最大化

近來一直在拜求如何讓 window.open 所跳出的新視窗能夠一開始就最大化,不需讓 user 還要再去點選一次瀏覽視窗的最大化,可惜,一直沒找到真正的解決方案。

有人透過

window.open(url,"","fullscreen=yes");

雖然是把畫面變大了,但它是屬於全螢幕的呈現方式,對於一般瀏覽器操作比較不熟的 user ,可能無法很順利的處理如何解除全螢幕的設定。

最後找到比較接近需求的方式,是透過 JavaScript 去控制新開啟的視窗,把它的寬高放大到與 user 目前的螢幕相同。
他的 code 如下所示:
sc=window.open(url,"","resizable=yes,scrollbars=yes");
sc.resizeTo((screen.availWidth),(screen.availHeight));
sc.moveTo(0,0);


參考:http://www.lslnet.com/linux/f/docs1/i57/big5380574.htm

2009年11月4日 星期三

JQuery 取得 checkbox 群組內被選取的項目



在 ASP 程式裡,只需要下 Request("cbox") 語法,就可以將所有 checkbox name="cbox" 的項目內容取回並以逗號(,)區隔。可是在 JQuery 就沒辦法用一行指令來完成了。以下分別使用 jQuery 與 JavaScript 來完成同樣的目的。

首先定義一下情境。

<input type="checkbox" name="pet" value="1"/>
<input type="checkbox" name="pet" value="2"/>
<input type="checkbox" name="pet" value="4"/>

<BR>
<input type="button" value="JQueryclick" OnClick="JQClick()" />
<BR>
<input type="button" value="JSclick"  onclick="JSClick()"  />

一共有三個 checkbox ,都是同樣的 name (pet),另外多了兩個 button,一個是呼叫 jquery 寫法,另一個則是 javascript 。

既然有要使用 jQuery,所以一開始就要記得將 jQuery.js 引用進來:
<script src="jquery.js" type="text/javascript">

接著就需要定義 JQClick() 與 JSClick() 。

JQClick:
function JQClick()
{  
   var str="";  
//$("input[name=pet]:checked") 
//可以先將畫面上 name=pet 且 有被勾選的 checkbox 選出來   
//然後再透過 each ( ) 去分別處理每個被選取的項目
   $("input[name=pet]:checked").each(function(i){str=str+$(this).val()+",";})
//將字串最後一個逗號去除
   if(str.length>0)
     str=str.substr(0,str.length-1);
     alert(str);
}

JSClick:
function JQClick()
{
  var checkedItems=""
  //取得畫面上 name = pet 的元素,他會回傳一個陣列集合
  var ckItems=document.getElementsByName('pet');
  //針對陣列集合的項目逐筆去處理
  for ( var i=0;i
    //如果有被勾選 ,才記錄下來
    if(ckItems[i].checked==true)
    {    
       checkedItems=checkedItems+ckItems[i].value+",";
    }
  }

  if(checkedItems.length>0)                
     checkedItems=checkedItems.substr(0,checkedItems.length-1);

  alert(checkedItems);
}