欢迎来到DIVCSS5查找CSS资料与学习DIV CSS布局技术!
在这里中,您将使用最新的Web技术开发Web应用程序。这里的大多数代码只是HTML,JavaScript和CSS —任何Web开发人员的核心技术。需要的最重要的东西是用于测试代码的浏览器。本文中的大多数代码将运行在最新的桌面浏览器上,例外的情况会指出来。当然,还必须在移动浏览器上进行测试,您肯定希望最新的iPhone和Android SDK支持这些代码。使用的是iPhone SDK 3.1.3和Android SDK 2.1。
本地存储基础
Web开发人员一直一直在尝试将数据存储在上面。HTTPcookie被滥用于此目的。开发人员将大量数据压缩到HTTP规范分配的4KB上。原因很简单。出于各种原因,相互之间Web应用程序需要存储数据,并且将这些数据存储在服务器上通常效率低下,不安全或者不适当。多年来,这个问题有了好多种替代方法。各种的浏览器已经约会了专有存储API。开发人员也利用了Flash Player中的扩展存储功能(通过JavaScript实现)。类似地,Google为各种浏览器创建了Gears插件,并且它包含了存储API。毫不奇怪的是,一些JavaScript库试图抹平这些差异。换句话说,这些库提供一个简单的API,然后检查有哪些存储功能(可能是一个专有浏览器API或是一个诸如Flash的插件)。
对Web开发人员来说幸运的是,HTML 5规范最终包含了一个针对本地存储的标准,被广泛的浏览器所实现。事实上,该标准是可以被采用的标准,在所有主要浏览器的最新版本中都受到支持:Microsoft®,InternetExplorer®,Mozilla Firefox,Opera,Apple Safari和Google Chrome。对于移动开发人员更为重要的是,它在基于WebKit的浏览器(例如iPhone和使用Android(版本) 2.0或更高版本)的手机中的浏览器)以及其他移动浏览器(例如Mozilla的Fennec)中受到支持。记住这一点,我们来看一下这个API。
存储API
localStorage API十分简单。实际上,根据HTML 5规范,它实现了DOM Storage接口。相反的原因是,HTML 5指定了两个不同的对象实现该接口:localStorage和sessionStorage。sessionStorage对象是一个只在会话期间存储的数据的存储实现。更准确地说,只要没有可以访问sessionStorage的脚本运行运行,浏览器就可以删除sessionStorage数据。这是与localStorage相对的,多个跨用户会话。两个对象共享相同的API ,所以我将只着重介绍localStorage。
存储API是一种经典的名/值对数据结构。您将使用的最常见的方法是getItem(name)和setItem(name,value)。这些方法完全跟您预期的一样:getItem返回与名称相关联的值,如果什么都不存在,则返回null,而setItem则是将名/值对添加到localStorage,或者是取代现有值。还有一个removeItem(name),顾名思意,它从localStorage删除一个名/值对(如果存在的话,否则什么都不做)。最后,对于在所有名/值对上继承,存在两个API。一个是长度属性,正在获取存储的名/值对的总数。对应地,一个key(index)方法从存储中使用的所有名称中返回一个名称。
利用这些简单的API,可以完成大量任务,某些说个性化或跟踪用户行为。这些可以说对移动Web开发人员是重要的用例,但是还有一个更为重要的用例:高速缓存。利用localStorage,可以这让您无需等待可能缓慢的服务器吞吐量,并且最小化了对服务器上数据的需求量。现在来看一个例子,演示了如何使用localStorage来获得这种高速缓存。
例子:利用本地存储实现高速缓存
本例建立在本系列第1部分局部的例子之上,那时您最先开始了t0开发。那个例子展示了如何通过利用地理定位API取得用户的位置而执行Twitter的本地搜索。从那个例子开始,对它进行简化,并大大提高它的性能。首先,将那个例子简化成不带定位的Twitter搜索。清单1展示了简化的Twitter搜索应用程序。
 
清单1.最基本的Twitter搜索
XML / HTML代码将内容复制到文本
< html >  
<头>  
< meta http-equiv = “ Content-Type”内容= “ text / html; charset = UTF-8” >    
< meta name  =  “ viewport” content  =  “宽度=设备宽度” />    
< title >基本的Twitter搜索</ title >  
<脚本类型= “ text / javascript” >   
    函数searchTwitter(){  
        VAR 的查询 =“http://search.twitter.com/search。JS吗?回调  
= showResults &q =“;  
        查询+ = $(“ kwBox”)。value;  
        var  script  =  document .createElement(“ script”);  
        script.src  = 查询;  
        document.getElementsByTagName(“ head”)[0] .appendChild(script);  
    }  
    //为简洁起见删除ui代码  
    函数showResults(response){  
        var  tweets  =  response .results;  
        tweets.forEach(function(tweet){  
            tweet.linkUrl  =  “ http://twitter.com/”  + tweet.from_user   
+“ / status /” + tweet.id;  
        });  
        makeResultsTable(tweets);  
    }  
