從一個時隱時現的工具欄說起(由一個工具欄引起的思(血)考(案))



寫在前面

1, 開發者在發的時候進行了copy ,copy後沒有進行更改。COPY的坑真的很大,要注意啊。
2, 對於變量的聲明 沒有搞清楚他的作用域,這個是開發者的水平的問題,需要加快學習,完善自己。
        3,我們自己的變量,方法的命名,不僅僅要和JavaScript的 關鍵字躲避開,也要躲開我們用的各種js框架的插件的關鍵字等等。
4 ,關鍵的問題,開發者的開發的水平參差不齊,需求的不定性,管理跟不上。
革命尚未成功,同志仍需努力!



 在這個圖片中有一個標紅的工具欄,這個工具欄是常規的列表中所用到的用來增刪改的工具欄。
這個是在測試的額時候提交上來的bug ,可是開發者在本機點擊的時候總是看不到這個工具欄,怎麼看都看不到,切換瀏覽器也看不到,然後找到測試人員進行查看,當查看的時候確實沒有了該工具欄。在另外一個開發者的機器上查看其它功能的時候,當點到這個功能的時候發現這個工具欄又出來了。
    這到(ta)底(ma)遇見鬼了嗎,神出鬼沒的。
當第一次開發人員提出來這個問題的時候,我沒在意,因爲我知道我寫的頁面中是沒有定義工具欄的,即使有那個配置項,我覺得他不會出現的,是測試人員的問題。從我本機看,確確實實也是看不到這個工具欄,確確實實看不到這個工具欄。確確實實看不到這個工具欄。重要的事情要說三遍。
    到底是爲什麼呢?後來我想起來了一個東西,這個破玩意和人的操作順序有關係,開發人員測試自己的功能的時候是直接點擊自己的功能菜單,就是說直奔主題,直接點擊他的功能項的菜單項,而測試人員並不是和開發人員一樣,他測試的時候對於菜單的點擊的順序不同,而就是這個順序不同造成了這個神出鬼沒的工具欄。
    難道說真的是操作順序的問題?難道說真的是操作順序的問題?難道說真的是操作順序的問題?
    當然不是了,對不對!(如果你認爲是,那我也沒辦法)
    那到底是什麼東西導致了這個工具欄的神出鬼沒呢。
    All is JavaScript!now,our datagrid is build with easyui which is a collection of user-interface plugin based on jQuery。What is jQuery ?Sorry ,I really don't know!
    剛纔喝多了,怎麼成英文了!
    有一個東西叫做作用域的東西在作怪,具體的一些基礎的概念,在這裏不再進行闡述。自行腦補。
    
情景一:不會出現工具欄,
               操作步驟 從菜單直接進入該頁面(功能項)A,假定爲頁面A吧,不會出現該工具欄。
 情景二:出現工具欄
                操作步驟,先點擊頁面(功能項)B,然後點擊頁面A,會出現工具欄。

頁面A 和頁面B 有很多的相同的地方,開發人員在進行開發功能A的時候進行了頁面複製(COPY),複製頁面B,然後進行了改動形成了頁面A。
        
    可惡的copy,開發過程中沒少被它坑吧。我相信不少人被copy 坑!好了,這個不是我們說的重點。
    
    說到作用域,先說一個東西叫做 window ,在所有的頁面中,都默認有這樣一個玩意。具體的我不做解釋,你知道有這樣一個東西就好。假設了,你已經知道這個東西和基礎的js的基礎。
        
        在傳統的,中規中矩的web系統中都有一個主頁面,然後其他的一些內容通過各種方式在主頁面中進行填充,變換。
        爲了說明這個問題,我們有三個頁面,Main.jsp ,A.jsp ,B.jsp



  Main.jsp 是主頁面,模仿系統的最初的頁面,
        A.jsp 是 包含那個時隱時現的工具欄的頁面。
        B.jsp 是 包含    B 功能的頁面
        
下圖是 main.jsp 的頁面





點擊菜單A 出現如下效果圖, 沒有構造出來datagrid,當然這是因爲找不到_tollbar 這個變量的問題,這個問題彆着急,往下看




點B的效果圖 如下,有工具欄,注意看title  “這是B頁面”





好了,然後我們再點回A 看看,效果如下如所示





這個時候A頁面中的工具欄出現了,datagrid的也出現了。
好了,表面的現象咱們都看到了,廢話說了一大桶,跟作用域毛關係呢,你倒底想說什麼呢,想說清楚一個東西就需要先說這麼一大堆廢話,廢話說完了。 咱們來看一下代碼。
    main.jsp
