2011年終總結:爲了娜娜的微笑



  蒙娜麗莎爲什麼笑?這個問題,如果達·芬奇自己都沒有交代過,那麼就沒有人知道答案了,後來所有的答案都是推測的,答案衆說紛紜,這裏就不做評論了。作爲計算機運行的代碼,答案只能是一個,1就是1,2就是2。
  2011年馬上就快過去,按照國際慣例,到了年底,總要進行下總結,以記錄過去,憧憬未來。養成良好的習慣,可以避免在工作中少出現問題,可以使項目提早完成,可以提早下班,提早拿到RMB。這樣,客戶會微笑,老闆會微笑,自己會微笑,當然,娜娜也會微笑了。爲了娜娜的微笑,下面就對CSDN上出現的一些問題,結合具體的案例,進行下分析和總結,希望對大家有所幫助。
1,meta 標籤搗亂
  有一個CSDN上的問題,爲了便於重現問題和測試,貼出完整的代碼如下:
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
  protected void Page_Load(object sender, EventArgs e)
  {
    Page.MetaKeywords = "孟子E章";
    Page.MetaDescription = "http://dotnet.aspx.cc";
  }
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title></title>
</head>
<body>
  <form id="form1">  
  請輸入關鍵字:<input id="keywords" /><br />
  請輸入其描述:<input id="description" /><br />
  <input type="button" value="得到輸入的關鍵字" onclick="alert(document.getElementById('keywords').value)" />
  <input type="button" value="得到輸入的描述" onclick="alert(document.getElementById('description').value)" />
  </form>
</body>
</html>
  上面的代碼有問題嗎?按道理說,不應該出現問題。但是,卻有人遇到了問題,該用戶問的是使用document.getElementById('keywords').value爲何得不到<input id="keywords" />的?當時他的貼的代碼並不全,所以,很難說明是什麼原因。經過分析,原來,他頁面的前面加了<meta name="keywords">導致name和id的不能正確的區分。IE瀏覽器的一個Bug就是不區分ID和Name屬性,就連meta裏面的name也不放過。
  當我們在低版本的IE中點擊按鈕時,得到的undefined,但是,在IE9下點擊,能夠得到正確的結果(注意:兼容模式下是不能得到的),這段代碼生成了下面的html
<meta name="description" content="http://dotnet.aspx.cc" />
<meta name="keywords" content="孟子E章" />
  所以,一個好的習慣就是不要使用有可能是關鍵字的標識符。當我們出現問題的時候,也應該想想,如果keywords換成 UserKeywords試試能否得到,就可以很快的解決問題了。
2,天生缺陷,button 行爲的改變
  不知道html元素中有input元素,爲何還要造出一個button元素,就是這個button元素導致了問題的產生。下面是一段ASP.NET MVC中產生的大致代碼
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title></title>
  <script type="text/javascript">
    function checkForm(oF) {
      if (oF.UserName.value == "") {
        alert("請輸入用戶名。")
      }
      else {
        //ajax提交
      }
    }
  </script>
</head>
<body>
  <form action="/SaveData" method="post">
  <input type="text" name="UserName" value="net_lover" />
  <button onclick="checkForm(this.form)">保存數據</button>
  </form>
</body>
</html>
  代碼執行的結果是,在數據庫中老是同時添加2條相同的記錄,按照以前IE的做法,這樣寫是沒有任何問題的,<button>就相當於<input type="button">,button的默認類型是button。但是從IE8之後,這種默認的行爲改變了,button的默認類型變成了submit,所以,上面的代碼其實是提交了2次。MSDN上對這種行爲的改變也做了很多的解釋,http://msdn.microsoft.com/en-us/library/ms535211%28v=vs.85%29.aspx
  另外,在非IE瀏覽器和W3C的定義中,button的默認類型都是submit的。
  我從來都不使用button元素的,一致使用input來解決問題。作爲一種好的習慣,出現莫名問題的時候,應該試着做一些改變。
3,id標識符和函數定義衝突
  上面說了IE中的問題,下面說一個非IE中也令人奇怪的現象。這個問題也是論壇上出現的。爲了說明問題,先貼上完整的代碼