</脚本>  
<!-为简洁起见删除了CSS->  
</头>  
<身体>  
    < div id = “ main” >   
        <标签为= “ kwBox” >搜索Twitter:</标签>   
        <输入类型= “文本” id = “ kwBox” />    
        <输入类型= “按钮”值= “开始!” onclick = “ searchTwitter()” />     
    </ div >  
    < div id = “结果” >   
    </ div >  
</ body >  
</ html >  
在这个应用程序中,使用了Twitter搜索API对JSONP的支持。用户提交搜索时,会动态添加一个脚本标记到页面并指定相应的函数的名称,从而进行一次API调用。这允许您从Web页面进行一次跨域调用。立即调用返回,将其调用(显示结果)就会被调用。您添加一个链接到Twitter返回的每个tweet,然后创建一个简单的表格使用显示这些tweet。为了提速,您可以高速缓存从搜索查询得到的结果,然后在用户每次提交查询时使用这些缓存的结果。首先来看如何使用localStorage来本地存储tweet。
本地保存
基本的Twitter搜索可以搜索Twitter搜索API提供一组tweet。如果您可以本地保存这些tweet,则它们与生成的关键字搜索相关联,那么您就拥有了一个有用的高速缓存。要保存tweet,您只需要修改当对Twitter搜索API的调用返回时将被调用的回调函数。清单2展示了修改后的函数。
 
清单2.搜索和保存
JavaScript代码将内容复制到
函数 searchTwitter(){  
    var  keyword = $(“ kwBox” ). value ;  
    var  query =  “ http://search.twitter.com/search.json?callback 
= processResults&q =“ ;  
    查询+ =关键字;  
    var  script = document.createElement(“ script” );  
    script.src =查询;  
    document.getElementsByTagName(“ head” )[0] .appendChild(script);  
}  
函数 processResults(response){  
    var  keyword = $(“ kwBox” ). value ;  
    var  tweets = response.results;  
    tweets.forEach(函数(tweet){  
        saveTweet(keyword,tweet);  
        tweet.linkUrl =  “ http://twitter.com/”  + tweet.from_user +  “ / status /”  + tweet.id;  
    });  
    makeResultsTable();  
    addTweetsToResultsTable(tweets);  
}  
函数 saveTweet(keyword,tweet){  
    //检查浏览器是否支持localStorage  
    如果 (!window.localStorage){  
        回报;  
    }  
    如果 (!localStorage.getItem(“ tweet”  + tweet.id)){  
        localStorage.setItem(“ tweet”  + tweet.id,JSON.stringify(tweet));  
    }  
    var  index = localStorage.getItem(“ index ::”  +关键字);  
    如果 (索引){  
        index = JSON.parse(index);  
    } 其他 {  
        索引= [];  
    }  
    如果 (!index.contains(tweet.id)){  
        index.push(tweet.id);  
        localStorage.setItem(“ index ::” +关键字,JSON.stringify(index));  
    }   
}  
 
从第一个函数searchTwitter开始。这在用户提交搜索时被调用。相对于清单1着重于惟一的地方是callback函数。不只是在tweet返回时显示它们,您还需要处理它们(除了显示,还要保存它们)。因此,您指定一个新的回调函数processResults。您针对每个tweet调用saveTweet。您还传递被用作生成搜索结果的关键字。这是因为您想要将这些tweet与该关键词相关联。
在saveTweet函数中,首先进行检查,确保localStorage真正受到浏览器的支持。前面提到的,localStorage在桌面和移动浏览器中都受到广泛支持,但是在使用这种新特性时进行检查总是一个好主意。如果它不受支持,那么您简单地从函数返回。看起来不会保存任何东西,但是也不会报错—应用程序在这种情况下只是不会具有高速缓存。如果localStorage受到支持,然后首先进行检查,看这个tweet是否已经存储。如果没有存储,那么使用setItem本地存储它。然后,检索一个对应于关键字的索引对象。这只是与关键字相关联的tweet的ID。如果tweet ID还不是索引的一部分,那么添加它并更新索引。
注意,在清单3中保存和加载JSON时,您使用了JSON.stringify和JSON.parse。JSON对象(或者更简单地说,是window.JSON)是HTML 5规范的一部分,作为一个总是存在的原生对象。stringify方法将把任何JavaScript对象转换成一个序列化的字符串,而parse方法则进行相反的操作,它从序列化的串行表示还原JavaScript对象。这是很必要的,因为localStorage只存储但是,原生JSON对象并不被广泛实现为localStorage。例如,它不出现在iPhone(在撰写本文中是版本3.1.3)的最新Mobile Safari浏览器上。它在最新的Android浏览器上受支持。您可以容易地检查它是否在那里,如果不在,就加载一个另外的JavaScript文件。您可以通过访问json.org Web站点(见参考资料),获得原生使用的相同JSON对象。要本地查看这些图1展示了一些高速缓存的推文,其存储在本地,使用Chrome的开发人员工具进行查看。
 
