zoukankan      html  css  js  c++  java
  • html与JacaScript中的重要思想:预留后路、向后兼容、js分离

    以一个简单的web程序为例

    详细设计模式请配合代码及凝视食用

    <!DOCTYPE html>
    <!--
    1 预留退路:假设用户禁用了js。链接还能正常显示吗?(href)
    2 分离js:行为层与结构层真的分开且互不干扰吗?(onclick)
    3 向后兼容:js代码中检測了浏览器的函数支持吗?(if(!xxx)return)
    -->
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>ImageGallery</title>
    
        <!--<script type="text/javascript" src="scripts/showPic.js"></script>-->
        <script type="text/javascript" src="scripts/preparegallery.js"></script>
        <!--<script type="text/javascript" src="scripts/popUp.js"></script> 測试弹窗脚本-->
        <link rel="stylesheet" href="css/layout.css" type="text/css" media="screen">
        <!--<link rel="stylesheet" href="css/.warning.css" type="text/css" media="screen">-->
    
    </head>
    
    <body>
        <h1>snapshots</h1>
            <!-- 測试通过链接调用js函数-->
            <!--<a href="javascript:popUp('http://www.baidu.com');">test 'javascript:'</a>-->
            <!-- 測试通过onclick调用js函数-->
            <!--<a href="#" onclick="popUp('http://www.baidu.com');return false">test on click popUp</a>-->
            <!-- 预留退路:将href地址与popup的url地址设为同样的-->
            <!--<a href="http://www.baidu.com" onclick="popUp('http://www.baidu.com');return false;">test popup</a>-->
            <!-- 使用弹窗的标准写法2个-->
            <!--<a href="http://www.baidu.com" onclick="popUp(this.getAttribute('href'));return false;">test popup</a>-->
            <!--<a href="http://www.baidu.com" onclick="popUp(this.href);return false;">test popup</a>-->
            <!-- test warning css-->
            <!--<p class="warning">Be careful!</p>-->
        <ul id="imagegallery"><!-- js分离的群体控制,挂钩子-->
            <li>
                <!--js分离前(onclick)<a href="images/fireworks.jpg"
                onclick="showPic(this);return false;" title="A firework display">Firework</a>-->
                <!--測试js分离(popup)(单个控制)<a href="images/fireworks.jpg"
                title= "A firework display" class="popup">Fireworks</a>-->
                <a href="images/fireworks.jpg" title="A firework display">
                    Fireworks</a>
            </li>
            <li>
                <a href="images/coffee.jpg" title="A cup of black coffee">
                    Coffee</a>
            </li>
            <li>
                <a href="images/rose.jpg" title="A red, red rose">
                    Rose</a>
            </li>
            <li>
                <a href="images/bigben.jpg" title="The famous clock">
                    BigBen</a>
            </li>
        </ul>
        <img id="placeholder" src="images/placeholder.gif" alt="my image gallery" onload="alert(3)"/> <!--img:alt 无法显示图片时用来替换的文本-->
        <p id="description">Choose an image.</p>
    </body>
    </html>


    window.onload = preparegallery;
    //addLoadEvent(preparegallery());
    //addLoadEvent(showPic());
    
    function preparegallery(){
        if (!document.getElementsByTagName) return false; // 向后兼容
        if (!document.getElementById) return false;
        if (!document.getElementById("imagegallery")) return false; // 预防性措施
    
        var gallery = document.getElementById("imagegallery");
        var links = gallery.getElementsByTagName("a");
        for (var i=0; i<links.length; i++) {
            links[i].onclick = function() {
                // 此处依据showPic的返回值控制了:onclick之后是否还要再打开一次链接(预留退路)
                //alert(showPic(this));
                return showPic(this);
            }
        }
    }
    
    // 改良后的showPic函数 (集成里替换图片、替换文字的两个功能)
    // 为什么检測的这么仔细呢,面对我们不可控制的html时写的js代码,不能主观觉得html里一定有什么,有点fuzzing的感觉
    function showPic(whichpic) {
        // 向后兼容。假设没有placeholder,那么onclick函数全然无用,
        // 考虑到“预留退路”,应该不取消onclick后面的return!
        // 此处用showPic的返回值进行控制是否取消onclick的"后摇"
        // (见调用showPic()的onclick函数!

    ) if (!document.getElementById("placeholder")) return true; // 向后兼容(不取消onclick之后的默认动作) var source = whichpic.getAttribute("href"); // 检查是否是图片 注意在nodeName中全是大写的 var placeholder = document.getElementById("placeholder"); if (placeholder.nodeName != "IMG") return true; placeholder.setAttribute("src", source); // 替换图片 if (!document.getElementById("description")) return false; // 向后兼容(取消默认动作) var description = document.getElementById("description"); if (whichpic.getAttribute("title")) { // 继续降低依赖性,用if推断 var text = whichpic.getAttribute("title"); } else { var text = ''; // 这样处理即使出错也不会影响视觉效果 } // 检查是否是文本 if (description.firstChild.nodeType == 3) { description.firstChild.nodeValue = text; // 替换文本 } return false; // 千万别忘了这一句 } /* // 载入js函数的通用方式 // 由于要将js分离,将onclick写到js里,所以须要在载入完html后、接受用户操作前载入js函数 // 为避免onload的冲突,採用下面两种通用方式 //1 为onload指定函数 window.onload = function(){ showPic(); preparegallery(); }; //2 程序化解决(在脚本库中加入addLoadEvent() 函数 并在加入时调用) addLoadEvent(preparegallery()); */

    function addLoadEvent(func) {
        var oldonload = window.onload;
        if (typeof window.onload != 'function') {
            window.onload = func;
        }
        else{
            window.onload = function(){
                oldonload();
                func();
            }
        }
    }
    
    //使用:
    //addLoadEvent(function_name)

    /**
     *
     * Created by xy on 7/18/15.
     */
    
    function popUp(winURL){
        window.open(winURL, "popUp", "width=320, height=480");
    }
    
    /*
    //分离js与html(将onclick方法放入js代码中)
    //script文档在html的head标签里被引入并载入,所以以下代码将会在body载入之前就执行,是无效的
    
    var links = document.getElementsByTagName("a");
    for (var i=0; i<links.length; i++) {
        links[i].onclick = function(){
            popUp(this.getAttribute("href"));
            return false;
        }
    }
    */
    
    /*
    //正确的处理方式(分离js)
    
    window.onload = prepareLinks;
    function prepareLinks(){
        var links = document.getElementsByTagName("a");
        for (var i=0; i<links.length; i++) {
            if(links[i].getAttribute("class") == "popup") { //对具有class=popup属性的标签载入onclick方法
                links[i].onclick = function() {
                    popUp(this.getAttribute("href"));  //调用popUp函数
                    return false;
                }
            }
        }
    }
    */
    
    //向后兼容(察看浏览器知否支持这种方法)
    //为了降低大括号层数,使用if(!xxx)return false;特别注意这里的方法不是调用。方法后面不要有小括号!

    //改动上例代码例如以下 //window.onload = prepareLinks; function prepareLinks(){ if (!document.getElementsByTagName) return false; // see this ! var links = document.getElementsByTagName("a"); for (var i=0; i<links.length; i++) { if(links[i].getAttribute("class") == "popup") { links[i].onclick = function() { popUp(this.getAttribute("href")); return false; } } } }



  • 相关阅读:
    Leetcode 92. Reverse Linked List II
    Leetcode 206. Reverse Linked List
    Leetcode 763. Partition Labels
    Leetcode 746. Min Cost Climbing Stairs
    Leetcode 759. Employee Free Time
    Leetcode 763. Partition Labels
    搭建数据仓库第09篇:物理建模
    Python进阶篇:Socket多线程
    Python进阶篇:文件系统的操作
    搭建数据仓库第08篇:逻辑建模–5–维度建模核心之一致性维度2
  • 原文地址:https://www.cnblogs.com/slgkaifa/p/6986212.html
Copyright © 2011-2022 走看看