<%--
  Created by IntelliJ IDEA.
  User: sunjiyun
  Date: 2016/3/1
  Time: 8:59
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title></title>
  <link rel="stylesheet" type="text/css" href="../js/jslibs/jquery-easyui-1.4.4/themes/default/easyui.css">

  <link rel="stylesheet" type="text/css" href="../js/jslibs/jquery-easyui-1.4.4/themes/icon.css">
  <%--<link rel="stylesheet" type="text/css" href="../demo.css">--%>
  <script type="text/javascript" src="../js/jslibs/jquery-easyui-1.4.4/jquery.min.js"></script>
  <script type="text/javascript" src="../js/jslibs/jquery-easyui-1.4.4/jquery.easyui.min.js"></script>
</head>
<body>
<h2>Basic Layout</h2>
<p>The layout contains north,south,west,east and center regions.</p>
<div style="margin:20px 0;"></div>
<div class="easyui-layout" style="width:700px;height:350px;">
  <div data-options="region:'north'" style="height:50px"></div>
  <div data-options="region:'south',split:true" style="height:50px;"></div>
  <div data-options="region:'east',split:true" title="East" style="width:100px;"></div>
  <div data-options="region:'west',split:true" title="West" style="width:100px;">
      <ul id="menu">
        <li id="A">菜單1-A</li>
        <li id="B">菜單2-B</li>
      </ul>
  </div>
  <div data-options="region:'center',title:'Main Title',iconCls:'icon-ok'">
    <div class="easyui-panel"  id="centerTab"
         data-options="border:false,fit:true" style="background:#eee;display:block;">
    </div>
  </div>
</div>

<script type="text/javascript">
  $(document).ready(function(){
    $("#menu li").click(function(){
      var _id = $(this).attr("id");
      $('#centerTab').panel({
        href:getRootPath()+'/blogs/jsscope/'+_id+".jsp"
      });

    });

    function getRootPath() {
      //獲取當前網址,如: http://localhost:8083/uimcardprj/share/meun.jsp
      var curWwwPath = window.document.location.href;
      //獲取主機地址之後的目錄,如: uimcardprj/share/meun.jsp
      var pathName = window.document.location.pathname;
      var pos = curWwwPath.indexOf(pathName);
      //獲取主機地址,如: http://localhost:8083
      var localhostPaht = curWwwPath.substring(0, pos);
      //獲取帶"/"的項目名,如:/uimcardprj
      var projectName = pathName.substring(0, pathName.substr(1).indexOf('/') + 1);
      return (localhostPaht + projectName+"/");
    }
  })
</script>
</body>
</html>



在 main.jsp中的代碼 我就不一行一行的解釋了, 只是個菜單的鏈接,在center中 有一個div 作爲panel ,這個panel作爲系統內容的初始化的地方,點擊 菜單A 和B 的時候 在這個地方顯示A 和B 的內容
 A.jsp的代碼如下
<table class="easyui-datagrid" title="這是A頁面" style="width:700px;height:250px"
       data-options="singleSelect:true,collapsible:true,url:'datagrid_data1.json',method:'get',toolbar:_toolbar">
  <thead>
  <tr>
    <th data-options="field:'itemid',width:80">Item ID</th>
    <th data-options="field:'productid',width:100">Product</th>
    <th data-options="field:'listprice',width:80,align:'right'">List Price</th>
    <th data-options="field:'unitcost',width:80,align:'right'">Unit Cost</th>
    <th data-options="field:'attr1',width:250">Attribute</th>
    <th data-options="field:'status',width:60,align:'center'">Status</th>
  </tr>
  </thead>
</table>

B.jsp的代碼

<body>

<table class="easyui-datagrid" title="這是B頁面" style="width:700px;height:250px"
       data-options="rownumbers:true,singleSelect:true,url:'datagrid_data1.json',method:'get',toolbar:_toolbar,">
  <thead>
  <tr>
    <th data-options="field:'itemid',width:80">Item ID</th>
    <th data-options="field:'productid',width:100">Product</th>
    <th data-options="field:'listprice',width:80,align:'right'">List Price</th>
    <th data-options="field:'unitcost',width:80,align:'right'">Unit Cost</th>
    <th data-options="field:'attr1',width:240">Attribute</th>
    <th data-options="field:'status',width:60,align:'center'">Status</th>
  </tr>
  </thead>
