• 一个Web页面的问题分析


    几个月之前我接到一个新的开发任务,要在一个旧的Web页面上面增添一些新的功能。在开发的过程中发现旧的代码中有很多常见的不合适的写法,结合这些问题,如何写出更好的,更规范的,更可维护的代码,就是这篇文章要阐述的内容。

    首先我查看了该Web页面的HTML代码,发现了一些典型的问题:

    • HTML页面中包含了很多Javascript和CSS代码
    • HTML页面中引用了大量的外部Javascript文件和CSS文件

    接下来就这些问题,我们逐个讨论一下:

    HTML页面中包含了很多Javascript和CSS代码

    一个正常的Web页面通常有以下三部分组成,HTML,CSS,Javascript,其中HTML是数据,CSS负责样式,而Javascript负责交互,三者的关系如下图:

    291049415635764

    在构建Web页面的过程中,要尽量让这三者保持松耦合的关系,不要牵一发而动全身,一个层面小的改动需要改动另外两个层面。首先要从文件级别上隔离这三部分,在HTML中通过引入文件的方式导入Javascript和CSS。

    要做到三者的松耦合,开发中需要注意的地方又如下几点:

    • 在CSS代码中不要包含Javascript
    • 在Javascript代码中不要包含CSS
    • 在HTML代码中不要包含Javascript
    • 在Javascript中不要包含HTML

    CSS代码中不要包含Javascript,指的是在CSS代码中慎用可计算的样式,如IE 8的 expression,CSS3的calc等等,从使用角度来讲全是很强大,从代码维护的角度来看,不推荐使用。出现了Bug的时候,需要同时Check Javascript和CSS代码。

    Javascript代码中不要包含CSS,我们经常需要在Javascript中去动态改变某一个Dom元素的样式,经常写出如下代码:

    element.style.color = 'red';

    这样的代码会导致当需求改变的时候,需要在Javascript代码中全文检索 red 关键字,深怕漏掉一点。推荐的做法如下:

    //在CSS文件中定义样式类型
    .red-class{
       color: red;
    }
    //Javascript中改变样式
    element.className += " red-class";
    // jQuery
    $(element).addClass("red-class");

    在Javascript中操纵Dom对象的Class来改变样式,需求改变的时候,只需要调整CSS文件就可以了。

    HTML代码中不要包含Javascript:

    <input type="button" value="click me" id="mybutton" onclick="do()"/>

    推荐使用下面的代码:

    var btn = document.getElementById('mybutton');
    btn.addEventListener("click", do);

    Javascript代码中不要包含HTML:

    var div = document.getElementById("my-div");
    div.innerHTML = "<h3>Error</h3><p>Invalid e-mail address.</p>";

    在Javascript代码中完全隔绝HTML很难,这一点可以根据实际情况来权衡使用。Javascript 模版技术就是一种有效隔离HTML和Javascript代码的手段,如下是jQuery Template的用法:

    // HTML
    <script id="bookTemplate" type="text/x-jQuery-tmpl">
            <div>
                <img src="BookPictures/${picture}" alt="" />
                <h2>${title}</h2>
                price: ${formatPrice(price)}
            </div>
     </script>
    // Javascript
    // Create an array of books
    var books = [{ title: "ASP.NET 4 Unleashed", price: 37.79, picture: "AspNet4Unleashed.jpg" }];
    // Render the books using the template
    $("#bookTemplate").tmpl(books).appendTo("#bookContainer");
     
    function formatPrice(price) {
          return "$" + price.toFixed(2);
    }

    HTML页面中引用了大量的外部Javascript文件和CSS文件

    HTML页面中引用了大量的外部Javascript文件和CSS文件,我们知道每一个引用外部文件的<script>或者<style>都会引起一个HTTP请求,而一个HTTP请求的代价其实是很高昂的,下图是HTTP请求的整个过程:

    291355006889108

    首先要通过DNS Server把域名变为IP,然后在浏览器与服务器之间建立TCP链接,建立TCP链接之后,浏览器向服务器发送HTTP请求,服务器处理完请求后,将结果返回给浏览器,最后关闭TCP链接。整个HTTP的请求的代价还是很大的,更多关于HTTP和TCP的信息,请参考:http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocolhttp://en.wikipedia.org/wiki/Transmission_Control_Protocol

    另外浏览器对于HTTP请求的并发数量是有限制的,每个浏览器不等,基本在4个左右。

    当HTML页面中引用了大量的外部Javascript文件和CSS文件,我们可以考虑通过合并以及压缩Javascript,CSS文件来达到减少HTTP请求数量,以及HTTP结果的目的。

    Grunt是一个基于任务的JavaScript项目命令行构建工具,通过Grunt可以将多个文件合并成一个文件,并且进行压缩处理。Grunt没有开发平台的限制,只要是前端项目,都可以使用Grunt来配置任务。Grunt有着广泛的社区支持,有很多的现有的插件。

    另外如果你是ASP.NET的项目的话,ASP.NET 4.5加入了Bundle,通过Bundle技术合并压缩Javascript和CSS。关于Bundle技术可以参考 http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification

    Javascript代码全局变量

    看完了HTML代码之后,又过了一下页面主要的Javascript代码,发现的问题主要是Javascript代码引入了太多的全局变量。JavaScript全局变量在很小的程序中可能会带来方便,但随着程序越来越大,它很快变得难以处理。因为一个全局变量可以被程序的任何部分在任意时间改变,使得程序的行为被极大地复杂化。在程序中使用全局变量降低了程序的可靠性。

    定义Javascript的方式有三种:

    //  在所有函数外部使用var定义变量
    var foo = 10;
    // 没有使用var,直接声明变量
    foo = 10;
    window.foo = 10;

    其中第二种隐式的声明了全局变量,尤其需要注意。

    我们应该尽量少的引入全局变量,jQuery也不过提供了两个全局变量:$, jQuery。那么有没有可能在注入Javascript到HTML页面之后,实现零个全局变量的引入?

    通过立即执行函数可以达到这一点,参见下面的代码:

    (function(win) {
        "use strict";
        var doc = win.document;
        // declare other variables here
        // other code goes here
    }(window));

    如果你需要将该对象返回,可以使用如下的方式:

    var module1 = (function(){
        var _count = 0;
        var m1 = function(){
          //...
        };
        var m2 = function(){
          //...
        };
        return {
          m1 : m1,
          m2 : m2
        };
    })();

    这样的话只会引入一个全局变量 module1,而且该对象具有很好的封装性,其内部变量“_count”,在外部是无法访问的。 整个页面其实也还有一些其他小的问题,在这里就不一一赘述了。 说了半天老代码的问题,其实没有对老代码有任何偏见,因为不论它是否美丑,都在为系统服务,都在产生价值。我们只是在追求更好的代码,更可读,更易维护的代码。

  • 相关阅读:
    HDU 4278 Faulty Odometer 8进制转10进制
    hdu 4740 The Donkey of Gui Zhou bfs
    hdu 4739 Zhuge Liang's Mines 随机化
    hdu 4738 Caocao's Bridges tarjan
    Codeforces Gym 100187M M. Heaviside Function two pointer
    codeforces Gym 100187L L. Ministry of Truth 水题
    Codeforces Gym 100187K K. Perpetuum Mobile 构造
    codeforces Gym 100187J J. Deck Shuffling dfs
    codeforces Gym 100187H H. Mysterious Photos 水题
    windows服务名称不是单个单词的如何启动?
  • 原文地址:https://www.cnblogs.com/powertoolsteam/p/Web_tips.html
Copyright © 2020-2023  润新知