图1.本地高速缓存的tweet
整个本地高速缓存的tweet的屏幕截图(带有Key和Value细分) 
Chrome和Safari都内置了开发人员工具,可以用于查看任何保存在localStorage中的数据。这对于调试使用localStorage的应用程序非常有用。它以纯文本形式展示本地存储的键/值对。既然您已经开始保存来自Twitter的搜索API的推文,刹车它们可以被用作高速缓存,所以您只需开始从localStorage读取其即可。下面来看这是如何做到的。
快速本地数据加载
在清单2中,您看到了一些示例使用getItem方法从localStorage读取数据。现在当一个用户提交搜索时,您可以检查高速缓存命中情况,并立即加载缓存的结果。当然,您仍将针对Twitter搜索API进行查询,因为人们一直在产生tweet并添加到搜索结果。但是,通过寻找还没在高速缓存中的结果,现在您也有了让查询更为高效的方式。清单3展示了更新后的搜索代码。
 
清单3.首先进行本地搜索
JavaScript代码将内容复制到
函数 searchTwitter(){  
    如果 ($(“ resultsTable” )){  
        $(“ resultsTable” ).innerHTML =  “” ; //清除结果  
    }  
    makeResultsTable();  
    var  keyword = $(“ kwBox” ). value ;  
    var  maxId = loadLocal(keyword);  
    var  query =  “ http://search.twitter.com/search.json?callback=processResults&q=” ;  
    查询+ =关键字;  
    如果 (maxId){  
        查询+ =  “&since_id =”  + maxId;  
    }  
    var  script = document.createElement(“ script” );  
    script.src =查询;  
    document.getElementsByTagName(“ head” )[0] .appendChild(script);  
}  
函数 loadLocal(keyword){  
    如果 (!window.localStorage){  
        回报;  
    }  
    var  index = localStorage.getItem(“ index ::”  +关键字);  
    var  tweets = [];  
    var  i = 0;  
    var  tweet = {};  
    如果 (索引){  
        index = JSON.parse(index);  
        对于 (i = 0; i <index.length; i ++){  
            tweet = localStorage.getItem(“ tweet” + index [i]);  
            如果 (鸣叫){  
                tweet = JSON.parse(tweet);  
                tweets.push(tweet);  
            }  
        }  
    }  
    如果 (tweets.length <1){  
        返回 0;  
    }  
    tweets.sort(函数(a,b){  
        返回 a.id> b.id;  
    });  
    addTweetsToResultsTable(tweets);  
    返回 tweets [0] .id;  
}  
 
您将注意到的第一件事情是,当一个搜索被提交时,您首先调用新的loadLocal函数。该函数返回一个整数,即高速缓存中找到的最新tweet的ID。loadLocal函数接受一个关键字作为参数,,该关键字也被用作本地存储高速缓存中查找相关的tweet。如果具有一个maxId,那么使用它来修改对Twitter的查询,添加since_id参数。您在告诉Twitter API只返回比该参数中给定的ID新的tweet。潜在地,这可以减少从Twitter返回的结果数量。您任何时候都可以为移动Web应用程序优化服务器调用,因为它可以真正改善慢速移动网络上的用户体验。现在更仔细地来看一下loadLocal。
在loadLocal函数中,您利用了存储在前面的清单中。2通过使用getItem,您首先加载与关键字相关联的索引。如果没找到任何索引,那么就没有缓存的tweet,所以就没有展示这些推文,并且没有可对查询进行的优化(您返回一个0值以指示这一点)。如果找到一个索引,那么您从它得到ID列表。这些tweet中的每一个都被本地高速缓存,所以您只需再次使用getItem方法,从高速缓存加载每一个tweet。的函数。您可能会引起注意,因为它在存储和检索tweet的代码与显示它们的代码之间创建了替换,全都通过processResults函数。使用存储事件会提供一种替代的,替代的的方法。
存储事件
现在扩展示例应用程序,展示最可能具有缓存结果的前10个搜索变量。这可能代表用户最常提交的搜索。清单4展示了一个用于计算并显示前10个搜索体积的函数。
 
