单页应用(SPA)示例

<!doctype html>
<html lang="zh">
<head>
    <meta charset="utf-8">
    <title>单页应用(SPA)示例</title>
    <style>
        [data-page] {
            display: none;
        }
    </style>
</head>
<body>


<div data-page="index">
    当前位置:首页
    <p><a href="./spa.html#page=list">打开列表页</a></p>
</div>


<div data-page="list">
    当前位置:首页 » 列表页
    <p><a href="./spa.html#page=index">返回首页</a></p>
    <p><a href="./spa.html#page=view">打开内容页</a></p>
</div>


<div data-page="view">
    当前位置:首页 » 列表页 » 内容页
    <p><a href="./spa.html#page=index">返回首页</a></p>
    <p><a href="./spa.html#page=list">返回列表页</a></p>
</div>


<script type="text/javascript" src="./jquery.min.js"></script>
<script type="text/javascript">
    function parse_url(str, component) {
        var query;
        var mode = (typeof require !== "undefined" ? require("../info/ini_get")("locutus.parse_url.mode") : undefined) || "php";
        var key = ["source", "scheme", "authority", "userInfo", "user", "pass", "host", "port", "relative", "path", "directory", "file", "query", "fragment"];
        var parser = {php: new RegExp(["(?:([^:\\/?#]+):)?", "(?:\\/\\/()(?:(?:()(?:([^:@\\/]*):?([^:@\\/]*))?@)?([^:\\/?#]*)(?::(\\d*))?))?", "()", "(?:(()(?:(?:[^?#\\/]*\\/)*)()(?:[^?#]*))(?:\\?([^#]*))?(?:#(.*))?)"].join("")), strict: new RegExp(["(?:([^:\\/?#]+):)?", "(?:\\/\\/((?:(([^:@\\/]*):?([^:@\\/]*))?@)?([^:\\/?#]*)(?::(\\d*))?))?", "((((?:[^?#\\/]*\\/)*)([^?#]*))(?:\\?([^#]*))?(?:#(.*))?)"].join("")), loose: new RegExp(["(?:(?![^:@]+:[^:@\\/]*@)([^:\\/?#.]+):)?", "(?:\\/\\/\\/?)?", "((?:(([^:@\\/]*):?([^:@\\/]*))?@)?([^:\\/?#]*)(?::(\\d*))?)", "(((\\/(?:[^?#](?![^?#\\/]*\\.[^?#\\/.]+(?:[?#]|$)))*\\/?)?([^?#\\/]*))", "(?:\\?([^#]*))?(?:#(.*))?)"].join(""))};
        var m = parser[mode].exec(str);
        var uri = {};
        var i = 14;
        while (i--) if (m[i]) uri[key[i]] = m[i];
        if (component) return uri[component.replace("PHP_URL_", "").toLowerCase()];
        if (mode !== "php") {
            var name = (typeof require !== "undefined" ? require("../info/ini_get")("locutus.parse_url.queryKey") : undefined) || "queryKey";
            parser = /(?:^|&)([^&=]*)=?([^&]*)/g;
            uri[name] = {};
            query = uri[key[12]] || "";
            query.replace(parser, function ($0, $1, $2) {
                if ($1) uri[name][$1] = $2
            })
        }
        delete uri.source;
        return uri
    }


    function parse_str(str, array) {
        var strArr = String(str).replace(/^&/, "").replace(/&$/, "").split("\x26");
        var sal = strArr.length;
        var i;
        var j;
        var ct;
        var p;
        var lastObj;
        var obj;
        var undef;
        var chr;
        var tmp;
        var key;
        var value;
        var postLeftBracketPos;
        var keys;
        var keysLen;
        var _fixStr = function (str) {
            return decodeURIComponent(str.replace(/\+/g, "%20"))
        };
        var $global = typeof window !== "undefined" ? window : global;
        $global.$locutus = $global.$locutus || {};
        var $locutus = $global.$locutus;
        $locutus.php = $locutus.php || {};
        if (!array) array = $global;
        for (i = 0; i < sal; i++) {
            tmp = strArr[i].split("\x3d");
            key = _fixStr(tmp[0]);
            value = tmp.length < 2 ? "" : _fixStr(tmp[1]);
            while (key.charAt(0) === " ") key = key.slice(1);
            if (key.indexOf("\x00") > -1) key = key.slice(0, key.indexOf("\x00"));
            if (key && key.charAt(0) !== "[") {
                keys = [];
                postLeftBracketPos = 0;
                for (j = 0; j < key.length; j++) if (key.charAt(j) === "[" && !postLeftBracketPos) postLeftBracketPos = j + 1; else if (key.charAt(j) === "]") if (postLeftBracketPos) {
                    if (!keys.length) keys.push(key.slice(0, postLeftBracketPos - 1));
                    keys.push(key.substr(postLeftBracketPos, j - postLeftBracketPos));
                    postLeftBracketPos = 0;
                    if (key.charAt(j + 1) !== "[") break
                }
                if (!keys.length) keys = [key];
                for (j = 0; j < keys[0].length; j++) {
                    chr = keys[0].charAt(j);
                    if (chr === " " || chr === "." || chr === "[") keys[0] = keys[0].substr(0, j) + "_" + keys[0].substr(j + 1);
                    if (chr === "[") break
                }
                obj = array;
                for (j = 0, keysLen = keys.length; j < keysLen; j++) {
                    key = keys[j].replace(/^['"]/, "").replace(/['"]$/, "");
                    lastObj = obj;
                    if (key !== "" && key !== " " || j === 0) {
                        if (obj[key] === undef) obj[key] = {};
                        obj = obj[key]
                    } else {
                        ct = -1;
                        for (p in obj) if (obj.hasOwnProperty(p)) if (+p > ct && p.match(/^\d+$/g)) ct = +p;
                        key = ct + 1
                    }
                }
                lastObj[key] = value
            }
        }
    }


    function basename(path, suffix) {
        let b = path;
        const lastChar = b.charAt(b.length - 1);
        if (lastChar === '/' || lastChar === '\\') {
            b = b.slice(0, -1)
        }
        b = b.replace(/^.*[/\\]/g, '');
        if (typeof suffix === 'string' && b.substr(b.length - suffix.length) === suffix) {
            b = b.substr(0, b.length - suffix.length)
        }
        return b
    }


    function pathinfo(path, options) {
        let opt = '';
        let realOpt = '';
        let optName = '';
        let optTemp = 0;
        const tmpArr = {};
        let cnt = 0;
        let i = 0;
        let haveBasename = false;
        let haveExtension = false;
        let haveFilename = false;
        if (!path) {
            return false
        }
        if (!options) {
            options = 'PATHINFO_ALL'
        }
        const OPTS = {PATHINFO_DIRNAME: 1, PATHINFO_BASENAME: 2, PATHINFO_EXTENSION: 4, PATHINFO_FILENAME: 8, PATHINFO_ALL: 0};
        for (optName in OPTS) {
            if (OPTS.hasOwnProperty(optName)) {
                OPTS.PATHINFO_ALL = OPTS.PATHINFO_ALL | OPTS[optName]
            }
        }
        if (typeof options !== 'number') {
            options = [].concat(options);
            for (i = 0; i < options.length; i++) {
                if (OPTS[options[i]]) {
                    optTemp = optTemp | OPTS[options[i]]
                }
            }
            options = optTemp
        }
        const _getExt = function (path) {
            const str = path + '';
            const dotP = str.lastIndexOf('.') + 1;
            return !dotP ? false : dotP !== str.length ? str.substr(dotP) : ''
        };
        if (options & OPTS.PATHINFO_DIRNAME) {
            const dirName = path.replace(/\\/g, '/').replace(/\/[^/]*\/?$/, '');
            tmpArr.dirname = dirName === path ? '.' : dirName
        }
        if (options & OPTS.PATHINFO_BASENAME) {
            if (haveBasename === false) {
                haveBasename = basename(path)
            }
            tmpArr.basename = haveBasename
        }
        if (options & OPTS.PATHINFO_EXTENSION) {
            if (haveBasename === false) {
                haveBasename = basename(path)
            }
            if (haveExtension === false) {
                haveExtension = _getExt(haveBasename)
            }
            if (haveExtension !== false) {
                tmpArr.extension = haveExtension
            }
        }
        if (options & OPTS.PATHINFO_FILENAME) {
            if (haveBasename === false) {
                haveBasename = basename(path)
            }
            if (haveExtension === false) {
                haveExtension = _getExt(haveBasename)
            }
            if (haveFilename === false) {
                haveFilename = haveBasename.slice(0, haveBasename.length - (haveExtension ? haveExtension.length + 1 : haveExtension === false ? 0 : 1))
            }
            tmpArr.filename = haveFilename
        }
        cnt = 0;
        for (opt in tmpArr) {
            if (tmpArr.hasOwnProperty(opt)) {
                cnt++;
                realOpt = opt
            }
        }
        if (cnt === 1) {
            return tmpArr[realOpt]
        }
        return tmpArr
    }
</script>
<script type="text/javascript">
    function getPage() {
        // 解析URL(从URL中获取page参数的值),URL示例:https://www.domain.com/spa.html#page=list
        let parse = new Object();
        parse_str(parse_url(window.location.href).fragment, parse);
        let page = parse.hasOwnProperty('page') ? parse.page.toString() : 'index';

        // 避免page参数的值为空字符串或对应的页面不存在
        if (page === '') {
            page = 'index';
        }
        if ($('[data-page="' + page + '"]').length === 0) {
            page = 'index';
        }

        return page;
    }

    function displayPage(page) {
        $('[data-page="' + page + '"]').show().siblings().hide();
    }

    $(function () {
        // 当浏览器地址栏的URL发生变化就会触发popstate事件
        window.onpopstate = function (event) {
            displayPage(getPage());
        };

        displayPage(getPage());
    });
</script>
</body>
</html>

Copyright © 2024 码农人生. All Rights Reserved