<address id="ttjl9"></address>

      <noframes id="ttjl9"><address id="ttjl9"><nobr id="ttjl9"></nobr></address>
      <form id="ttjl9"></form>
        <em id="ttjl9"><span id="ttjl9"></span></em>
        <address id="ttjl9"></address>

          <noframes id="ttjl9"><form id="ttjl9"></form>

          首頁

          關于Cookie的原理、作用,區別以及使用

          seo達人

          如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里

          1、cookie的作用:

          我們在瀏覽器中,經常涉及到數據的交換,比如你登錄郵箱,登錄一個頁面。我們經常會在此時設置30天內記住我,或者自動登錄選項。那么它們是怎么記錄信息的呢,答案就是今天的主角cookie了,Cookie是由HTTP服務器設置的,保存在瀏覽器中,但HTTP協議是一種無狀態協議,在數據交換完畢后,服務器端和客戶端的鏈接就會關閉,每次交換數據都需要建立新的鏈接。就像我們去超市買東西,沒有積分卡的情況下,我們買完東西之后,超市沒有我們的任何消費信息,但我們辦了積分卡之后,超市就有了我們的消費信息。cookie就像是積分卡,可以保存積分,商品就是我們的信息,超市的系統就像服務器后臺,http協議就是交易的過程。


          2、機制的區別:

          session機制采用的是在服務器端保持狀態的方案,而cookie機制則是在客戶端保持狀態的方案,cookie又叫會話跟蹤機制。打開一次瀏覽器到關閉瀏覽器算是一次會話。說到這里,講下HTTP協議,前面提到,HTTP協議是一種無狀態協議,在數據交換完畢后,服務器端和客戶端的鏈接就會關閉,每次交換數據都需要建立新的鏈接。此時,服務器無法從鏈接上跟蹤會話。cookie可以跟蹤會話,彌補HTTP無狀態協議的不足。


          3、cookie的分類:

          cookie分為會話cookie和持久cookie,會話cookie是指在不設定它的生命周期expires時的狀態,前面說了,瀏覽器的開啟到關閉就是一次會話,當關閉瀏覽器時,會話cookie就會跟隨瀏覽器而銷毀。當關閉一個頁面時,不影響會話cookie的銷毀。會話cookie就像我們沒有辦理積分卡時,單一的買賣過程,離開之后,信息則銷毀。

          持久cookie則是設定了它的生命周期expires,此時,cookie像商品一樣,有個保質期,關閉瀏覽器之后,它不會銷毀,直到設定的過期時間。對于持久cookie,可以在同一個瀏覽器中傳遞數據,比如,你在打開一個淘寶頁面登陸后,你在點開一個商品頁面,依然是登錄狀態,即便你關閉了瀏覽器,再次開啟瀏覽器,依然會是登錄狀態。這就是因為cookie自動將數據傳送到服務器端,在反饋回來的結果。持久cookie就像是我們辦理了一張積分卡,即便離開,信息一直保留,直到時間到期,信息銷毀。


          4、簡單的使用cookie的代碼

          cookie的幾種常見屬性:document.cookie="key=value;expires=失效時間;path=路徑;domain=域名;secure;(secure表安全級別),

          cookie以字符串的形式保存在瀏覽器中。下面貼段代碼出來,是一個類似購物網站的將商品添加到購物車,再從購物車還原商品信息的過程,是自己用原生JS封裝的函數。

          封裝的cookie的存入,讀取以及刪除的函數:(這里是將信息以對象的形式存放到cookie中的,會用到JSON的知識)

          [javascript] view plain copy
          1. // key : cookie 名  
          2. // value : cookie 值  
          3. // options : 可選配置參數  
          4. //      options = {  
          5. //          expires : 7|new Date(), // 失效時間  
          6. //          path : "/", // 路徑  
          7. //          domain : "", // 域名  
          8. //          secure : true // 安全連接  
          9. //      }  
          10. function cookie(key, value, options) {  
          11.     /* read 讀取 */  
          12.     // 如果沒有傳遞 value ,則表示根據 key 讀取 cookie 值  
          13.     if (typeof value === "undefined") { // 讀取  
          14.         // 獲取當前域下所有的 cookie,保存到 cookies 數組中  
          15.         var cookies = document.cookie.split("; ");  
          16.         // 遍歷 cookies 數組中的每個元素  
          17.         for (var i = 0, len = cookies.length; i < len; i++) {  
          18.             // cookies[i] : 當前遍歷到的元素,代表的是 "key=value" 意思的字符串,  
          19.             // 將字符串以 = 號分割返回的數組中第一個元素表示 key,  
          20.             // 第二個元素表示 value  
          21.             var cookie = cookies[i].split("=");  
          22.             // 判斷是否是要查找的 key,對查找的 key 、value 都要做解碼操作  
          23.             if (decodeURIComponent(cookie[0]) === key) {  
          24.                 return decodeURIComponent(cookie[1]);  
          25.             }  
          26.         }  
          27.         // 沒有查找到指定的 key 對應的 value 值,則返回 null  
          28.         return null;  
          29.     }  
          30.   
          31.     /* 存入 設置 */  
          32.     // 設置 options 默認為空對象  
          33.     options = options || {};  
          34.     // key = value,對象 key,value 編碼  
          35.     var cookie = encodeURIComponent(key) + "=" + encodeURIComponent(value);  
          36.     // 失效時間  
          37.     if ((typeof options.expires) !== "undefined") { // 有配置失效時間  
          38.         if (typeof options.expires === "number") { // 失效時間為數字  
          39.             var days = options.expires,   
          40.                 t = options.expires = new Date();  
          41.             t.setDate(t.getDate() + days);  
          42.         }   
          43.         cookie += ";expires=" + options.expires.toUTCString();  
          44.     }  
          45.     // 路徑  
          46.     if (typeof options.path !== "undefined")  
          47.         cookie += ";path=" + options.path;  
          48.     // 域名  
          49.     if (typeof options.domain !== "undefined")  
          50.         cookie += ";domain=" + options.domain;  
          51.     // 安全連接  
          52.     if (options.secure)  
          53.         cookie += ";secure";  
          54.   
          55.     // 保存  
          56.     document.cookie = cookie;  
          57. }  
          58.   
          59. // 從所有的 cookie 中刪除指定的 cookie  
          60. function removeCookie(key, options) {  
          61.     options = options || {};  
          62.     options.expires = -1; // 將失效時間設置為 1 天前  
          63.     cookie(key, "", options);  
          64. }  

          下面是商品詳情頁的JS代碼

          [javascript] view plain copy
          1. // 找到所有的 “添加到購物車” 超級鏈接  
          2.             var links = $("a", $("#tab"));  
          3.             // 循環,為每個 “添加到購物車” 的超級鏈接添加點擊事件  
          4.             for (var i = 0, len = links.length; i < len; i++) {  
          5.                 links[i].onclick = function(){  
          6.                     // 獲取當前超級鏈接所在行的所有單元格  
          7.                     var _cells = this.parentNode.parentNode.cells;  
          8.                     // 獲取到即將添加到購物車中的商品信息  
          9.                     var _id = _cells[0].innerHTML,  
          10.                         _name = _cells[1].innerHTML,  
          11.                         _price = _cells[2].innerHTML;  
          12.                     // 將商品信息包裝到一個對象中  
          13.                     var product = {  
          14.                         id : _id,  
          15.                         name : _name,  
          16.                         price : _price,  
          17.                         amount : 1  
          18.                     };  
          19.   
          20.                     /* 將當前選購的商品對象保存到 cookie 中去 */  
          21.                     // 從 cookie 中讀取已有的保存購物車的數組結構  
          22.                     var _products = cookie("products");  
          23.                     if (_products === null// cookie 中不存在 products 名的 cookie  
          24.                         _products = [];  
          25.                     else // 存在,則解析 cookie 讀取到的字符串為 數組 結構  
          26.                         _products = JSON.parse(_products);  
          27.   
          28.                     // 將當前選購的商品追加到數組中保存  
          29.                     _products.push(product);  
          30.                     // 繼續將 _products 數組內容存回 cookie  
          31.                     cookie("products", JSON.stringify(_products), {expires:7});  
          32.                 }  
          33.             }  
          html代碼,css代碼大家可以自己寫

          [javascript] view plain copy
          1. <table id="tab">  
          2.         <tr>  
          3.             <td>序號</td>  
          4.             <td>名稱</td>  
          5.             <td>價格</td>  
          6.             <td>操作</td>  
          7.         </tr>  
          8.         <tr>  
          9.             <td>1</td>  
          10.             <td>空調</td>  
          11.             <td>3999</td>  
          12.             <td><a href="javascript:void(0);">添加到購物車</a></td>  
          13.         </tr>  
          14.         <tr>  
          15.             <td>2</td>  
          16.             <td>風扇</td>  
          17.             <td>288</td>  
          18.             <td><a href="javascript:void(0);">添加到購物車</a></td>  
          19.         </tr>  
          20.     </table>  
          21.     <a href="cart_購物車.html" target="_blank">查看購物車</a>  

          購物車還原商品信息:

          [javascript] view plain copy
          1. // 從 cookie 中讀取購物車已有的商品信息  
          2.             var _products = cookie("products");  
          3.             // 判斷購物車是否有商品  
          4.             if (_products === null || (_products = JSON.parse(_products)).length === 0)  
          5.                 return;  
          6.   
          7.             // 如果有商品,則顯示到頁面中  
          8.             $(".result")[0].innerHTML = "";  
          9.             for (var i = 0, len = _products.length; i < len; i++) {  
          10.                 // 當前遍歷到的商品對象  
          11.                 var prod = _products[i];  
          12.                 // 克隆 .row 的節點  
          13.                 var _row = $(".row")[0].cloneNode(true);  
          14.                 // 將當前商品對象的信息替換節點中對應的部分,用class名獲取到的節點返回類型是一個數組所以要在后面加上[0]  
          15.                 $(".index", _row)[0].innerHTML = prod.id; // 編號  
          16.                 $(".name", _row)[0].innerHTML = prod.name; // 名稱  
          17.                 $(".price", _row)[0].innerHTML = prod.price; // 價格  
          18.                 $(".amount", _row)[0].innerHTML = prod.amount; // 數量  
          19.                 $(".oper", _row)[0].innerHTML = "<a href='javascript:void(0);'>刪除</a>"  
          20.   
          21.                 // 將克隆的節點副本追加到 .result 的 div 中  
          22.                 $(".result")[0].appendChild(_row);  
          23.             };  
          24.   
          25.             // 為每個 “刪除” 的超級鏈接綁定點擊事件  
          26.             var links = $("a", $("#container"));  
          27.             for (var i = 0, len = links.length; i < len; i++) {  
          28.                 // links[i].index = i; // 為當前遍歷到的超級鏈接附加數據  
          29.                 links[i].product = _products[i]; //   
          30.                 links[i].onclick = function(){  
          31.                     // alert("你點擊的是第" + (this.index + 1) + "個連接");  
          32.                     var index = inArray(this.product, _products);  
          33.                       
          34.                     if (index !== -1) {  
          35.                         _products.splice(index, 1);  
          36.                     }  
          37.                     // 更新 cookie  
          38.                     cookie("products", JSON.stringify(_products), {expires:7});  
          39.   
          40.                     // 找出頁面中待刪除的行  
          41.                     var _row = this.parentNode.parentNode;  
          42.                     _row.parentNode.removeChild(_row);  
          43.                 };  
          44.             }  
          這里的$(' ')函數是自己封裝的函數,用于獲取到DOM節點,可以看下我關于getElementsByClassName的兼容那篇文章。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務

          你真的了解盒模型么

          seo達人

          如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里

          說到前端, 大家第一反應是不是都是vue、react、webpack等這些大大小小的框架或者工具, 但其實這些都是和js相關的, 真正的樣式會被大家忽略。其實真正呈現給大家看到華麗的頁面, 都是樣式才讓他們多了那份色彩。那么大家覺得簡單的css樣式, 真的簡單么? 讓我們一起來看下, 開啟css的入坑之旅, 今天一起跟大家簡單聊聊盒模型的相關問題......

          盒模型

          百度知道對此的解釋, 很有意思, 在此引用一下

          CSS盒子模型, 內容(CONTENT)就是盒子里裝的東西; 而填充(PADDING)就是怕盒子里裝的東西(貴重的)損壞而添加的泡沫或者其它抗震的輔料; 邊框(BORDER)就是盒子本身了; 至于邊界(MARGIN)則說明盒子擺放的時候的不能全部堆在一起,要留一定空隙保持通風,同時也為了方便取出。 —— 百度知道

          640?wx_fmt=png&wxfrom=5&wx_lazy=1

          這段描述很有趣, 很好的解釋margin、border、padding之間的關系, 不同模式下, 盒模型的width也是不同的, 那么好, 盒模型的第一個坑來了, width的范圍問題。

          通常瀏覽器里, 盒模型的分為兩種模式, 兩種模式(怪異模式和標準模式)下width和height的值不同, 怪異模式的width和height包含border、padding和content, 而標準模式下的width和height只包含content, 這就是為啥有些瀏覽器渲染出來的dom標簽排版會亂。解決也很簡單, 在標簽的上面, 加上doctype的設置就好了, 讓瀏覽器統一用同一種標準去解析頁面。 怪異模式(左圖)和標準模式(右圖)的如下:

          640?wx_fmt=png

          當然, 還有用來改變盒模型width范圍的一個css3的屬性, box-sizing:

          當設置為'border-box'時, width = border + padding + content;

          當設置為'content-box'時, width = content。

          640?wx_fmt=png

          
              
          1.   <div class="wrapper z1"></div>

          2.   <div class="wrapper z2"></div>

          
              

             .wrapper{

          1.     width: 100px;

          2.     height: 50px;

          3.     padding: 10px;

          4.     background-color: #dedede;

             }

          1. .z1{

          2.     box-sizing: border-box;

          3. }

          4. .z2{

          5.     box-sizing: content-box;

             }

          那么第一個div的實際寬度為100px, 第二個div的實際寬度為120px。

          說完盒模型的padding和border, 那么再來吐槽下margin, 盒模型的margin的折疊(margin collapsing)問題, 有些也叫外邊距合并。

          通常我們說的折疊, 都是垂直方向上的折疊, 水平方向是不存在的。標準模式下, 上下兩個兄弟的塊級元素, margin是會重疊的, 并且以最大的那個間距為準(都為正數)。

          比如下面這段代碼:

          
              

             <div class="wrapper"></div>

             <div class="wrapper"></div>

          
              

             .wrapper{

          1.      width: 100px;

          2.      height: 50px;

          3.      margin: 10px;

          4.      background-color: #dedede;

          5.   }

          640?wx_fmt=png

          上圖灰色為重疊部分, 重疊10px的間距。

          既然兄弟盒模型會有margin折疊, 那么父子呢? 答案是一定的, 父子也存在margin折疊的問題, 只不過條件稍微苛刻一點, 我們一起來看下。 父子組件的折疊觸發, 要求不能有間隙, 就是父組件不能設置border或padding值, 不能有空余的內容, 且同時有margin值, 比如下面這段代碼:

          
              
          1. <div class="outer">

          2.   <div class="inner"></div>

          3. </div>

          
              

             .outer{

          1.     width: 200px;

          2.     height: 100px;

          3.     margin: 10px;

          4.     background-color: #dedede;

             }

             .inner{

          1.      width: 100px;

          2.      height: 50px;

          3.      margin: 10px;

          4.      background-color: #bcbcbc;

             }

          當然, 折疊后的空余部分, 也是取較大值, 且折疊觸發, 只存在于垂直方向。

          640?wx_fmt=png

          上圖灰色為重疊部分, 重疊10px的間距。

          剛才提到一個詞"間隙", 如果有間隙的話是不會觸發折疊的, 比如父級元素設置了padding, 或者子元素都設置了相對定位和top值等等。如下圖:

          640?wx_fmt=png

          看到這里, 我想有些同學會問了, 對于這些 margin collapsing, 有沒有一個統一的整理, 對于大轉轉的FEer, 我們當然想到了大家的前面, 請看下面:

          • Margins between a floated box and any other box do not collapse (not even between a float and its in-flow children).

          • Margins of elements that establish new block formatting contexts (such as floats and elements with 'overflow' other than 'visible') do not collapse with their in-flow children.

          • Margins of absolutely positioned boxes do not collapse (not even with their in-flow children).

          • Margins of inline-block boxes do not collapse (not even with their in-flow children).

          • The bottom margin of an in-flow block-level element always collapses with the top margin of its next in-flow block-level sibling, unless that sibling has clearance.

          • The top margin of an in-flow block element collapses with its first in-flow block-level child's top margin if the element has no top border, no top padding, and the child has no clearance.

          • The bottom margin of an in-flow block box with a 'height' of 'auto' and a 'min-height' of zero collapses with its last in-flow block-level child's bottom margin if the box has no bottom padding and no bottom border and the child's bottom margin does not collapse with a top margin that has clearance.

          • A box's own margins collapse if the 'min-height' property is zero, and it has neither top or bottom borders nor top or bottom padding, and it has a 'height' of either 0 or 'auto', and it does not contain a line box, and all of its in-flow children's margins (if any) collapse.

          這是從W3C里引用的原文, 這8條規則是特殊的不折疊的情況, 簡單翻譯過來(僅供參考):

          • 浮動的盒模型不會margin折疊

          • 創建BFC與子不折疊

          • 設置定位的盒模型不會折疊

          • 行內塊級元素的盒模型不折疊

          • 兄弟元素有間隙不折疊

          • 父子盒模型元素, 孩子元素有border、padding、有浮動就不折疊

          • height為auto、min-height為0的塊級盒模型, 和它的最后一個沒有border和padding的孩子盒模型底邊距折疊, 且孩子的底部外邊距和被清除浮動上邊距有間隙不折疊。

          • 如果min-height為0, 上下border、上下padding都為0, height為0或auto, 且沒有行內盒模型, 他的孩子節點都會折疊

          有點晦澀難懂, 大家不妨消化一下。說到這, 再補充一下, 盒模型margin折疊的計算問題, 總結了以下幾點:

          • 同為正值時, 取較大者為兩者為間距

          • 一正一負時, 正負相加為間距, 若結果為負值, 則兩者部分重合

          • 都為負值時, 兩者重合, 且重合部分為絕對值大者

          舉個例子:

          
              
          1.    <div class="wrapper z-01"></div>

          2.    <div class="wrapper z-02"></div>

          
              
          1.    .wrapper{

          2.        width: 100px;

          3.        height: 50px;

          4.        background-color: #dedede;

          5.    }

          6.    .z-01{

          7.        margin: -10px;

          8.    }

          9.    .z-02{

          10.        margin: -15px;

          11.    }

          兩者都為負值, 兩個div上下重合, 且重合間距為15px。

          暫時就想到這么多, css的學習之路任重而道遠, 盒模型又是重中之重。上面有描述不對的地方也歡迎各位同學批評指正, 也歡迎大家來到大轉轉FE做客, 一起討論一起研究前端的技術問題。志同道合的同學, 也歡迎加入我們轉轉FE團隊, 咱們一起打拼。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務

          js設計模式——代理模式proxy

          seo達人

          如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里

          什么是代理模式

          代理模式是為一個對象提供一個代用品或占位符,以便控制對它的訪問。

          (可以想象一下明星與經紀人的關系,明星是請求的本體,經紀人就是代理proxy)

          如何實現代理模式

          代理對象內部含有對本體對象的引用,因而可以與調用本體的相關方法;同時,代理對象提供與本體對象相同的接口,方便在任何時刻代理本體對象。

          例子(上代碼)

          代理模式的變體有很多,有:保護代理、虛擬代理、緩存代理、防火墻代理、遠程代理、智能引用代理、寫時復制代理。具體介紹前三種。

          (1)保護代理

          保護代理主要用于控制不同權限的對象對本體對象的訪問權限。比如很多人想訪問本體A,如果有代理B存在的話,B會首先剔除不滿足A的訪問條件的訪問者,符合條件的才能訪問。

          作用:過濾請求

          例如:權限的劃分和管理就是使用保護代理proxy來完成的。

          注冊普通用戶:code為“001”

          論壇管理者   :code為“002”

          系統管理者   :code為“003”

          游        客    :code為“000”

          論壇開放了四個基礎功能

          1,發帖

          2,帖子審核

          3,清除帖子

          4,留言

          游客不具備任何操作權限,注冊用戶只能發帖,論壇管理者可以審核以及刪帖操作,系統管理者具有所有功能權限。

          [javascript] view plain copy
          1. //用戶本體  
          2. function User(name,code){  
          3.     this.name = name ;  
          4.     this.code = code ;  
          5. } ;  
          6. User.prototype = {  
          7.     getName : function(){  
          8.         return this.name ;  
          9.     } ,  
          10.     getCode : function(){  
          11.         return this.code ;  
          12.     } ,  
          13.     post : function(){  
          14.         console.log("發帖子!") ;  
          15.     } ,  
          16.     remove : function(){  
          17.         console.log("刪除帖子!") ;  
          18.     } ,  
          19.     check : function(){  
          20.         console.log("審核帖子!") ;  
          21.     } ,  
          22.     comment : function(){  
          23.         console.log("回復帖子!") ;  
          24.     }  
          25. } ;  
          26. //代理論壇類  
          27. function Forum(user){  
          28.     this.user = user ;  
          29. } ;  
          30. Forum.prototype = {  
          31.     getUser : function(){  
          32.         return this.user ;  
          33.     } ,  
          34.     post : function(){  
          35.         if(this.user.getCode() == "001" || this.user.getCode() == "003"){  
          36.             return this.user.post() ;  
          37.         }  
          38.         console.log("沒權限發帖子!") ;  
          39.     } ,  
          40.     remove : function(){  
          41.         if(this.user.getCode() == "002" || this.user.getCode() == "003"){  
          42.             return this.user.remove() ;  
          43.         }  
          44.         console.log("沒權限刪除帖子!") ;  
          45.     } ,  
          46.     check : function(){  
          47.         if(this.user.getCode() == "002" || this.user.getCode() == "003"){  
          48.             return this.user.check() ;  
          49.         }  
          50.         console.log("沒權限審核帖子!") ;  
          51.     } ,  
          52.     comment : function(){  
          53.         if(this.user.getCode() == "003"){  
          54.             return this.user.comment() ;  
          55.         }  
          56.         console.log("沒權限回復帖子!") ;  
          57.     }  
          58. } ;  
          59. //功能測試  
          60. function ForumClient(){  
          61.      this.run = function(){  
          62.          new Forum(new User("bigbear","003")).check() ; // 審核帖子  
          63.      }  
          64.  } ;  

          在該例子中,論壇代理有與user本體相同的接口,可以在滿足條件時,執行與本體相同的代碼,與調用方法的人而言,是不透明的,我實現了調用,但不在乎是通過代理實現的,還是本體實現的。

          本案例來源:大熊君大話設計模式JavaScript

          (2)虛擬代理

          虛擬代理是將調用本體方法的請求進行管理,等到本體適合執行時,再執行。

          作用:將開銷很大的對象,延遲到真正需要它的時候再執行。

          比如:利用虛擬代理實現圖片預加載功能:

          [javascript] view plain copy
          1. /**在圖片預加載中實現虛擬代理 */  
          2. var myImage = (function(){  
          3.     var imageNode = document.createElement('img');  
          4.     document.body.appendChild(imageNode);  
          5.   
          6.     return {  
          7.         setSrc: function(src){  
          8.             imageNode.src = src;  
          9.         }  
          10.     }  
          11. })()  
          12.   
          13. //代理類  
          14. var proxyImage = (function(){  
          15.     var img = new Image();  
          16.     img.onload = function(){  
          17.         myImage.setSrc(this.src);  
          18.     }  
          19.   
          20.     return {  
          21.         setSrc: function(src){  
          22.             myImage.setSrc('本地的圖片地址');  
          23.             img.src = src; //緩存完畢之后會觸發img的onload事件  
          24.         }  
          25.     }  
          26. })()  

          比如:利用虛擬代理合并HTTP請求

          [javascript] view plain copy
          1. /**虛擬代理合并http請求 */  
          2. //通過代理函數收集一段時間的請求,一次性發送給服務器,減少頻繁的網絡請求帶來的極大開銷  
          3. //模擬向服務器發送同步請求的函數  
          4. var synchronousFile = function(id){  
          5.     console.log('開始同步上傳文件,id為:'+id);  
          6. }  
          7.   
          8. //代理類收集一段時間的同步請求,統一發送  
          9. var proxySynchronousFile = (function(){  
          10.     var cache = [], //設置緩存數組  
          11.         timer; //定時器,通過閉包訪問定時器的引用  
          12.   
          13.     return function(id){  
          14.         cache.push(id);  
          15.         if(timer){  
          16.             return;  
          17.         }  
          18.         timer = setTimeout(function(){  
          19.             synchronousFile(cache.join(','));  
          20.             clearTimeout(timer);  
          21.             timer = null;  
          22.             cache.length = 0;  
          23.         },2000)  
          24.     }  
          25. })()  
          26.   
          27. var checkbox = document.getElementsByTagName('input');  
          28.   
          29. for(var i=0,c;c=checkbox[i++];){  
          30.     c.onclick = function(){  
          31.         if(this.check === true){  
          32.             proxySynchronousFile(this.id);  
          33.         }  
          34.     }  
          35. }  

          在這些例子中,虛擬代理對請求進行擱置處理,等到合適的時機,對本體的接口進行調用,可以有效提升Web性能。

          (3)緩存代理

          緩存代理可以為開銷大的一些運算結果提供暫時性的存儲,如果再次傳進相同的參數是,直接返回結果,避免大量重復計算。

          [javascript] view plain copy
          1. /**創建緩存代理工廠 */  
          2. //將緩存代理與工廠模式相結合,創建多種運算的緩存代理  
          3. var mult = function(){  
          4.     var a = 1;  
          5.     for(var i=0;i<arguments.length;i++){  
          6.         a = a*arguments[i];  
          7.     }  
          8.     return a;  
          9. }  
          10. var plus = function(){  
          11.     var a = 0;  
          12.     for(var i=0; i<arguments.length; i++){  
          13.         a = a + arguments[i];  
          14.     }  
          15.     return a;  
          16. }  
          17. //高階函數:將函數作為參數或者返回值的函數  
          18. var proxyFactory = function(fn) {  
          19.     var cache = {}; //參數緩存列表  
          20.     return function(){  
          21.         var args = Array.prototype.join.call(arguments,',');  
          22.         if(args in cache){  
          23.             return cache[args];  
          24.         }  
          25.         //參數屬性對應的是函數  
          26.         return cache[args] = fn.apply(this,arguments);  
          27.     }  
          28. }  
          29.   
          30. //測試  
          31. var proxyMult = proxyFactory(mult),  
          32.     proxyPlus = proxyFactory(plus);  
          33.   
          34. console.log(proxyMult(1,2,3,4));  
          35. console.log(proxyMult(1,2,3,4));  
          36. console.log(proxyPlus(5,6,7,8));  
          37. console.log(proxyPlus(5,6,7,8));  

          什么情況下使用代理

          當我們需要使用的對象很復雜或者需要很長時間去構造,這時就可以使用代理模式(Proxy)。例如:如果構建一個對象很耗費時間和計算機資源,代理模式(Proxy)允許我們控制這種情況,直到我們需要使用實際的對象。一個代理(Proxy)通常包含和將要使用的對象同樣的方法,一旦開始使用這個對象,這些方法將通過代理(Proxy)傳遞給實際的對象。

          比如上面的代碼:需要花很長的時間加載很多圖片,復雜的運算過程,頻繁的多次請求處理等;都可以用到代理模式。

          小結

          代理模式的一個好處就是對外部提供統一的接口方法,而代理類在接口中實現對真實類的附加操作行為,從而可以在不影響外部調用情況下,進行系統擴展。也就是說,我要修改真實角色的操作的時候,盡量不要修改他,而是在外部在“包”一層進行附加行為,即代理類。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務

          你真的了解盒模型么

          seo達人

          如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里

          說到前端, 大家第一反應是不是都是vue、react、webpack等這些大大小小的框架或者工具, 但其實這些都是和js相關的, 真正的樣式會被大家忽略。其實真正呈現給大家看到華麗的頁面, 都是樣式才讓他們多了那份色彩。那么大家覺得簡單的css樣式, 真的簡單么? 讓我們一起來看下, 開啟css的入坑之旅, 今天一起跟大家簡單聊聊盒模型的相關問題......

          盒模型

          百度知道對此的解釋, 很有意思, 在此引用一下

          CSS盒子模型, 內容(CONTENT)就是盒子里裝的東西; 而填充(PADDING)就是怕盒子里裝的東西(貴重的)損壞而添加的泡沫或者其它抗震的輔料; 邊框(BORDER)就是盒子本身了; 至于邊界(MARGIN)則說明盒子擺放的時候的不能全部堆在一起,要留一定空隙保持通風,同時也為了方便取出。 —— 百度知道

          640?wx_fmt=png&wxfrom=5&wx_lazy=1

          這段描述很有趣, 很好的解釋margin、border、padding之間的關系, 不同模式下, 盒模型的width也是不同的, 那么好, 盒模型的第一個坑來了, width的范圍問題。

          通常瀏覽器里, 盒模型的分為兩種模式, 兩種模式(怪異模式和標準模式)下width和height的值不同, 怪異模式的width和height包含border、padding和content, 而標準模式下的width和height只包含content, 這就是為啥有些瀏覽器渲染出來的dom標簽排版會亂。解決也很簡單, 在標簽的上面, 加上doctype的設置就好了, 讓瀏覽器統一用同一種標準去解析頁面。 怪異模式(左圖)和標準模式(右圖)的如下:

          640?wx_fmt=png

          當然, 還有用來改變盒模型width范圍的一個css3的屬性, box-sizing:

          當設置為'border-box'時, width = border + padding + content;

          當設置為'content-box'時, width = content。

          640?wx_fmt=png

          
              
          1.   <div class="wrapper z1"></div>

          2.   <div class="wrapper z2"></div>

          
              

             .wrapper{

          1.     width: 100px;

          2.     height: 50px;

          3.     padding: 10px;

          4.     background-color: #dedede;

             }

          1. .z1{

          2.     box-sizing: border-box;

          3. }

          4. .z2{

          5.     box-sizing: content-box;

             }

          那么第一個div的實際寬度為100px, 第二個div的實際寬度為120px。

          說完盒模型的padding和border, 那么再來吐槽下margin, 盒模型的margin的折疊(margin collapsing)問題, 有些也叫外邊距合并。

          通常我們說的折疊, 都是垂直方向上的折疊, 水平方向是不存在的。標準模式下, 上下兩個兄弟的塊級元素, margin是會重疊的, 并且以最大的那個間距為準(都為正數)。

          比如下面這段代碼:

          
              

             <div class="wrapper"></div>

             <div class="wrapper"></div>

          
              

             .wrapper{

          1.      width: 100px;

          2.      height: 50px;

          3.      margin: 10px;

          4.      background-color: #dedede;

          5.   }

          640?wx_fmt=png

          上圖灰色為重疊部分, 重疊10px的間距。

          既然兄弟盒模型會有margin折疊, 那么父子呢? 答案是一定的, 父子也存在margin折疊的問題, 只不過條件稍微苛刻一點, 我們一起來看下。 父子組件的折疊觸發, 要求不能有間隙, 就是父組件不能設置border或padding值, 不能有空余的內容, 且同時有margin值, 比如下面這段代碼:

          
              
          1. <div class="outer">

          2.   <div class="inner"></div>

          3. </div>

          
              

             .outer{

          1.     width: 200px;

          2.     height: 100px;

          3.     margin: 10px;

          4.     background-color: #dedede;

             }

             .inner{

          1.      width: 100px;

          2.      height: 50px;

          3.      margin: 10px;

          4.      background-color: #bcbcbc;

             }

          當然, 折疊后的空余部分, 也是取較大值, 且折疊觸發, 只存在于垂直方向。

          640?wx_fmt=png

          上圖灰色為重疊部分, 重疊10px的間距。

          剛才提到一個詞"間隙", 如果有間隙的話是不會觸發折疊的, 比如父級元素設置了padding, 或者子元素都設置了相對定位和top值等等。如下圖:

          640?wx_fmt=png

          看到這里, 我想有些同學會問了, 對于這些 margin collapsing, 有沒有一個統一的整理, 對于大轉轉的FEer, 我們當然想到了大家的前面, 請看下面:

          • Margins between a floated box and any other box do not collapse (not even between a float and its in-flow children).

          • Margins of elements that establish new block formatting contexts (such as floats and elements with 'overflow' other than 'visible') do not collapse with their in-flow children.

          • Margins of absolutely positioned boxes do not collapse (not even with their in-flow children).

          • Margins of inline-block boxes do not collapse (not even with their in-flow children).

          • The bottom margin of an in-flow block-level element always collapses with the top margin of its next in-flow block-level sibling, unless that sibling has clearance.

          • The top margin of an in-flow block element collapses with its first in-flow block-level child's top margin if the element has no top border, no top padding, and the child has no clearance.

          • The bottom margin of an in-flow block box with a 'height' of 'auto' and a 'min-height' of zero collapses with its last in-flow block-level child's bottom margin if the box has no bottom padding and no bottom border and the child's bottom margin does not collapse with a top margin that has clearance.

          • A box's own margins collapse if the 'min-height' property is zero, and it has neither top or bottom borders nor top or bottom padding, and it has a 'height' of either 0 or 'auto', and it does not contain a line box, and all of its in-flow children's margins (if any) collapse.

          這是從W3C里引用的原文, 這8條規則是特殊的不折疊的情況, 簡單翻譯過來(僅供參考):

          • 浮動的盒模型不會margin折疊

          • 創建BFC與子不折疊

          • 設置定位的盒模型不會折疊

          • 行內塊級元素的盒模型不折疊

          • 兄弟元素有間隙不折疊

          • 父子盒模型元素, 孩子元素有border、padding、有浮動就不折疊

          • height為auto、min-height為0的塊級盒模型, 和它的最后一個沒有border和padding的孩子盒模型底邊距折疊, 且孩子的底部外邊距和被清除浮動上邊距有間隙不折疊。

          • 如果min-height為0, 上下border、上下padding都為0, height為0或auto, 且沒有行內盒模型, 他的孩子節點都會折疊

          有點晦澀難懂, 大家不妨消化一下。說到這, 再補充一下, 盒模型margin折疊的計算問題, 總結了以下幾點:

          • 同為正值時, 取較大者為兩者為間距

          • 一正一負時, 正負相加為間距, 若結果為負值, 則兩者部分重合

          • 都為負值時, 兩者重合, 且重合部分為絕對值大者

          舉個例子:

          
              
          1.    <div class="wrapper z-01"></div>

          2.    <div class="wrapper z-02"></div>

          
              
          1.    .wrapper{

          2.        width: 100px;

          3.        height: 50px;

          4.        background-color: #dedede;

          5.    }

          6.    .z-01{

          7.        margin: -10px;

          8.    }

          9.    .z-02{

          10.        margin: -15px;

          11.    }

          兩者都為負值, 兩個div上下重合, 且重合間距為15px。

          暫時就想到這么多, css的學習之路任重而道遠, 盒模型又是重中之重。上面有描述不對的地方也歡迎各位同學批評指正, 也歡迎大家來到大轉轉FE做客, 一起討論一起研究前端的技術問題。志同道合的同學, 也歡迎加入我們轉轉FE團隊, 咱們一起打拼。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務

          jQuery與Ajax的應用

          seo達人

          如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里


          一、Ajax的XMLHttpRrequest對象

          Ajax的核心是XMLHttpRequest對象(發送異步請求、接受響應及執行回調),它是ajax實現的關鍵

          XMLHttpRequest對象的open()方法與send()方法

          方法 描述
          open(method,url,async)

          規定請求的類型、URL 以及是否異步處理請求。

          • method:請求的類型;GET 或 POST
          • url:文件在服務器上的位置
          • async:true(異步)或 false(同步)
          send(string)

          將請求發送到服務器。

            • string:僅用于 POST 請求

          請求類型,GET 還是 POST?

          與 POST 相比,GET 更簡單也更快,并且在大部分情況下都能用。

          然而,在以下情況中,請使用 POST 請求:

          • 無法使用緩存文件(更新服務器上的文件或數據庫)
          • 向服務器發送大量數據(POST 沒有數據量限制)
          • 發送包含未知字符的用戶輸入時,POST 比 GET 更穩定也更可靠

          (1). GET請求

          [javascript] view plain copy
          1. //簡單的get請求,可能得到的是緩存的結果  
          2. xmlhttp.open("GET","demo_get.asp",true);  
          3. xmlhttp.send();  
          4. //為了避免上述情況,請向 URL 添加一個唯一的ID  
          5. xmlhttp.open("GET","demo_get.asp?t=" + Math.random(),true);  
          6. xmlhttp.send();  
          7. //若希望通過 GET 方法發送信息,請向 URL 添加信息  
          8. xmlhttp.open("GET","demo_get2.asp?fname=Bill&lname=Gates",true);  
          9. xmlhttp.send();  

          (2). POST請求

          [javascript] view plain copy
          1. //簡單的POST請求  
          2. xmlhttp.open("POST","demo_post.asp",true);  
          3. xmlhttp.send();  
          4. //如果需要像HTML表單那樣POST數據,請使用 setRequestHeader()來添加HTTP頭。  
          5. //然后在send()方法中規定您希望發送的數據  
          6. xmlhttp.open("POST","ajax_test.asp",true);  
          7. xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");  
          8. xmlhttp.send("fname=Bill&lname=Gates");  
          方法 描述
          setRequestHeader(header,value)

          向請求添加 HTTP 頭。

          • header: 規定頭的名稱
          • value: 規定頭的值


          async參數設置

          XMLHttpRequest對象如果要用于AJAX的話,其open()方法的async參數必須設置為true

          通過 AJAX,JavaScript 無需等待服務器的響應,而是:

          • 在等待服務器響應時執行其他腳本
          • 當響應就緒后對響應進行處理

          (1). 當使用 async=true 時,請規定在響應處于 onreadystatechange 事件中的就緒狀態時執行的函數:

          [javascript] view plain copy
          1. xmlhttp.onreadystatechange=function()  
          2.   {  
          3.   if (xmlhttp.readyState==4 && xmlhttp.status==200)  
          4.     {    document.getElementById("myDiv").innerHTML=xmlhttp.responseText;  
          5.     }  
          6.   }  

          (2). 當您使用 async=false 時,請不要編寫 onreadystatechange 函數 - 把代碼放到 send() 語句后面即可:

          [javascript] view plain copy
          1. xmlhttp.open("GET","test1.txt",false);  
          2. xmlhttp.send();  
          3. document.getElementById("myDiv").innerHTML=xmlhttp.responseText;  

          服務器響應

          使用 XMLHttpRequest 對象的 responseText 或 responseXML 屬性。

          屬性 描述
          responseText 獲得字符串形式的響應數據。
          responseXML 獲得 XML 形式的響應數據。


          (1). 如果來自服務器的響應并非 XML,請使用 responseText 屬性。

          responseText 屬性返回字符串形式的響應,因此您可以這樣使用:

          document.getElementById("myDiv").innerHTML=xmlhttp.responseText;


          (2). 如果來自服務器的響應是 XML,而且需要作為 XML 對象進行解析,請使用 responseXML 屬性

          [javascript] view plain copy
          1. xmlDoc=xmlhttp.responseXML;  
          2. txt="";  
          3. x=xmlDoc.getElementsByTagName("ARTIST");  
          4. for (i=0;i<x.length;i++)  
          5.   {  
          6.   txt=txt + x[i].childNodes[0].nodeValue + "<br />";  
          7.   }  
          8. document.getElementById("myDiv").innerHTML=txt;  
          onreadystatechange事件

          當請求被發送到服務器時,我們需要執行一些基于響應的任務。

          每當 readyState 改變時,就會觸發 onreadystatechange 事件。readyState 屬性存有 XMLHttpRequest 的狀態信息。

          下面是 XMLHttpRequest 對象的三個重要的屬性:

          屬性 描述
          onreadystatechange 存儲函數(或函數名),每當 readyState 屬性改變時,就會調用該函數。
          readyState

          存有 XMLHttpRequest 的狀態。從 0 到 4 發生變化。

          • 0: 請求未初始化
          • 1: 服務器連接已建立
          • 2: 請求已接收
          • 3: 請求處理中
          • 4: 請求已完成,且響應已就緒
          status

          200: "OK"

          404: 未找到頁面

          Ajax()函數示例:

          • 定義一個函數,用于異步獲取信息
          [javascript] view plain copy
          1. function Ajax(){  
          2.     //code  
          3. }  
          • 聲明一個空對象來裝入XMLHttpRequest對象
          [javascript] view plain copy
          1. var xmlHttpReq = null;  
          • 給XMLHttpRequest對象賦值
          [javascript] view plain copy
          1. if(window.ActiveXObject){  
          2.     xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");  
          3. }else if(window.XMLHttpRequest){  
          4.     xmlHttpReq = new XMLHttpRequest();  
          5. }  

          IE5、IE6是以ActiveXObject的方式引入XMLHttpRequest對象的,而其他瀏覽器的XMLHttpRequest對象是window的子對象。

            • 實例化后,使用open()方法初始化XMLHttpRequest對象,指定HTTP方法和要使用的服務器URL
          [javascript] view plain copy
          1. xmlHttpReq.open("GET","test.php",true);  
          • 因為要做一個異步調用,所以需要注冊一個XMLHttpRequest對象將調用的回調事件處理器當做它的readystate值改變時調用。當readyState值改變時,會激發一個readystatechange事件,可以使用onreadystatechange屬性來注冊該回調事件處理器。
          [javascript] view plain copy
          1. xmlHttpReq.onreadystatechange = RequestCallBack;  
          • 使用send()方法發送請求,因為這個請求使用的是HTTP的“GET”方式,所以可以在不指定參數或使用null參數的情況下調用send()方法
          [javascript] view plain copy
          1. xmlHttpReq.send(null);  

          當請求改變時,XMLHttpRequest對象調用onreadystatechange屬性注冊的事件處理器,因此在處理該響應前,事件處理器首先應該檢查readyState的值和HTTP的狀態。當請求完成加載時(readyState==4)并且已經響應成功(status==200)時,就可以調用JavaScript函數來處理該響應內容。

          [javascript] view plain copy
          1. function RequestCallBack(){  
          2.     if (xmlHttpReq.readyState == 4) {  
          3.         if (xmlHttpReq.status == 200) {  
          4.             //將xmlHttpReq.responText的值賦予id為resText的元素  
          5.             document.getElementById('resText').innerHTML = xmlHttpReq.responText;  
          6.         }  
          7.     }  
          8. }  
          二、jQuery中的Ajax

          jQuery對Ajax操作進行了封裝,在jQuery中$.ajax()方法屬于最底層的方法,第2層是load()、$.get()、$.post()方法,第3層是$.getScript()、$.getJSON()方法

          1、load()方法    通常用來從WEB服務器上獲取靜態的數據文件

          最常用的Ajax方法,能載入遠程HTML代碼并插入DOM中

          load(url[,data][,callback]);

          • url:String    請求HTML頁面的URL地址
          • data:Object    發送至服務器的key/value數據
          • callback:Function    請求完成時的回調函數,無論請求成功或失敗
          [javascript] view plain copy
          1. $(function(){  
          2.     $("#send").click(function(){  
          3.         $("#resText").load("test.html");  
          4.     })  
          5. })  
          [javascript] view plain copy
          1. <button type="button" id="send">ajax加載</button>  
          2. <div class="comment">已有評論:</div>  
          3. <div id="resText">替換內容</div>  

          test.html代碼為:

          [javascript] view plain copy
          1. <div class="comment">  
          2.     <h6>張三:</h6>  
          3.     <p class="para">沙發</p>  
          4. </div>  
          5. <div class="comment">  
          6.     <h6>李四:</h6>  
          7.     <p class="para">板凳</p>  
          8. </div>  
          9. <div class="comment">  
          10.     <h6>王五:</h6>  
          11.     <p class="para">地板</p>  
          12. </div>  

          篩選載入的HTML文檔

          load()方法的URL參數的語法結構為:“url selector”

          [javascript] view plain copy
          1. $("#resText").load("test.html .para");  

          load()傳遞方式根據參數data自動指定,沒有參數 --> GET,反之為POST   

          [javascript] view plain copy
          1. // 無參數傳遞 GET  
          2. $("#resText").load("test.html",function(){  
          3.     //code  
          4. });  
          5. // 有參數傳遞 POST  
          6. $("#resText").load("test.html",{name:"rain",age:"22"},function(){  
          7.     //code  
          8. });  

          回調函數:有三個參數,請求返回的內容、請求狀態、XMLHttpRequest對象

          [javascript] view plain copy
          1. // 回調函數  
          2. $("#resText").load("test.html",function(responseText,textStatus,XMLHttpRequest){  
          3.     //responseText  請求返回的內容  
          4.     //textStatus    請求狀態:success、error、notmodified、timeout  
          5.     //XMLHttpRequest    XMLHttpRequest對象  
          6. });  

          2、$.get()和$.post()方法    jQuery中的全局函數

          2.1 $.get()    使用GET方式來進行異步請求

          [javascript] view plain copy
          1. $.get(url[,data][,callback][,type]);  
          • url:String    請求HTML頁面的URL地址
          • data:Object    發送至服務器的key/value數據會作為QueryString附加到請求URL中
          • callback:Function    載入成功時回調函數(只有當response的返回狀態是success才調用該函數)自動將請求結果和狀態傳遞給該方法
          • type:服務器返回內容的格式,包括html、xml、script、json、text、_default
          [javascript] view plain copy
          1. $("#send").click(function(){  
          2.     $.get("get1.php",{  
          3.         username:$("#username").val(),  
          4.         content:$("#comment").val()  
          5.     },function(data,textStatus){  
          6.         // data:返回的內容  
          7.         // textStatus:請求狀態,success、error、notmodified、timeout  
          8.     })  
          9. })  

          數據格式:服務器返回的數據格式

          (1)HTML片段    較少工作量

          [javascript] view plain copy
          1. $.get("get1.php",{  
          2.     username:$("#username").val(),  
          3.     content:$("#comment").val()  
          4. },function(data,textStatus){  
          5.     // data:返回的內容  
          6.     // textStatus:請求狀態,success、error、notmodified、timeout  
          7.     $("#resText").html(data);   //將返回的數據添加到頁面上  
          8. });  

          (2) XML文檔    需要對返回的數據處理

          方便使用

          可以通過attr()、find()、filter()方法對數據進行處理

          [javascript] view plain copy
          1. $("#send").click(function(){  
          2.     $.get("get1.php", {   
          3.         username :  $("#username").val() ,   
          4.         content :  $("#content").val()    
          5.     }, function (data, textStatus){  
          6.         var username = $(data).find("comment").attr("username");  
          7.         var content = $(data).find("comment content").text();  
          8.         var txtHtml = "<div class='comment'><h6>"+username  
          9.                     +":</h6><p class='para'>"+content+"</p></div>";  
          10.         $("#resText").html(txtHtml); // 把返回的數據添加到頁面上  
          11.     });  
          12. })  
          由于期待服務器返回的數據類型為XML文檔,因此需要在服務期端設置Content-Type類型
          [javascript] view plain copy
          1. header("Content-Type:text/html; charset=utf-8");  

          (3)JSON文件    需要對返回的數據處理

          JSON相對于XML比較簡潔

          [javascript] view plain copy
          1. $("#send").click(function(){  
          2.     $.get("get3.php", {   
          3.         username :  $("#username").val() ,   
          4.         content :  $("#content").val()    
          5.     }, function (data, textStatus){  
          6.         var username = data.username;  
          7.         var content = data.content;  
          8.         var txtHtml = "<div class='comment'><h6>"+username  
          9.                     +":</h6><p class='para'>"+content+"</p></div>";  
          10.         $("#resText").html(txtHtml); // 把返回的數據添加到頁面上  
          11.     },"json");  
          12. })  

          以上三種方法對比:

          HTML返回數據最簡單,如果數據需要重用使用JSON(性能與文件大小方面有優勢),當遠程程序未知時使用XML。

          2.2 $.post()    通過 HTTP POST 請求從服務器上請求數據

          [javascript] view plain copy
          1. $.post(URL[,data][,callback]);  
          • url:String    請求的URL地址
          • data:Object    發送至服務器的key/value數據
          • callback:Function    載入成功時的回調函數

          由于POST和GET方式提交的所有數據都可以通過$_REQUEST[]來獲取,因此只需要改變jQuery函數,就可以將程序在GET請求和POST請求之間切換。

          當load()方法帶有參數傳遞時,會使用POST方式發送請求。因此也可以使用load()方法來完成同樣的功能。

          $.post()與$.get()方法的區別:
          • GET請求會將參數跟在URL后進行傳遞,而POST請求則是作為HTTP消息的實體內容發送給Web服務器。當然,在Ajax請求中,這種區別對用戶是不可見的。
          • GET方式對傳輸的數據有大小限制(通常不能大于2KB),而使用POST方式傳遞的數據量要比GET方式大得多(理論上不受限制)。
          • GET方式請求的數據會被瀏覽器緩存起來,因此其他人就可以從瀏覽器的歷史記錄中讀取到這些數據,例如賬號和密碼等。在某種情況下,GET方式會帶來嚴重的安全性問題,而POST方式相對來說就可以避免這些問題。
          • GET方式和POST方式傳遞的數據在服務器端的獲取也不相同。在PHP中,GET方式的數據可以用$_GET[]獲取,而POST方式可以用$_POST[]獲取。兩種方式都可以用$_REQUEST[]來獲取。

                上面使用load()、$.get()和$.post()方法完成了一些常規的Ajax程序,如果還需要編寫一些復雜的Ajax程序,那么就要用到jQuery中的$.ajax()方法。$.ajax()方法不僅能實現與load()、$.get()和$.post()方法同樣的功能,而且還可以設定beforeSend(提交前回調函數)、error(請求失敗后處理)、success(請求成功后處理)以及complete(請求完成后處理)回調函數,通過這些回調函數,可以給用戶更多的Ajax提示信息。另外,還有一些參數,可以設置Ajax請求的超時時間或者頁面的“最后更改”狀態等。

          3、$.getScript()和$.getJSON()方法

          3.1 $.getScript()

          有時候,在頁面初次加載時就取得所需的全部JavaScript文件是完全沒有必要的。雖然可以在需要哪個JavaScript文件時,動態地創建<script>標簽

          [javascript] view plain copy
          1. $(document.createElement("script").attr("src","test.js")).appenChild("head");  
          2. //或  
          3. $("<script type='text/javscript' src='test.js'></script>").appendChild("head");  
          上述方法不理想,jQuery又提供了$.getScript()方法
          [javascript] view plain copy
          1. $(function(){  
          2.     $("#btn").click(function(){  
          3.         $.getScript("test.js");  
          4.     })  
          5. })  
          有回調函數
          [javascript] view plain copy
          1. $.getScript("test.js",function(){  
          2.     $(element).click(function(){  
          3.         $(element).animate({backgroundcolor:'pink'},1000)  
          4.         .animate({backgroundcolor:'coral'},1000);  
          5.     })  
          6. });  

          3.2 $.getJSON()方法    用于加載JSON文件,用法同$.getScript()方法

          [javascript] view plain copy
          1. $(function(){  
          2.     $("#btn").click(function(){  
          3.         $.getJSON("test.json");  
          4.     })  
          5. })  

          上面函數雖然加載了JSON代碼,但是并沒有告訴JS對返回的數據如何處理,所以需要回調函數

          [javascript] view plain copy
          1. $(function(){  
          2.     $("#btn").click(function(){  
          3.         $.getJSON("test.json",function(){  
          4.             //data:返回的數據  
          5.         });  
          6.     })  
          7. })  

          jQuery遍歷方法  -->  $.each()方法    遍歷對象和數組

          $.each(data,callback)    // 為全局函數   不同于each()方法

          • data:數組或對象
          • callback:回調函數,有兩個參數(對象的成員或數組的索引,對應變量或內容)

          4、$.ajax()方法    jQuery最底層的Ajax實現

          $.ajax(options);

          參數名稱  類型  說明
          url String (默認為當前頁地址)發送請求的地址
          type String

           請求方式(POST/GET)默認GE

          注意其他HTTP請求方法,例如PUT和DELETE,僅部分瀏覽器支持

          timeout Number

           設置請求超時時間(毫秒)

          此設置將覆蓋$.ajaxSetup()方法的全局設置

          data Object/String

           發送到服務器的數據。如果已經不是字符串,將自動轉換為字符串格式。

          GET請求中將附加在URL后。防止這種自動轉換,可以查看processData選項。

          對象必須為key/value格式

              例如:{foo1:"bar1",foo2:"bar2"}轉換為&foo1=bar1&foo2=bar2。

          如果是數組,jQuery將自動為不同的值對應同一個名稱

              例如:{foo:["bar1","bar2"]}轉換為&foo=bar1&foo=bar2

          dataType String

          預期服務器返回的數據類型。

          如果不指定,jQuery將自動根據HTTP包MIME信息返回responseXML或responseText,

          并作為回調函數參數傳遞。

          可用類型,

          xml:返回XML文檔,可用jQuery處理

          html:返回純文本HTML信息,包含的script標簽會在插入DOM是執行

          script:返回純文本的JavaScript代碼,不會自動緩存結果。除非設置cache參數

                      注意在遠程請求時(不在同一個域下),所有POST請求都將轉換為GET請求

          json:返回json數據

          jsonp:jsonp格式,使用jsonp形式調用參數時,myurl?callback=?

          jQuery:將自動替換后一個“?”為正確的函數名,以執行回調函數

          text:返回純文本字符串

          beforeSend Function

          發送請求前可以修改XMLHttpRequest對象的函數例如添加自定義HTTP頭。

          在beforeSend中如果返回false可以取消本次Ajax請求。XMLHttpRequest對象是唯一的函數

          function(XMLHttpRequest){

              this;//調用本次Ajax請求時傳遞的options參數

          }

          complete Function

           請求完成后調用的函數(請求成功或失敗時均調用)

          參數:XMLHttpRequest對象和一個描述成功請求類型的字符串

          function(XMLHttpRequest,textStatus){

              this;//調用本次Ajax請求時傳遞的options參數

          }

          success Function

          請求完成后調用的函數(請求成功或失敗時均調用)

          參數:(1) 由服務器返回,并根據datatype參數進行設置

                     (2) 描述狀態的字符串

          function(XMLHttpRequest,textStatus){

              //data可能是XMLDoc、jsonObj、html、text等

              this;//調用本次Ajax請求時傳遞的options參數

          }

          error Function

           請求失敗時被調用的函數

          參數:(1) XMLHttpRequest對象

                     (2) 錯誤信息

                     (3) 捕獲的錯誤對象(可選)

          function(XMLHttpRequest,textStatus,errorThrown){

              //通常情況下textStatus和errorThrown只有其中一個包含信息

              this;//調用本次Ajax請求時傳遞的options參數

          }

          global Boolean

           默認為true。表示是否觸發全局Ajax事件。設置為false將不會觸發全局Ajax事件

          AjaxStart或AjaxStop可用于控制各種Ajax事件

          前面用到的$.load()、$.get()、$.post()、$.getScript()和$.getJSON()這些方法,都是基于$.ajax()方法構建的,$.ajax()方法是jQuery最底層的Ajax實現,因此可以用它來代替前面的所有方法。

          [javascript] view plain copy
          1. $(function(){  
          2.     $("#btn").click(function(){  
          3.         $.getScript("test.js");  
          4.     })  
          5. })  

          可被替換為

          [javascript] view plain copy
          1. $(function(){  
          2.     $("#btn").click(function(){  
          3.         $.ajax({  
          4.             type:"GET",  
          5.             url:"test.js",  
          6.             dataType:"script"  
          7.         });  
          8.     });  
          9. })  
          [javascript] view plain copy
          1. $(function(){  
          2.     $("#btn").click(function(){  
          3.         $.getJSON("test.json",function(data){  
          4.                 $("#resText").empty();  
          5.                 var html = " ";  
          6.                 $.each(data,function(commentIndex,comment){  
          7.                     html+='<div class="comment"><h6>'+comment['username']  
          8.                          +'</h6><p class="para">'+comment['content']  
          9.                          +'</p></div>'  
          10.                 })  
          11.                 $("resText").html(html);  
          12.             }  
          13.         });  
          14.     });  
          15. })  

          可被替換為

          [javascript] view plain copy
          1. $(function(){  
          2.     $("#btn").click(function(){  
          3.         $.ajax({  
          4.             type:"GET",  
          5.             url:"test.json",  
          6.             dataType:"json",  
          7.             success:function(data){  
          8.                 $("#resText").empty();  
          9.                 var html = " ";  
          10.                 $.each(data,function(commentIndex,comment){  
          11.                     html+='<div class="comment"><h6>'+comment['username']  
          12.                          +'</h6><p class="para">'+comment['content']  
          13.                          +'</p></div>'  
          14.                 })  
          15.                 $("resText").html(html);  
          1. })
          } }); });
          三、序列化元素

          1.serialize()方法

          異步提交表單,并將服務器返回的數據顯示到當前頁面中

          [javascript] view plain copy
          1. $.get("get1.php",{  
          2.     username:$("#username").val(),  
          3.     content:$("#comment").val()  
          4. },function(data,textStatus){  
          5.     // data:返回的內容  
          6.     // textStatus:請求狀態,success、error、notmodified、timeout  
          7.     $("#resText").html(data);   //將返回的數據添加到頁面上  
          8. });  

          serialize()方法也是作用于一個jQuery對象,它能夠將DOM元素內容序列化為字符串,用于Ajax請求??蓪⑸鲜龃a簡化為:

          [javascript] view plain copy
          1. $.get("get1.php",$("#form1").serialize(),function(data,textStatus){  
          2.     // data:返回的內容  
          3.     // textStatus:請求狀態,success、error、notmodified、timeout  
          4.     $("#resText").html(data);   //將返回的數據添加到頁面上  
          5. });  

          serialize()方法作用于jQuery對象,所以不光只有表單能使用它,其他選擇器選取的元素也都能使用它,如以下jQuery代碼:

          [javascript] view plain copy
          1. $(":checkbox,:radio").serialize();  

          把復選框和單選框的值序列化為字符串形式,只會將選中的值序列化。

          2.serializeArray()方法

          該方法不是返回字符串,而是將DOM元素序列化后,返回JSON格式的數據

          3.$.param()方法

          它是serialize()方法的核心,用來對一個數組或對象按照key/value進行序列化。

          比如將一個普通的對象序列化:

          四、jQuery中的全局事件

          jQuery簡化Ajax操作不僅體現在調用Ajax方法和處理響應方面,而且還體現在對調用Ajax方法的過程中的HTTP請求的控制。通過jQuery提供的一些自定義全局函數,能夠為各種與Ajax相關的事件注冊回調函數。例如當Ajax請求開始時,會觸發ajaxStart()方法的回調函數;當Ajax請求結束時,會觸發ajaxStop()方法的回調函數。這些方法都是全局的方法,因此無論創建它們的代碼位于何處,只要有Ajax請求發生時,就會觸發它們。

          有時,當網頁加載過慢時,就需要為網頁添加一個提示信息,常用的提示信息是“加載中…”,代碼如下:

          [javascript] view plain copy
          1. <div class="loading">加載中...</div>  
          然后通過CSS控制元素隱藏,當Ajax請求開始的時候,將此元素顯示,用來提示用戶Ajax請求正在進行。當Ajax請求結束后,將此元素隱藏。
          [javascript] view plain copy
          1. $("$loading").ajaxStart(function(){  
          2.     $(this).show();  
          3. }).ajaxStop(function(){  
          4.     $(this).hide();  
          5. });  

          jQuery的Ajax全局事件中還有幾個方法,也可以在使用Ajax方法的過程中為其帶來方便。


          方法名稱  說明
          ajaxComplete(callback) Ajax請求完成時執行的函數
          ajaxError(callback) Ajax請求發生錯誤時執行的函數,捕捉到的錯誤可以作為最后一個參數傳遞
          ajaxSend(callback) Ajax請求發送前執行的函數
          ajaxSuccess(callback) Ajax請求成功時執行的函數

          注意:

          1,如果想使某個Ajax請求不受全局方法的影響,那么可以在使用$.ajax(options)方法時,將參數中的global設置為false,jQuery代碼如下

          [javascript] view plain copy
          1. $.ajax({  
          2.     url:"test.html",  
          3.     global:false  
          4. });  

          2,在jQuery1.5版本之后,如果Ajax請求不觸發全局方法,那么可以設置:


          [javascript] view plain copy
          1. $.ajaxPrefilter(function(options){  
          2.     options.global = true;  
          3. })  

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務




          獲取json數據后在 地圖上打點,根據 json不斷移動點的位置

          seo達人

          如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里

          <?php echo <<<_END <!doctype html>
          <html>
          <head>
              <meta charset="utf-8">
              <meta http-equiv="X-UA-Compatible" content="IE=edge">
              <meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
              <title>點標記</title>
              <link rel="stylesheet" />
              <style>
                  .marker {
                      color: #ff6600; padding: 4px 10px;
                      border: 1px solid #fff; white-space: nowrap;
                      font-size: 12px;
                      font-family: "";
                      background-color: #0066ff;  } </style>
              <script src="http://webapi.amap.com/maps?v=1.3&key=您申請的key值"></script>
              <script type="text/javascript" src="http://cache.amap.com/lbs/static/addToolbar.js"></script>
          </head>
          <body>
          <div id="container"></div>
          <script> var marker, map = new AMap.Map("container", {
                  resizeEnable: true, center: [126.60580555556, 45.702363888889], zoom: 13 }); var getJSON = function(url) { return new Promise(function(resolve, reject) { var xhr = new XMLHttpRequest();
                  xhr.open('get', url, true);
                  xhr.responseType = 'json';
                  xhr.onload = function() { var status = xhr.status; if (status == 200) {
                      resolve(xhr.response);
                    } else {
                      reject(status);
                    }
                  };
                  xhr.send();
                });
              };
          
              getJSON('http://web.cellpies.com/api/driving/getVehicleLocationPoints?vehicleDeviceId=0400000000030603&timeType=4&startTime=2017-03-17%2013:00:00&stopTime=2017-03-17%2014:00:00').then(function(jdata) { //alert('Your Json result is:  ' + jdata); //you can comment this, i used it to debug
                  //alert(jdata.data[0].gpsx);
                  //alert(jdata.data[0].gpsy); window.i=0; //addMarker(jdata.data[i].gpsx,jdata.data[i].gpsy); setInterval(function () { addMarker(jdata.data[window.i].gpsx,jdata.data[window.i].gpsy); },"1000");
          
              }, function(status) { //error detection.... alert('Something went wrong.');
              }); // 實例化點標記 function addMarker(v1,v2) {
          
               window.i+=10;
                  marker = new AMap.Marker({
                      icon: "http://webapi.amap.com/theme/v1.3/markers/n/mark_b.png", position: [v1,v2]
                  });
                  marker.setMap(map);
              } </script>
          </body>
          </html>
          
          </script>
          </body>
          </html> _END; ?>

          效果圖

          -----------------------------------------------------------------------更新---------------------------------------------------------

          去掉連續顯示多個點,每次只顯示一個點

          <?php echo<<<_END <!doctype html>
          <html>
          <head>
              <meta charset="utf-8">
              <meta http-equiv="X-UA-Compatible" content="IE=edge">
              <meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
              <title>點標記</title>
              <link rel="stylesheet" />
              <style>
                  .marker {
                      color: #ff6600; padding: 4px 10px;
                      border: 1px solid #fff; white-space: nowrap;
                      font-size: 12px;
                      font-family: "";
                      background-color: #0066ff;  } </style>
              <script src="http://webapi.amap.com/maps?v=1.3&key=您申請的key值"></script>
              <script type="text/javascript" src="http://cache.amap.com/lbs/static/addToolbar.js"></script>
          </head>
          <body>
          <div id="container"></div>
          <script> var marker, map = new AMap.Map("container", {
                  resizeEnable: true, center: [126.60580555556, 45.702363888889], zoom: 13 }); var getJSON = function(url) { return new Promise(function(resolve, reject) { var xhr = new XMLHttpRequest();
                  xhr.open('get', url, true);
                  xhr.responseType = 'json';
                  xhr.onload = function() { var status = xhr.status; if (status == 200) {
                      resolve(xhr.response);
                    } else {
                      reject(status);
                    }
                  };
                  xhr.send();
                });
              };
          
              getJSON('http://web.cellpies.com/api/driving/getVehicleLocationPoints?vehicleDeviceId=0400000000030603&timeType=4&startTime=2017-03-17%2013:00:00&stopTime=2017-03-17%2014:00:00').then(function(jdata) {
                  addMarker(jdata.data[0].gpsx,jdata.data[0].gpsy);
                  window.i=1; //updateMarker(jdata.data[1].gpsx,jdata.data[1].gpsy); setInterval(function () { updateMarker(jdata.data[window.i].gpsx,jdata.data[window.i].gpsy); },"1000");
          
              }, function(status) { //error detection.... alert('Something went wrong.');
              }); // 實例化點標記 function addMarker(v1,v2) {
          
                  marker = new AMap.Marker({
                      icon: "http://webapi.amap.com/theme/v1.3/markers/n/mark_b.png", position: [v1,v2]
                  });
                  marker.setMap(map);
              } function updateMarker(v1,v2) { //在地圖上更新標記
                  // 自定義點標記內容 window.i+=10; var markerContent = document.createElement("div"); // 點標記中的圖標 var markerImg = document.createElement("img");
                  markerImg.className = "markerlnglat";
                  markerImg.src = "http://webapi.amap.com/theme/v1.3/markers/n/mark_r.png";
                  markerContent.appendChild(markerImg); // 點標記中的文本 var markerSpan = document.createElement("span");
                  markerSpan.className = 'marker';
                  markerSpan.innerHTML = "Hi,我換新裝備啦!";
                  markerContent.appendChild(markerSpan);
          
                  marker.setContent(markerContent); //更新點標記內容 marker.setPosition([v1,v2]); //更新點標記位置  } </script>
          </body>
          </html>
          
          </script>
          </body>
          </html> _END; ?>

           

          涉及setInterval傳參的問題。

          發現用addMarker(jdata.data[i].gpsx,jdata.data[i].gpsy);時程序可正常運行,但是將該函數 放到setInterval中后卻出現了問題,可通過閉包解決。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 平面設計服務

          js瀏覽器兼容問題總結及解決辦法

          seo達人

          如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里

          javascript部分

          1. document.form.item 問題 
            問題: 
            代碼中存在 document.formName.item(“itemName”) 這樣的語句,不能在FF下運行 
            解決方法: 
            改用 document.formName.elements[“elementName”]

          2. 集合類對象問題 
            問題: 
            代碼中許多集合類對象取用時使用(),IE能接受,FF不能 
            解決方法: 
            改用 [] 作為下標運算,例:

          document.getElementsByName("inputName")(1) 改為 document.getElementsByName("inputName")[1]
              
          • 1
          1. window.event 
            問題: 
            使用 window.event 無法在FF上運行 
            解決方法: 
            FF的 event 只能在事件發生的現場使用,此問題暫無法解決??梢园?event 傳到函數里變通解決:
          onMouseMove = "functionName(event)" function functionName (e) { e = e || window.event;
              ......
          }
              
          • 1
          • 2
          • 3
          • 4
          • 5
          1. HTML對象的 id 作為對象名的問題 
            問題: 
            在IE中,HTML對象的 ID 可以作為 document 的下屬對象變量名直接使用,在FF中不能 
            解決方法: 
            使用對象變量時全部用標準的 getElementById(“idName”)

          2. 用 idName 字符串取得對象的問題 
            問題: 
            在IE中,利用 eval(“idName”) 可以取得 id 為 idName 的HTML對象,在FF中不能 
            解決方法: 
            用 getElementById(“idName”) 代替 eval(“idName”)

          3. 變量名與某HTML對象 id 相同的問題 
            問題: 
            在FF中,因為對象 id 不作為HTML對象的名稱,所以可以使用與HTML對象 id 相同的變量名,IE中不能 
            解決方法: 
            在聲明變量時,一律加上 var ,以避免歧義,這樣在IE中亦可正常運行 
            最好不要取與HTML對象 id 相同的變量名,以減少錯誤

          4. event.x 與 event.y 問題 
            問題: 
            在IE中,event 對象有x,y屬性,FF中沒有 
            解決方法: 
            在FF中,與 event.x 等效的是 event.pageX ,但event.pageX IE中沒有 
            故采用 event.clientX 代替 event.x ,在IE中也有這個變量 
            event.clientX 與 event.pageX 有微妙的差別,就是滾動條 
            要完全一樣,可以這樣: 
            mX = event.x ? event.x : event.pageX; 
            然后用 mX 代替 event.x

          5. 關于frame 
            問題: 
            在IE中可以用 window.testFrame 取得該frame,FF中不行 
            解決方法:

          window.top.document.getElementById("testFrame").src = 'xx.htm' window.top.frameName.location = 'xx.htm'
              
          • 1
          • 2
          1. 取得元素的屬性 
            在FF中,自己定義的屬性必須 getAttribute() 取得

          2. 在FF中沒有 parentElement,parement.children 而用 parentNode,parentNode.childNodes 
            問題: 
            childNodes 的下標的含義在IE和FF中不同,FF的 childNodes 中會插入空白文本節點 
            解決方法: 
            可以通過 node.getElementsByTagName() 來回避這個問題 
            問題: 
            當html中節點缺失時,IE和FF對 parentNode 的解釋不同,例如:

          <form> <table> <input/> </table> </form>
              
          • 1
          • 2
          • 3
          • 4
          • 5

          FF中 input.parentNode 的值為form,而IE中 input.parentNode 的值為空節點 
          問題: 
          FF中節點自己沒有 removeNode 方法 
          解決方法: 
          必須使用如下方法 node.parentNode.removeChild(node)

          1. const 問題 
            問題: 
            在IE中不能使用 const 關鍵字 
            解決方法: 
            以 var 代替

          2. body 對象 
            FF的 body 在 body 標簽沒有被瀏覽器完全讀入之前就存在,而IE則必須在 body 完全被讀入之后才存在 
            這會產生在IE下,文檔沒有載入完時,在body上appendChild會出現空白頁面的問題 
            解決方法: 
            一切在body上插入節點的動作,全部在onload后進行

          3. url encoding 
            問題: 
            一般FF無法識別js中的& 
            解決方法: 
            在js中如果書寫url就直接寫&不要寫&

          4. nodeName 和 tagName 問題 
            問題: 
            在FF中,所有節點均有 nodeName 值,但 textNode 沒有 tagName 值,在IE中,nodeName 的使用有問題 
            解決方法: 
            使用 tagName,但應檢測其是否為空

          5. 元素屬性 
            IE下 input.type 屬性為只讀,但是FF下可以修改

          6. document.getElementsByName() 和 document.all[name] 的問題 
            問題: 
            在IE中,getElementsByName()、document.all[name] 均不能用來取得 div 元素 
            是否還有其它不能取的元素還不知道(這個問題還有爭議,還在研究中)

          7. 調用子框架或者其它框架中的元素的問題 
            在IE中,可以用如下方法來取得子元素中的值

          document.getElementById("frameName").(document.)elementName
          window.frames["frameName"].elementName
              
          • 1
          • 2

          在FF中則需要改成如下形式來執行,與IE兼容:

          window.frames["frameName"].contentWindow.document.elementName window.frames["frameName"].document.elementName
              
          • 1
          • 2
          1. 對象寬高賦值問題 
            問題: 
            FireFox中類似 obj.style.height = imgObj.height 的語句無效 
            解決方法: 
            統一使用 obj.style.height = imgObj.height + “px”;

          2. innerText的問題 
            問題: 
            innerText 在IE中能正常工作,但是 innerText 在FireFox中卻不行 
            解決方法: 
            在非IE瀏覽器中使用textContent代替innerText

          3. event.srcElement和event.toElement問題 
            問題: 
            IE下,even對象有srcElement屬性,但是沒有target屬性;Firefox下,even對象有target屬性,但是沒有srcElement屬性 
            解決方法:

          var source = e.target || e.srcElement; var target = e.relatedTarget || e.toElement;
              
          • 1
          • 2
          1. 禁止選取網頁內容 
            問題: 
            FF需要用CSS禁止,IE用JS禁止 
            解決方法:
          IE: obj.onselectstart = function() {return false;}
          FF: -moz-user-select:none;
              
          • 1
          • 2
          1. 捕獲事件 
            問題: 
            FF沒有setCapture()、releaseCapture()方法 
            解決方法:
          IE: obj.setCapture(); obj.releaseCapture(); FF: window.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP); window.releaseEvents(Event.MOUSEMOVE|Event.MOUSEUP); if (!window.captureEvents) {
                     o.setCapture(); }else {
                     window.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP); }
              if (!window.captureEvents) {
                     o.releaseCapture(); }else {
                     window.releaseEvents(Event.MOUSEMOVE|Event.MOUSEUP); }
              
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16

          CSS部分

          div類

          1. 居中問題 
            div里的內容,IE默認為居中,而FF默認為左對齊 
            可以嘗試增加代碼margin:auto

          2. 高度問題 
            兩上下排列或嵌套的div,上面的div設置高度(height),如果div里的實際內容大于所設高度,在FF中會出現兩個div重疊的現象;但在IE中,下面的div會自動給上面的div讓出空間 
            所以為避免出現層的重疊,高度一定要控制恰當,或者干脆不寫高度,讓他自動調節,比較好的方法是 height:100%; 
            但當這個div里面一級的元素都float了的時候,則需要在div塊的最后,閉和前加一個沉底的空div,對應CSS是:

          .float_bottom { clear:both; font-size:0px; margin:0; line-height:0px; }
              
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          1. clear:both; 
            不想受到float浮動的,就在div中寫入clear:both;

          2. IE浮動 margin 產生的雙倍距離

          #box { float:left; width:100px; margin:0 0 0 100px; //這種情況之下IE會產生200px的距離 display:inline; //使浮動忽略 }
              
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          1. padding 問題 
            FF設置 padding 后,div會增加 height 和 width,但IE不會 (* 標準的 XHTML1.0 定義 dtd 好像一致了) 
            高度控制恰當,或嘗試使用 height:100%; 
            寬度減少使用 padding 
            但根據實際經驗,一般FF和IE的 padding 不會有太大區別,div 的實際寬 = width + padding ,所以div寫全 width 和 padding,width 用實際想要的寬減去 padding 定義

          2. div嵌套時 y 軸上 padding 和 marign 的問題 
            FF里 y 軸上 子div 到 父div 的距離為 父padding + 子marign 
            IE里 y 軸上 子div 到 父div 的距離為 父padding 和 子marign 里大的一個 
            FF里 y 軸上 父padding=0 且 border=0 時,子div 到 父div 的距離為0,子marign 作用到 父div 外面

          3. padding,marign,height,width 的傻瓜式解決技巧 
            注意是技巧,不是方法: 
            寫好標準頭

          <!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">
              
          • 1
          • 2

          高盡量用padding,慎用margin,height盡量補上100%,父級height有定值子級height不用100%,子級全為浮動時底部補個空clear:both的div 
          寬盡量用margin,慎用padding,width算準實際要的減去padding

          列表類

          1. ul 標簽在FF中默認是有 padding 值的,而在IE中只有margin有值 
            先定義 ul {margin:0;padding:0;}

          2. ul和ol列表縮進問題 
            消除ul、ol等列表的縮進時,樣式應寫成: {list-style:none;margin:0px;padding:0px;}

          顯示類

          1. display:block,inline 兩個元素 
            display:block; //可以為內嵌元素模擬為塊元素 
            display:inline; //實現同一行排列的的效果 
            display:table; //for FF,模擬table的效果 
            display:block 塊元素,元素的特點是: 
            總是在新行上開始; 
            高度,行高以及頂和底邊距都可控制; 
            寬度缺省是它的容器的100%,除非設定一個寬度

          IE: filter: progid: DXImageTransform.Microsoft.Alpha(style=0,opacity=60); IE: filter: alpha(opacity=10); FF: opacity:0.6; FF: -moz-opacity:0.10;
              
          • 1
          • 2
          • 3
          • 4

          最好兩個都寫,并將opacity屬性放在下面


          css和js的瀏覽器兼容問題匯總2009-05-31 13:48首先談一下瀏覽器,雖然現在ie依然是瀏覽器市場的老大,大約占有67%的份額,但是由于其各方面的欠缺,用戶開始選擇其他瀏覽器作為自己瀏覽網頁的主要 工具,比如firefox、theworld、maxthon、chrome、opera等等,在用戶使用比較多的瀏覽器中,分為2大派系 - ie內核和非ie內核,像theworld、maxthon、greenbrower等等都屬于ie內核,而firefox、chrome、opera則 為非ie內核,眾多的瀏覽器使我們的web程序就出現了兼容問題,像ie就有ie 6、ie7、ie8之分,同樣的樣式控制和js腳本,在不同的ie版本中也會出現不同的效果,甚至bug,何況在非ie內核的firefox、 chrome、opera了。從市場份額分析,目前ie依然是瀏覽器市場老大,并會在很長一段時間內很難改變,不過我們不能忽略firefox以及其他瀏 覽器的快速成長,未來我們沒有辦法估計,很多初級用戶還沒有看到其他非ie內核的優勢,當他們發現時,我們的在去滿足他們的需求是否已經晚了呢,所以我們 必須做到多瀏覽器的兼容。現在市場上大多web開發著選擇兼容ie7和firefox作為主要兼容對象,這兩款也是目前用戶使用最多的,那好我們就主要講 兼容這兩款瀏覽器。

          眾多的瀏覽器使我們就要面臨多種瀏覽器測試的尷尬,比如ie在一臺機器上只能安裝一個版本,我們要測試程序在ie 3個版本中的顯示效果,就要在安裝3個版本的機器上分別測試將是一件非常繁瑣的事情,這里推薦一款工具,ietester可以同時測試3個版本的ie程 序,非常不錯。至于其他瀏覽器在同一臺機器上安裝是沒有問題的,所以我們準備好了測試環境。

          Firefox是一款有著豐富插件的瀏覽器,這里我推薦3款web開發人員必備的開發工具 - Firebug、web developer、ie tab。 
          Firebug 是Firefox下的一款開發類插件,現屬于Firefox的五星級強力推薦插件之一。它集HTML查看和編輯、Javascript控制臺、網絡狀況監 視器于一體,是開發JavaScript、CSS、HTML和 Ajax的得力助手。Firebug如同一把精巧的瑞士軍刀,從各個不同的角度剖析Web頁面內部的細節層面,給Web開發者帶來很大的便利。 
          Web Developer 插件以工具欄的形式對網頁的(X)HTML、腳本、多媒體、CSS、緩存、圖象等多方面的實用工具。使我們能輕易的獲得網頁的更多信息,使我們進一步的了解當前所瀏覽的網頁。 
          ie tab是firefox下一款firefox和ie互相切換的插件,這樣開發人員可以很輕松的一鍵查看2中主流瀏覽器的兼容效果。 
          以上3款工具具體使用方法到Google、baidu中搜索使用關鍵字即可。 
          debugBar是在ie中類似firebug的工具,不過功能就差很遠了,不過這里也推薦一下。

          Firefox瀏覽器良好支持W3C標準,是目前對CSS支持最好的瀏覽器,而ie是出現的比較早,在w3c支持方面做的一直不是很好,所以兩種瀏覽器在很多方面不盡相同。 
          下面總結一下這兩種瀏覽器的兼容問題: 
          1.集合類對象問題 
          說明:IE下,可以使用()或[]獲取集合類對象; 
          Firefox下,只能使用[]獲取集合類對象. 
          解決方法:統一使用[]獲取集合類對象.

          2.HTML對象獲取問題 
          FireFox:document.getElementById(“idName”); 
          ie:document.idname或者document.getElementById(“idName”). 
          解決辦法:統一使用document.getElementById(“idName”);

          3.const問題 
          說明:Firefox下,可以使用const關鍵字或var關鍵字來定義常量; 
          IE下,只能使用var關鍵字來定義常量. 
          解決方法:統一使用var關鍵字來定義常量.

          4.window.event問題 
          說明:window.event只能在IE下運行,而不能在Firefox下運行,這是因為Firefox的event只能在事件發生的現場使用. Firefox必須從源處加入event作參數傳遞。Ie忽略該參數,用window.event來讀取該event。 
          解決方法: 
          IE&Firefox: 
          Submitted(event)”/> …

          function Submitted(evt) { evt=evt?evt:(window.event?window.event:null); }

          5.event.x與event.y問題 
          說明:IE下,even對象有x,y屬性,但是沒有pageX,pageY屬性; 
          Firefox下,even對象有pageX,pageY屬性,但是沒有x,y屬性. 
          解決方法:使用mX(mX = event.x ? event.x : event.pageX;)來代替IE下的event.x或者Firefox下的event.pageX.

          6.event.srcElement問題 
          說明:IE下,event對象有srcElement屬性,但是沒有target屬性; 
          Firefox下,even對象有target屬性,但是沒有srcElement屬性. 
          解 決方法:使用obj(obj = event.srcElement ? event.srcElement : event.target;)來代替IE下的event.srcElement或者Firefox下的event.target. 請同時注意event的兼容性問題。

          7.window.location.href問題 
          說明:IE或者Firefox2.0.x下,可以使用window.location或window.location.href; 
          Firefox1.5.x下,只能使用window.location. 
          解決方法:使用window.location來代替window.location.href.

          8.模態和非模態窗口問題 
          說明:IE下,可以通過showModalDialog和showModelessDialog打開模態和非模態窗口;Firefox下則不能. 
          解決方法:直接使用window.open(pageURL,name,parameters)方式打開新窗口。 
          如果需要將子窗口中的參數傳遞回父窗口,可以在子窗口中使用window.opener來訪問父窗口. 
          例如:var parWin = window.opener; parWin.document.getElementById(“Aqing”).value = “Aqing”;

          9.frame問題 
          以下面的frame為例: 

          (1)訪問frame對象: 
          IE:使用window.frameId或者window.frameName來訪問這個frame對象. frameId和frameName可以同名。 
          Firefox:只能使用window.frameName來訪問這個frame對象. 
          另外,在IE和Firefox中都可以使用window.document.getElementById(“frameId”)來訪問這個frame對象.

          (2)切換frame內容: 
          在 IE和Firefox中都可以使用window.document.getElementById(“testFrame”).src = “xxx.html”或window.frameName.location = “xxx.html”來切換frame的內容. 
          如果需要將frame中的參數傳回父窗口(注意不是opener,而是parent frame),可以在frame中使用parent來訪問父窗口。例如:parent.document.form1.filename.value=”Aqing”;

          10.body問題 
          Firefox的body在body標簽沒有被瀏覽器完全讀入之前就存在;而IE的body則必須在body標簽被瀏覽器完全讀入之后才存在.

          1. 事件委托方法 
            IE:document.body.onload = inject; //Function inject()在這之前已被實現 
            Firefox:document.body.onload = inject();

          2. firefox與IE的父元素(parentElement)的區別 
            IE:obj.parentElement 
            firefox:obj.parentNode 
            解決方法: 因為firefox與IE都支持DOM,因此使用obj.parentNode是不錯選擇.

          13.cursor:hand VS cursor:pointer 
          firefox不支持hand,但ie支持pointer 
          解決方法: 統一使用pointer

          14.innerText在IE中能正常工作,但是innerText在FireFox中卻不行. 需用textContent。 
          解決方法: 
          if(navigator.appName.indexOf(“Explorer”) > -1){ 
          document.getElementById(‘element’).innerText = “my text”; 
          } else{ 
          document.getElementById(‘element’).textContent = “my text”; 
          }

          1. FireFox中設置HTML標簽的style時,所有位置性和字體尺寸的值必須后跟px。這個ie也是支持的。

          2. ie,firefox以及其它瀏覽器對于 table 標簽的操作都各不相同, 
            在ie中不允許對table和tr的innerHTML賦值,使用js增加一個tr時,使用appendChild方法也不管用。 
            解決方法:

          //向table追加一個空行:
          var   row   =   otable.insertRow(-1); var   cell   =   document.createElement("td"); cell.innerHTML = "   ";  cell.className = "XXXX";  row.appendChild(cell);
              
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          1. padding 問題 
            padding 5px 4px 3px 1px FireFox無法解釋簡寫, 
            必須改成 padding-top:5px; padding-right:4px; padding-bottom:3px; padding-left:1px;

          2. 消除ul、ol等列表的縮進時 
            樣式應寫成:list-style:none;margin:0px;padding:0px; 
            其中margin屬性對IE有效,padding屬性對FireFox有效

          3. CSS透明 
            IE:filter:progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=60)。 
            FF:opacity:0.6。

          4. CSS圓角 
            IE:不支持圓角。

          FF: -moz-border-radius:4px,或者-moz-border-radius-topleft:4px;-moz-border- radius-topright:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius- bottomright:4px;。
              
          • 1
          1. CSS雙線凹凸邊框
          IE:border:2px   outset;。 
          FF: -moz-border-top-colors: #d4d0c8 white;-moz-border-left-colors: #d4d0c8 white;-moz-border-right-colors:#404040 #808080;-moz-border-bottom-colors:#404040 #808080;
              
          • 1
          • 2
          1. 對select的options集合操作 
            枚 舉元素除了[]外,SelectName.options.item()也是可以的, 另外SelectName.options.length, SelectName.options.add/remove都可以在兩種瀏覽器上使用。注意在add后賦值元素,否則會失敗。

          2. XMLHTTP的區別

          //mf if (window.XMLHttpRequest)  //mf {
              xmlhttp=new XMLHttpRequest()
              xmlhttp.onreadystatechange=xmlhttpChange
              xmlhttp.open("GET",url,true)
              xmlhttp.send(null)
              } //ie else if (window.ActiveXObject)  //   code   for   IE {
              xmlhttp=new ActiveXObject("Microsoft.XMLHTTP") if (xmlhttp)
                  {
                  xmlhttp.onreadystatechange=xmlhttpChange
                  xmlhttp.open("GET",url,true)
                  xmlhttp.send()
                  }
              }
          } 
              
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21

          24.css中的width和padding 
          在IE7和FF中width寬度不包括padding,在Ie6中包括padding.

          25.css hack 
          根據不同瀏覽器對CSS樣式的支持程度,解析結果和識別CSS的優先級不同,設計師們就可以根據這些不同瀏覽器 的特點來書寫不同的CSS樣式代碼。IE6能識別下劃線和星號*,IE7能識別星號*,不能識別下劃線,而firefox兩個都不能識別,如此,就可 以針對IE6.IE7和FF通過對這些特殊符號的使用寫不同的代碼了。

          <style> div{ background:green; /* for FireFox */ *background:red; /* for IE7 */ _background:blue; /* for IE6 */ } </style>
              
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7

          該樣式顯示的效果是:在FireFox中背景色為green;在IE7中背景色為red;在IE6中背景色為blue。

          此外,!important聲明也可以很好地提升指定樣式規則的應用優先權。在IE6和FF中用!important聲明可以提高優先級別,但在 IE6中 的!important聲明會被之后的同名屬性定義替換。所以,通過*和!important聲明兩者的搭配也可以很好地解決IE6,IE7和FF三者之 間的兼容性問題。

          區別FF,IE7,IE6:background:red; *background:green !important; *background:blue;

          注:IE都能識別;FF不能識別;IE6能識別,但不能識別 !important;IE7能識別,也能識別!important;FF不能識別*,但能識別!important;

          針對IE7/firefox 在css的前面加 [xmlns], 如下面的left屬性,如果我想要只針對IE7/firefox起作用,寫法如下: 
          [xmlns] #left { 
          float:left; 
          border:4px solid #999; 
          padding:5px; 
          width:200px; 
          height:200px; 

          只針對IE6起作用,可以在css前面加* html,如: 
          * html #left { 
          clear:both; 
          }

          只針對IE7起作用,在css里前面加*+html,如: 
          *+html #left { 
          clear:both; 
          }

          書寫的順序都是FireFox的寫在前面,IE7的寫在中間,IE6的寫在最后面。

          26.使用IE專用的條件注釋

          <!--其他瀏覽器 --> <link rel="stylesheet" type="text/css" href="css.css" /> <!--[if IE 7]> 
          <!-- 適合于IE7 --> <link rel="stylesheet" type="text/css" href="ie7.css" /> <![endif]--> <!--[if lte IE 6]> 
          <!-- 適合于IE6及一下 --> <link rel="stylesheet" type="text/css" href="ie.css" /> <![endif]-->
              
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12

          27.div 的垂直居中問題: vertical-align:middle; 將行距增加到和整個DIV一樣高 line-height:200px; 然后插入文字,就垂直居中了。缺點是要控制內容不要換行

          28.cursor: pointer 可以同時在 IE FF 中顯示游標手指狀, hand 僅 IE 可以

          29.FF: 鏈接加邊框和背景色,需設置 display: block, 同時設置 float: left 保證不換行。參照 menubar, 給 a 和 menubar 設置高度是為了避免底邊顯示錯位, 若不設 height, 可以在 menubar 中插入一個空格。

          30.在mozilla firefox和IE中的BOX模型解釋不一致導致相差2px解決方法:div{margin:30px!important;margin:28px;} 
          注意這兩個margin的順序一定不能寫反,據阿捷的說法!important這個屬性IE不能識別,但別的瀏覽器可以識別。所以在IE下其實解釋成這樣:div{maring:30px;margin:28px} 
          重復定義的話按照最后一個來執行,所以不可以只寫margin:XXpx!important;

          31.IE5 和IE6的BOX解釋不一致 
          IE5下div{width:300px;margin:0 10px 0 10px;} 
          div 的寬度會被解釋為300px-10px(右填充)-10px(左填充)最終div的寬度為280px,而在IE6和其他瀏覽器上寬度則是以 300px+10px(右填充)+10px(左填充)=320px來計算的。這時我們可以做如下修改 div{width:300px!important;width /**/:340px;margin:0 10px 0 10px}

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務


          網站內部結構優化_如何優化網站的內部結構

          seo達人

          如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里

          如何優化網站的內部結構?網站內部結構優化是網站SEO過程中不可缺少的環節,在網站建設的初期就要做好設置工作。網站內部結構的優化主要包括:網站結構、頁面元素、后期優化等,下面就從這幾個方面為大家講解,希望能給一些不了解的朋友提供實質性的指導作用。

                1、結構目錄

          目錄的設計是網站建設中很關鍵的環節,是一個網站的骨架,所以網站目錄直接關系到用戶的體驗。建議:目錄的組織結構從首頁到內容頁點擊不超過三次,也就是三級:首頁-欄目頁-內容頁。目錄名可采用網站的一些核心產品詞。

          2、鏈接

          我們說一個網站的優化最重要的兩點是什么?對,是鏈接和關鍵詞。如果說目錄是一個網站的骨架,那么鏈接就是網站的血液。建議:網站鏈接的設置以英文形式展現,簡短易懂,使用靜態化URL,迎合搜索引擎的喜好,更好的服務于網站優化。

          3、robots協議

          robots.txt相當于網站的一張臉,一張接客的臉,接的搜索引擎的蜘蛛(或機器人、爬蟲)。它是一種抓取協議文件,用于告訴搜索引擎spider,此網站中的哪些內容是不應被搜索引擎的索引,哪些是可以被索引的。

          現在很多地方都有自動生成工具,百度站長工具,或者一些插件等,根據自己的喜好選擇使用。這里有一個小技巧,將網站的地圖鏈接放置在robots內,對網站的收錄絕對是不小的幫助。具體方法:在最后一行增加 Sitemap:http://www.example.com/sitemap.xml。

          4、Sitemaps

          Sitemaps就是一個管家,總結統計網站的數據鏈接,將匯總的結果更好的展現給網站的客人-搜索引擎spider。

          Sitemaps一般有html與XML兩種格式。目前百度、Google、雅虎、微軟等搜索引擎都支持Sitemaps,Sitemaps的提交可以通過各個搜索引擎的站長平臺提交,也可以將其地址放在robots.txt文件里,上面已經說過了。

          5、404頁面

            404頁面是客戶端在瀏覽網頁時,服務器無法正常提供信息,或是服務器無法回應,且不知道原因所返回的頁面。據說在第三次科技革命之前,互聯網的形態就是一個大型的中央數據庫,這個數據庫就設置在404房間里面。那時候所有的請求都是由人工手動完成的,如果在數據庫中沒有找到請求者所需要的文件,或者由于請求者寫錯了文件編號,用戶就會得到一個返回信息:room 404 : file not found。404錯誤信息通常是在目標頁面被更改或移除,或客戶端輸入頁面地址錯誤后顯示的頁面,人們也就習慣了用404作為服務器未找到文件的錯誤代碼了。當然實際考證傳說中的room 404是不存在的,在http請求3位的返回碼中,4開頭的代表客戶錯誤,5開頭代表服務器端錯誤。

          6、nofollow標簽

          nofollow標簽是盡量減少垃圾鏈接對搜索引擎的影響,當超鏈接中出現nofollow標簽后,搜索引擎會不考慮這些鏈接的權重,也不用使用這些鏈接用于排名。

          nofollow標簽通常有兩種使用方法:一種方法是將"nofollow"寫在網頁上的meta標簽上,例如:。另一種方法是將"nofollow"放在超鏈接中,例如: 。

          需要注意的是,如果一個網站鏈向了某些被搜索引擎認為是垃圾網站的地址,那么這個網站的權重也會受到影響。因此對于一個網站來說,nofollow標簽的使用十分必要。

          7、統計代碼

          網站統計分析工具應該是每一位站長都了解的,現在常用的就是百度統計、cnzz、谷歌分析、51等,具體的就不做介紹了。網站統計代碼添加時,為了不 影響網站的加載速度,最好放在網站底部。

                相關拓展:關鍵詞的爬行和抓取

                 搜索引擎派出一個能夠在網上發現新網頁并抓文件的程序,這個程序通常稱之為蜘蛛。搜索引擎從已知的數據庫出發,就像正常用戶的瀏覽器一樣訪問這些網頁并抓取文件。搜索引擎會跟蹤網頁中的鏈接,訪問更多的網頁,這個過程就叫爬行。這些新的網址會被存入數據庫等待抓取。所以跟蹤網頁鏈接是搜索引擎蜘蛛發現新網址的最基本的方法,所以反向鏈接成為搜索引擎優化的最基本因素之一。沒有反向鏈接,搜索引擎連頁面都發現不了,就更談不上排名了。

                 搜索引擎抓取的頁面文件與用戶瀏覽器得到的完全一樣,抓取的文件存入數據庫。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 平面設計服務

          如何搞定響應式網頁的布局設計?

          seo達人

          如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里

          編者按:作為今年大熱的設計趨勢,響應式已然是設計師的標配技能。今天阿里的同學從響應式設計的布局類型、布局實現兩方面深入講解,有哪些實現布局的方式,該采用何種方式,都有相當專業細致的解答,不多說,來收 >>>

          Heyuchan :在談響應式布局前,我們先梳理下網頁設計中整體頁面排版布局,常見的主要有如下幾種類型:

          布局類型


          640?wx_fmt=png&wxfrom=5&wx_lazy=1

          布局實現


          采用何種方式實現布局設計,也有不同的方式,這里基于頁面的實現單位而言,分為四種類型:固定布局、可切換的固定布局、彈性布局、混合布局。

          ?固定布局:以像素作為頁面的基本單位,不管設備屏幕及瀏覽器寬度,只設計一套尺寸;


          ?可切換的固定布局:同樣以像素作為頁面單位,參考主流設備尺寸,設計幾套不同寬度的布局。通過設別的屏幕尺寸或瀏覽器寬度,選擇最合適的那套寬度布局;


          ?彈性布局:以百分比作為頁面的基本單位,可以適應一定范圍內所有尺寸的設備屏幕及瀏覽器寬度,并能完美利用有效空間展現最佳效果;


          ?混合布局:同彈性布局類似,可以適應一定范圍內所有尺寸的設備屏幕及瀏覽器寬度,并能完美利用有效空間展現最佳效果;只是混合像素、和百分比兩種單位作為頁面單位。


          640?wx_fmt=png

          可切換的固定布局、彈性布局、混合布局都是目前可被采用的響應式布局方式。

          其中可切換的固定布局的實現成本,但拓展性比較差;而彈性布局與混合布局效果具響應性,都是比較理想的響應式布局實現方式。

          只是對于不同類型的頁面排版布局實現響應式設計,需要采用不用的實現方式。通欄、等分結構的適合采用彈性布局方式、而對于非等分的多欄結構往往需要采用混合布局的實現方式。

          640?wx_fmt=png

          布局響應 對頁面進行響應式的設計實現,需要對相同內容進行不同寬度的布局設計,有兩種方式:

          桌面優先(從桌面端開始向下設計);

          移動優先(從移動端向上設計);

           無論基于那種模式的設計,要兼容所有設備,布局響應時不可避免地需要對模塊布局做一些變化(發生布局改變的臨界點稱之為斷點), 我們通過JS獲取設備的屏幕寬度,來改變網頁的布局,這一過程我們可以稱之為布局響應屏幕。

          常見的主要有如下幾種方式:

          布局不變,即頁面中整體模塊布局不發生變化,主要有:

          ?模塊中內容:擠壓-拉伸;

          ?模塊中內容:換行-平鋪;

          ?模塊中內容:刪減-增加;

          640?wx_fmt=png640?wx_fmt=png640?wx_fmt=png

          布局改變,即頁面中的整體模塊布局發生變化,主要有:

          ?模塊位置變換;

          ?模塊展示方式改變:隱藏-展開;

          ?模塊數量改變:刪減-增加;

          640?wx_fmt=png640?wx_fmt=png640?wx_fmt=png

          很多時候,單一方式的布局響應無法滿足理想效果,需要結合多種組合方式,但原則上盡可能時保持簡單輕巧,而且同一斷點內(發生布局改變的臨界點稱之為斷點)保持統一邏輯。

          否則頁面實現得太過復雜,也會影響整體體驗和頁面性能。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 平面設計服務

          ES6(一):Promise對象

          seo達人

          如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里

          介紹Promise

          promise的概念和實現最初來源于社區,用于解決異步編程的回調嵌套問題,即將多級的嵌套改良成順序的代碼行。ES6將其寫入了語言標準,統一了用法,提供了原生的Promise。

          Promise是一個構造函數,用于生成一個Promise實例。Promise實例代表一次異步操作。 它只可能有3種轉態,分別是Pending(未決議)Resolved(完成) 和 Rejected(出錯) 。

          創建一個Promise實例時,其處于Pending狀態,當異步操作完成,執行回調函數的時候,根據回調函數中的err的值,如果err 為空則異步操作成功,否則異步操作失敗。此后,Promise實例的狀態將不再改變。

          Promise實例

          var pro = function () { return new Promise(function(resolve, reject) { fs.readdir(_dirname, function(err, data) { if (err) {
                          reject(err); //失敗則將Promise對象置為rejected狀態 } else {
                          resolve(data); //成功則將Promise對象置為resolved轉態 }
                  });
              });
          } /*pro是一個函數
           調用該函數返回一個Promise實例
          */ var promiseObject = pro(); /*then方法執行Resolved和Rejected狀態的回調函數*/ promiseObject
          .then(doneCallbacks, failCallbacks)
          .catch(function(err) { console.log(err);
          }); var doneCallbacks = function(data) { console.log(data);
          }; var failCallbacks = function(err) { console.log(err)
          };
              
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29

          catch是then的一個語法糖,相當于

          promiseObject.then(undefined, function(err) {
              console.log(err)
          });
              
          • 1
          • 2
          • 3

          Promise對象的錯誤具有向后傳遞的性質,因此,如果在調用過程拋出異常,則異常總能被最后一個catch捕獲。這也是為什么我們習慣在then的調用后跟隨一個catch調用。

          then的鏈式寫法

          then 方法是定義在構造函數Promise 的原型對象上的。這個方法為Promise實例添加狀態改變時的回調函數。then方法返回一個新的Promise實例,因此then方法后面可以調用then()方法。傳給then()方法的函數,可返回三類值,分別如下:

          • 一個Promise實例
          • 一個普通值
          • 拋出一個異常

          如果返回的是一個新的Promise對象,則下一級的then接收函數在這個Promise實例 狀態發生改變時被觸發執行。因此,then的鏈式寫法,可以按順序執行一系列的異步操作,并且后一個異步操作在前一個完成之后開始。如下代碼實例所示:

          var fs = require('fs'); var pro = function () { return new Promise(function(resolve, reject) { fs.readdir(_dirname, function(err, data) { if (err) {
                          reject(err); //失敗則將Promise對象置為rejected狀態 } else {
                          resolve(data); //成功則將Promise對象置為resolved轉態 }
                  });
              });
          } var newPro = function(data) { return new Promise(function(resolve, reject) { setTimeout(function(){ resolve(data);
                  },2000);
              });
          }; /*pro是一個函數
           調用該函數返回一個Promise實例
          */ var promiseObject = pro(); /*then方法執行Resolved和Rejected狀態的回調函數*/ promiseObject
              .then(function(data){ console.log("fisrt sync op");
                  console.log(data); return newPro(data);//返回一個新的Promise對象 })
              .then(function(data) { console.log("second sync op");
                  console.log(data);//兩秒鐘后才會被執行 })
              .catch(function(err) { console.log(err);
              });
          
          promiseObject.then(undefined, function(err) { console.log(err)
          }); var doneCallbacks = function(data) { console.log(data);
          }; var failCallbacks = function(err) { console.log(err)
          }; 
              
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46
          • 47
          • 48
          • 49
          • 50
          • 51
          • 52
          • 53

          把上一級異步調用的結果返回給下一級調用,then這樣的鏈式寫法,解決了回調函數的多層嵌套調用。

          解決異步嵌套回調的更多方案

          “回調金字塔”

          多層嵌套

          bluebird庫 + Generator

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務


          日歷

          鏈接

          個人資料

          藍藍設計的小編 http://www.syprn.cn

          存檔

          亚洲va欧美va天堂v国产综合