Web 内容,表现和行为分离

of traits of Javascript-DOM – Unobtrusive, graceful degrade and backward compatability

Unobtrusive这一词的原意是不引人注目的、不突出的。在这里的可以理解为隔离的,隔离javascript代码和html代码(css代码同理)。标题所列的这几个特性,是出于考虑代码的可维护性,效率,以及对于用户端的考虑。其一:假设用户的客户端不支持javascript脚本(也可能不支持某个css属性)。至少使得用户可以正常访问页面,只是效果做出些牺牲。
为了更好的对比出优劣,以原始性(old school)的方式编写代码并把JS和HTML的代码杂糅在一起。

(这是篇学习笔记形式的博客,在一边写的时候,仔细往深的去思考的时候,发现对于我这种初学者,有很多需要去深入理解,感觉没有概括好,也会存在错误的理解)。

<html>
<head>
<title>example</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
//由于为了显示出css分离的优势,暂时这里不写出引用
<!--<link />-->
//由于为了显示出javascript分离的优势,暂时这里不写出引用
//<script type="text/javascript" src="#"></script>
//这里是不把js脚本单列到js的文件
<script>
    function showPic(whichPic){
        //使用DOM的getAttribute函数获取元素属性节点
        //showPic函数里的this关键字指向了<a>元素节点,并传入给whichPic参数
        var sourcePic=whichPic.getAttribute("href");
        //接来下获取到占位符的图片
        var placeHolder=document.getElementById("placeHolder");
        //DOM里有getAttribute函数获取属性信息,setAttribute函数则用于给元素赋予新的信息
        //使用方式如下,值得提示下是:getAttribute和setAttribute都需要使用元素节点特有的
        placeHolder.setAttribute("src",sourcePic);

        //前面已完成图片在本页面替换,在看文本的替换。由于没有元素节点的属性节点,我们得换种方式,
        //一些新的知识点,childNodes,nodeType, nodeValue...etc
        //首先照旧,可以用getAttribute获取到title属性节点的文本信息
        var text=whichpic.getAttribute('title');
        //使用id的特点获取到被替换文本所在的元素节点
        var description=document.getElementById("description");
        //获取元素节点的childNodes及其值,并简单直接用前面代码中获取到的text替换它
        //由于只有一个孩子节点,所以下面两种方式都可以.二选其一
        description.childNodes[0].nodeValue=text;
        description.firstChild.nodeValue=text;
}
</script>
</head>
<body style="margin: auto 10%; font-family: 'Titillium', sans-serif; background-color: #ccc; color: #333;">
<ul>
<li style="float: left; list-style-type: none; padding: 5px;">
<a href="images/1.jpg" onclick="showPic(this)" title="splendid fireworks">Fireworks</a>
</li>
<li style="float: left; list-style-type: none; padding: 5px;">
<a href="images/2.jpg" onclick="showPic(this)" title="A cup of coffee">Coffee</a>
</li>
<li style="float: left; list-style-type: none; padding: 5px;"><a href="images/3.jpg" onclick="showPic(this); return false;" title="Red Rose">  Rose</a>
</li>
<li style="float: left; list-style-type: none; padding: 5px;"><a href="images/4.jpg" onclick="showPic(this); return false;" title="A big Ben">Big Ben</a>
</li>
</ul>
//利用id的唯一性特点,下面两个元素都用id的方式引用
<img id="placeHolder" src="images/5.jpg"/>
<p id="description">substitute text</p>
</body>
</html>

可以出看出目前只是在元素标签body和li里添加了css,其实我们已经能感觉出很笨拙。
牵涉到后面的修改会更多麻烦,
还有就是用户的客户端是否支持css,
当然还有searchbot方面的考虑–searchbot通常只是对html 代码进行搜索收藏。


接下来看隔离后的代码。观察后会发现是纯html代码,要的就是这个效果。

