无入侵脚本编程(unobtrusive scripting)
一个无入侵的脚本应该包括如下的所有特征:
1、它应该是可用的。即给网站带来了明确的可用性好处。
2、它应该是可访问的。即如果javascript失效了,网页应该依然是可阅读和可理解的,及时不可避免的损失了一些可用性。
3、它应该容易实现。典型的情况:web开发者只需要在页面中引入脚本本身和一个javascript钩子(hook),然后脚本就可以运行了。
4、它应该是分离的。它只存在于自己的.js文件中,而不是散落在HTML的各个角落。
三个层
一个web页面由如下三个层组成:
1、HTML结构层 2、CSS表现层 3、JavaScript行为层
分离关注点
把客户端代码分为三个层还引入了另一个话题,几分利关注点。一般来说,最好能把三个层分开来管理。最基本的要求是确保要做到如下几点:
1、HTML是结构化的,不要太复杂,而且在没有CSS和JavaScript的情况下要有意义。
2、CSS表现层和JavaScript行为层分别放置于.css文件和.js文件中。
分离关注点方便维护,此外分离使你可以改变整个CSS表现层,给你的网站一个全新的设计,而且既不用重写HTML结构,也不用重写JavaScript行为层。
三个分离-- 表现与结构分离
分离表现层和结构层的基本思想就是确保由HTML来定义结构(且之定义结构),而所有表现都定义在另一个单独的CSS文件中。
css修改:javascript允许修改css,通常实时修改css的最好办法是改变一个元素的className。
更改结构还是表现:有两种方法来隐藏表单域
1、用css是它们不可见(display:none)--表现层
2、从文档结构中将它们彻底移除。--结构层
但是要注意,当提交表单的时候,浏览器会给所有的表单域创建名/值对,然后再把它们发送给服务器。如果我们把一些不需要的表单通过css隐藏,则这些表单域仍然是表单的一部分,不过是隐藏了而已,因此,它们也会被发送到服务器,即使它们是没用的。
相对地,如果从文档结构中把这些表单域完全的移除,它们就不会被发送到服务器,即使它们是没用的。
推荐:最好把表单域直接移除,而不是隐藏它们。
三个分离-- 行为与结构分离
行为与结构分离比较容易理解:不把任何javascript代码写到你的HTML页面里。这需要两个步骤:
1、把所有的javascript函数都放到一个独立的.js文件中,然后把它链入到所有需要它的HTML页面。
2、从HTML中移除所有的事件处理程序,把它们放到同一个.js文件里。
<a href="somepage.html" id="nifty">DO it!</a> //单独的js文件中 document.getElementById('nifty').onclick = doAllKindOfNiftyThings;
三个分离-- 行为与表现分离
事实上,存在着CSS和javascript重合的灰色地带,不能清除地把某个效果归为表现还是行为。
所以,如果需要创建“相似但不完全相同”的效果时,比如mouseover,javascript是最有效的方法,当你必须在css和javascript之间做出选择时,请记住这一点。
可访问性规则
1、条理分明的HTML (硬编码的链接必须有href)
2、产生对脚本用户有意义的内容
a.触发高级脚本的链接(如果给链接加上href不可行,那么久用javascript来生成链接,如下代码:)
var link = document.createElement("a"); link.href = "#"; link.onclick = starUpAjaxStuff; var linkText = document.createTextNode('Commmence coolness'); link.appendChild(linkText); document.body.appendChild(link); function starUpAjaxStuff(){ alert("ok"); }
b.用javascript隐藏内容(隐藏内容是危险的,如果没有javascript,内容就永远不会变的可见,而这个页面就不具备可访问性)
c.重定向用户
有时候,解决可访问性的问题的最佳办法就是为你的网站同时创建一个有脚本版本和一个无脚本版本。我不喜欢这个解决方案,尽量避免它,但是,实践证
明它还是有价值的。
如果你使用这种方法,就应该遵循如下两条规则:
首先,你网站的入口页面应该是一个无脚本页面,这样,所有的浏览器,即使是那些只能支持HTML的浏览器都可以得到一个可以使用的页面。这样,所有
的浏览器,即使是那些只能支持HTML的浏览器,都可以得到一个可以使用的页面。
第二,当浏览器达到这个无脚本页面时,启动一段脚本来检测它是否可以支持你的高级脚本,如果可以,就用replace()方法把它们转向到有脚本页面。
这里需要注意的是,location.href会在浏览器的历史记录中创建一条新纪录,如果用户到达无脚本页面,她就被转向到有脚本页面。然而,一旦她
点击后退按钮,就会被回送到无脚本页面,而上述的脚本又会立刻启动,并且又把它回送到有脚本页面,后退按钮的功能事实上被破坏了。
所以,使用location.replace()方法,它会载入一个新页面,但它会覆盖旧页面在浏览器中的历史记录,这个时候后退按钮可以一直正常工作。