清单4.计算前10个搜索范围
JavaScript代码将内容复制到
函数 displayStats(){  
    如果 (!window.localStorage){  return ; }  
    var  i = 0;  
    var  key =  “” ;  
    var  index = [];  
    var  cachedSearches = [];  
    对于 (i = 0; i <localStorage.length; i ++){  
        键= localStorage.key(i);  
        如果 (key.indexOf(“ index ::” )== 0){  
            index = JSON.parse(localStorage.getItem(key));  
            cachedSearches.push({keyword:key.slice(7),numResults:index.length});  
        }  
    }  
    cachedSearches.sort(函数(a,b){  
        如果 (a.numResults == b.numResults){  
            如果 (a.keyword.toLowerCase()<b.keyword.toLowerCase()){  
                返回 -1;  
            } 否则,如果 (a.keyword.toLowerCase()> b.keyword.toLowerCase()){   
                返回 1;  
            }  
            返回 0;  
        }  
        返回 b.numResults-a.numResults;  
    })。slice(0,10).forEach(函数(搜索){  
        var  li = document.createElement(“ li” );  
        var  txt = document.createTextNode(search.keyword +  “:”  + search.numResults);  
        li.appendChild(txt);  
        $(“ stats” ).appendChild(li);  
    });  
}  
 
该函数充分展示了localStorage API。您首先获得存储在localStorage中的大小的总数,然后再转换这些压缩。如果索引是索引,那么您就可以解析该对象并创建一个表示您要处理的数据的对象:与该数据存储在一个叫做cachedSearches的排序中。然后,对cachedSearches进行排序,将具有最大结果的搜索排在第一位,如果两个搜索具有相同数量的然后对于前10个搜索,为每个搜索创建HTML,并将它们附加到一个排好序的列表。让我们在页面初次加载时调用该函数,如清单5所示。
 
清单5.初始化页面
window.onload = function(){ displayStats(); document.body.setAttribute(“ onstorage”,“ handleOnStorage();”); }
第一行在页面加载时调用清单4中的函数。第二次加载是变得更有趣的地方。您在这里为onstorage事件设置一个事件处理程序。每当localStorage.setItem函数执行完成,该事件就会激活。这将允许您重新计算前10个搜索。清单6展示了该事件处理程序。
 
清单6.存储事件处理程序
函数handleOnStorage(){ 如果(window.event && window.event.key.indexOf(“ index ::”)== 0){ $(“ stats”)。innerHTML =“”; displayStats(); } }
onstorage事件将与窗口相关联。它具有几个有用的属性:key,oldValue和newValue。除了这些自解释的属性之外,它还有一个URL(更改值的页面的URL)和source(包含更改值)。如果用户具有多个到应用程序的窗口或选项卡或者甚至是iFrames,那么这最后两个属性就更有用,但是没有哪一个在移动应用程序中特别常见。返回清单6 ,,您真正需要的惟一的属性是键属性。您使用该属性来看它是不是一个已修改的索引。如果是的,那么您重新设置前10名列表,并通过再次调用displayStats函数而重新替换它。该技术的优点是,其他函数都不需要了解前10名列表,因为它是自包含的。
在前面我提到过,DOM Storage(它包含localStorage和sessionStorage)总体来说是一个被广泛采用的HTML 5特性。但是,存储事件对于这一点来说是一个例外—至少在桌面浏览器上如此。在iPhone和Android浏览器是Safari 4+和Internet Explorer 8+。在Firefox,Chrome和Opera中不受支持。但是在移动领域,情况稍有好转。的最新版本都完全支持存储事件,并且此处指定的代码都能在这些浏览器中完美地运行。
结束语
作为长期的Web开发人员来说,为做到他们一直一直想做,却苦于找不,因为作为一名开发人员,突然在缩减上拥有巨额的存储空间,您会觉得自己获得了很大的解放。到好的方式来做的事情带来了转机。对于移动开发人员来说,则更振奋人心,因为它真正开启了数据的本地高速缓存。除了大大改善应用程序的性能之外,本地高速缓存对于推动移动Web应用程序的另一个新的令人振奋的功能-离线-是很关键的。这将是本系列下一篇文章的主题。

如需转载,请注明文章出处和来源网址:http://www.divcss5.com/html/h60893.shtml