</table>
<script >
  var _toolbar = [{
    text:'增加',
    iconCls:'icon-add',
    handler:function()
    {    }
  },{
    text:'刪除',
    iconCls:'icon-remove',
    handler:function()
    {   }
  },{
    text:'修改',
    iconCls:'icon-edit',
    handler:function()
    { }
  }];
</script>
</body>

在B.jsp的頁面中 多了一點東西是 _toolbar
注意看 這個東西生命的地方是直接在  

<script >
</script> 中聲明的 ,那麼說這個 _toobar 的作用域 是多大呢, 咱們用debugger 來看一下, 我們在聲明_toolbar的下面加上debugger 看看




在chrome 瀏覽器中 F12 打開控制檯看



在debugger 窗口中我們看到 watch ,call back ,scope 等選項卡, 我們點開scope 選項卡,選項卡下面有global選項,(你可以用var 聲明個其他的東西 看看會不會出來個local選項)


而global 後面對着的是window ,那麼說global下面包含哪些東西呢,我們點開看看,global下面的東西就是Window下面的東西
點開global 之後看到裏面有好多東西,那麼多,有的我能看懂,有的我也看不懂,不過沒關係,找咱們關心的東西 _toolbar 到底在不在這兒,向下翻,很不幸,我們真的在Window下找到了它



也就是說 _toobar的有效範圍是Window 那麼說這個Window到底指的是誰呢, 那我們繼續向下找,找什麼呢,
找Window.location.href 這個的值就是這個Window 的頁面地址



很明顯 這個window 是main.jsp 這個頁面,也就是說 當_toolbar初始化的時候,他就在Window(main.jsp)中有效了。
A.jsp/B.jsp 作爲main.jsp的一部分,在main.jsp中的js中聲明的變量啊,函數啊,在A.jsp/B.jsp中是有效的,能夠訪問到的。
爲什麼 情景一 不出現工具欄而且datagrid出不來呢 ? 因爲當你初始化Main.jsp以後 你直接點擊菜單A 這時候 A中的js 就會查找聲明的變量,他找啊找,發現在A.jsp中找不到,然後他就向上找 找mian.jsp找,因爲你main.jsp包含着我(A.jsp),你不能不管啊,就給main.jsp要,找啊找啊,還是沒找到,找不到了 ,哎!

最後找吐血了,沒辦法,你也沒有,我只能給你報個錯,不讓你正常了! 只能看到上面的那個出不來的datagrid 的圖片了。


這個時候點擊B.jsp B.JSP中聲明瞭_toolbar,當然沒問題了 所以B 頁面能夠正常顯示。 這個時候main.jsp 也很高興啊,剛纔A。jsp給我要_toobar,都要吐血了,我都沒有沒法給他,現在B.jsp頁面 你給我了,太好了,這個時候Main.jsp非常高興,那個嘚瑟啊



這個時候A回來了 點擊A 。jsp ,A.jsp不高興,但是既然點擊我了,我就得給你工作,他沒有_toolbar,還是給main.jsp要,這次main.jsp吧別人給他的_toobar偷偷地給了A 。A不溫不火的走了,你給了我就好好給你幹活,上次都不給我,


既然Main.jsp把_toolBar 給他了,他也沒理由不好好工作了,所以這時候能夠正常顯示datagrid了,並且把工具欄帶來了。

不知道 大概你明白 爲什麼了嗎?
關於 作用域的 問題,網上有一大推的材料,我也解釋不了。

下面說說這個問題出現的原因
1, 開發者在發的時候進行了copy ,copy後沒有進行更改。COPY的坑真的很大,要注意啊。
2, 對於變量的聲明 沒有搞清楚他的作用域,這個是開發者的水平的問題,需要加快學習,完善自己。
3, 關於變量的命名的問題,爲什麼我們的頁面在測試的時候沒出現datagrid的出不來的現象呢, 因爲我們的代碼是這樣的

因爲<在options 中key 和value 都是一樣的,也就是說 後面的這個toolbar 是本來開發者自己定義的。但是這裏也是被叫做toolbar,由於js的特殊性,這個toolbar 和key 的toolbar 是一個東西唄。
也就是說我們自己的變量,方法的命名,不僅僅要和JavaScript的 關鍵字躲避開,也要躲開我們用的各種js框架的插件的關鍵字等等。
4 ,關鍵的問題,開發者的開發的水平參差不齊,需求的不定性,管理跟不上。
革命尚未成功,同志仍需努力!

預知後事如何,且聽下回分解!








發佈了39 篇原創文章 · 獲贊 7 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章