<html>
<head>
<title>example</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
//引入外部的js脚本
<script type="text/javascript" src="myJs.js"></script>
//引入外部的css代码
<link rel="stylesheet" src="mystyle.css" type="text/css"/>  
</script>
</head>
<body>
<!--此处看不到任何嵌套的js脚本,只是相比前面的代码增加了id属性-->
<ul id="imageGallery">
<li>
<a href="images/1.jpg"  title="splendid fireworks">Fireworks</a></li>
<li>
<a href="images/2.jpg"  title="A cup of coffee">Coffee</a>
</li>
<li>
<a href="images/3.jpg"  title="Red Rose">Rose</a>
</li>
<li>
<a href="images/4.jpg"  title="A big Ben">Big Ben</a>
</li>
</ul>
<img id="placeHolder" src="images/5.jpg"/>
<p id="description">substitute text</p>
</body>
</html>

———接下来编写css样式代码和js代码,隔离后并达到同样的效果。

body{
    background-color:#ccc;
    margin: auto 10%;
    color: #333;
    font-family: 'Titillium', sans-serif;
}
h1{
    font-size: bold;
    background-color: transparent;
    color: #333
}
ul{
    padding: 0;
}
li{
    list-style-type:none;
    float: left;
    padding: 6px;
}
a{
    text-decoration: none;
    font-weight: bold;
    color: #c60;
    background-color: transparent;
}
img{
    display: block;
    clear: both;
}
//javascript-DOM要被正常执行,
//首先是整个html(DOM)文档要被加载完,否则javascript代码无法正常执行,比如这里下面有行代码--
//!document.getElementById("imageGallery"),从这里可以看出imageGallery会获取不到。
//那么就需要用到事件句柄--onload,把他绑定给window对象。当然这种方式不利于扩展,
//为了一劳永逸的作用,写个addLoadEvent(){}.
//当然,如果只是直接把对应的函数赋予window.onload,或者简单建立个相应的函数。
//简单点可以这样

window.οnlοad=function (){
firstFunction();
secondFunction();
}

//下面这个就是Simons.Willison写的。
function addLoadEvent(fun){
    var oldOnload=window.onload;
    if(window.onload!="function"){
        window.onload=fun;
    }else{
        window.onload=function(){
            oldOnload();
            fun();
        }
    }
}

addLoadEvent(papareGallery);
//好了,接下来回到主题,把行为代码和界面显示隔离。
//当然这里还会增加一些检测代码,主要是起到gracefully degrade的作用。
//window.onload=prepareLinks;
function prepareGallery(){
//判断浏览器是否支持DOM Core的getElementById
if (!document.getElementById()){
    return false;
}
//判断浏览器是否支持DOM Core的getElementsByTagName
if (!document.getElementByTagName){
    return false;
}
//是否获取到id -- imageGallery
if (!document.getElementById("imageGallery")){
    return false;
}
//考虑这些检测后,就使用DOM Core这两个属性去获取相对应的值。
var gallery=document.getElementById("imageGallery");
var links=gallery.getElementsByTagName("href");
for(var i=0; i < links.length; i++){
    //把onclick点击事件赋予<a>标记元素
    links[i].onclick=function(){
        //调用接来下要另外写的函数,点击图片交换占位符的图片和说明文字
        return !showPic(this);
    }
}

function showPic(whichPic){
    //注意这里,为了以防用户的浏览器或者工具不支持javascritpt或者说DOM,
    //至少用户还能看到html内容,
    //所以在判断是否获取到占位符的属性值,我们返回true,否则,页面可能会显示空白。
    if(!document.getElementById("placeHolder")){
        return true;
    }
    var source=whichPic.getAttribute("href");
    var placeHolder=document.getElementById("placeHolder");
    if(placeHolder.nodeName!="IMG"){
        return false;
    }
    placeHolder.setAttribute("src",source); //replace pic

    if(document.getElementById("description")){
        var text=whichPic.getAttribute("title")?whichPic.getAttribute("title"):"";
        var description=document.getElementByID("description");
        if(description.firstChild.nodeType==3){ //3 repesents text
            description.firstChild.nodeValue=text; //replace the current text by //corresponding text which is descided by which element tag <a> clicked
        }
    }
    return true;
}

标题开的有点大,代码只是粗浅的应用一下。希望多给我些批评指点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值