<!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>
<script type="text/javascript">
  function changebg() {
    document.getElementById("bg").style.backgroundImage = "url(http://dotnet.aspx.cc/Images/logoSite.gif)";
  }
  function changebg2() {
    document.getElementById("bg2").style.backgroundImage = "url(http://dotnet.aspx.cc/Images/logoSite.gif)";
  }  
</script>
</head>
<body>
<div id="bg" style="height:60px;background:url(http://dotnet.aspx.cc/Images/meng.gif)"></div>
<img id="changebg" src="http://dotnet.aspx.cc/Images/logoSite.gif" alt="" /><br />
<input type="button" value="改變背景1" onclick="changebg()" />

<div id="bg2" style="height:60px;background:url(http://dotnet.aspx.cc/Images/meng.gif)"></div>
<div id="changebg2">測試</div>
<input type="button" value="改變背景2" onclick="changebg2()" />
</body>
</html>
  在Firefox、Chrome、Oprea中,上面的代碼“改變背景1”按鈕是無法改變背景的,會提示 changebg is not a function ,但是“改變背景2”則是可以的,這個問題比較奇怪,出現問題的原因是函數定義和id標識符名稱相同。但更奇怪的是,爲何img的id和div的id都與函數名稱相同,爲何執行的行爲卻不一樣?當然,解決問題的方法很簡單,就是改一下名字就可以了。
  採用不同的標識名稱永遠都是一個好的習慣。是放之四海而皆準的真理。
4,保證DOM結構的完整正確
  下面,再說一個非 IE 中的問題。爲了便於測試,也先貼出完整的測試代碼:
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
  protected void Page_Load(object sender, EventArgs e)
  {
    if (Request.HttpMethod.Equals("POST"))
    {
      int RowCount = Int32.Parse(Request.Form["RowCount"]);
      for (int i = 0; i < RowCount; i++)
      {
        Response.Write("<li>你輸入了:" + Request.Form["txt" + i]);
      }
    }
  }
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
  <title></title>
  <script type="text/javascript">
    var count = 1;
    function addRow() {
      oTable = document.getElementById("table1");
      oRow1 = oTable.insertRow(oTable.rows.length);
      oCell1 = oRow1.insertCell(0);
      oCell1.innerHTML = "輸入名稱:";
      oCell2 = oRow1.insertCell(1);
      oCell2.innerHTML = "<input name='txt" + count + "'/>";
      count++;
      document.forms[0].RowCount.value = count;
    }
  </script>
</head>
<body>
  <table>
  <tbody>
    <form id="form1" runat="server">
    <input type="hidden" name="RowCount" value="1" />
    <tr>
      <td>
      <table border="1" id="table1">
      <tr>
      <td>輸入名稱:</td><td><input name="txt0" /></td>
      </tr>
      </table>
      </td>
    </tr>
    </form>
    </tbody>
  </table>
  <input type="button" value="添加" onclick="addRow()" />
  <input type="button" value="提交" onclick="document.forms[0].submit()" />
</body>
</html>
  上面的代碼,在IE執行,可以正確得到所輸入的內容,但是在非IE中,只能得到txt0的內容。這個問題也確實比較奇怪的,按理說,js生成的和原來的html應該是相同的,但是在非IE中,確是無法得到這些輸入的內容的。當然,解決方法很簡單,就是把form移到table之外即可解決。
  還有其他的例子,這裏就不再寫了,以後再集中寫吧。
  所以,好的習慣是保持DOM Tree的正確性,比如不要在span中寫div,p之類的標籤元素,因爲span是行內元素,div,p 都是塊級元素,非IE瀏覽器對文檔結構的要求都是很嚴格的。我們要養成良好的習慣。

  不管怎麼樣,2011年馬上就要過去,2012年是否真的是世界末日,還需要拭目以待。不過,如果我們養成了良好的習慣,以最少的時間來完成我們的工作,把剩下的時間用來鍛鍊下自己的身體,即使像2012裏面描述的那樣出現海水倒灌,至少我們還有力氣游泳,對吧:)






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章