JQuery HashChange插件修改

来源:互联网 发布:mac vim 编辑:程序博客网 时间:2024/06/10 17:56

在做AJAX的时候前进、后退按钮的处理是比较重要的,可以使用location.hash来解决这个问题。原理这里不再重复,为了方便,我使用了JQuery的HashChange插件,不过这个插件用起来不好:$.locationHash()方法只能设置hash,不能读取hash,不符合JQuery的风格;hashchange事件在用户通过地址栏直接敲“a.htm?#a”这种方式的时候不会触发,必须在ready的时候做处理。
我对这个插件做了修改代码如下:

(function($) {

    $.fn.extend({
        hashchange: function(callback) {
            this.bind('hashchange', callback);

            if (location.hash)//if location.hash is not empty,fire the event when load,make ajax easy
            {
                callback();
            }
        },
        openOnClick: function(href) {
            if (href === undefined || href.length == 0)
                href = '#';
            return this.click(function(ev) {
                if (href && href.charAt(0) == '#') {
                    // execute load in separate call stack
                    window.setTimeout(function() { $.locationHash(href) }, 0);
                } else {
                    window.location(href);
                }
                ev.stopPropagation();
                return false;
            });
        }
    });

    // IE 8 introduces the hashchange event natively - so nothing more to do
    if ($.browser.msie && document.documentMode && document.documentMode >= 8) {
        $.extend({
            locationHash: function(hash) {
                if (!hash)//get hash value
                {
                    if (location.hash.charAt(0) == '#') {
                        return location.hash.substr(1, location.hash.length-1);
                    }
                    return location.hash;
                }
                if (!hash) hash = '#';
                else if (hash.charAt(0) != '#') hash = '#' + hash;
                location.hash = hash;
            }
        });
        return;
    }

    var curHash;
    // hidden iframe for IE (earlier than 8)
    var iframe;

    $.extend({
        locationHash: function(hash) {
            if (!hash)//get hash value
            {
                if (location.hash.charAt(0) == '#') {
                    return location.hash.substr(1, location.hash.length - 1);
                }
                return location.hash;
            }
            if (curHash === undefined) return;

            if (!hash) hash = '#';
            else if (hash.charAt(0) != '#') hash = '#' + hash;

            location.hash = hash;

            if (curHash == hash) return;
            curHash = hash;

            if ($.browser.msie) updateIEFrame(hash);
            $.event.trigger('hashchange');
        }
    });

    $(document).ready(function() {
        curHash = location.hash;
        if ($.browser.msie) {
            // stop the callback firing twice during init if no hash present
            if (curHash == '') curHash = '#';
            // add hidden iframe for IE
            iframe = $('<iframe />').hide().get(0);
            $('body').prepend(iframe);
            updateIEFrame(location.hash);
            setInterval(checkHashIE, 100);
        } else {
            setInterval(checkHash, 100);
        }
    });
    $(window).unload(function() { iframe = null });

    function checkHash() {
        var hash = location.hash;
        if (hash != curHash) {
            curHash = hash;
            $.event.trigger('hashchange');
        }
    }

    if ($.browser.msie) {
        // Attach a live handler for any anchor links
        $('a[href^=#]').live('click', function() {
            var hash = $(this).attr('href');
            // Don't intercept the click if there is an existing anchor on the page
            // that matches this hash
            if ($(hash).length == 0 && $('a[name=' + hash.slice(1) + ']').length == 0) {
                $.locationHash(hash);
                return false;
            }
        });
    }

    function checkHashIE() {
        // On IE, check for location.hash of iframe
        var idoc = iframe.contentDocument || iframe.contentWindow.document;
        var hash = idoc.location.hash;
        if (hash == '') hash = '#';

        if (hash != curHash) {
            if (location.hash != hash) location.hash = hash;
            curHash = hash;
            $.event.trigger('hashchange');
        }
    }

    function updateIEFrame(hash) {
        if (hash == '#') hash = '';
        var idoc = iframe.contentWindow.document;
        idoc.open();
        idoc.close();
        if (idoc.location.hash != hash) idoc.location.hash = hash;
    }

})(jQuery);


$.locationHash()是读取当前页面的hash,$.locationHash("a")是设置当前页面的hash,$(window).hashchange()监听hash改变事件(在第一次绑定事件的时候如果页面有hash值,则立即触发一次事件)。
例子:
            $(window).hashchange(function() {
                alert($.locationHash());
            });
            $("input").click(function() {
                $.locationHash($(this).val());
            });


完整的例子,一个在服务器端进行数字加倍运算:
    <script type="text/javascript">
        var calcFinish = function(data) {
            $("#msg").text(data);
        }
        $(function() {
            $("#btn1").click(function() {
                //改变hash
                $.locationHash($("#txt1").val());
            });
            $(window).hashchange(function() {
                var i = $.locationHash();//获得hash
                if (i) {//发出计算请求
                    $.post("CalcService.ashx", {"i":i},calcFinish);
                }
            });
        });
    </script>

<input type="text" id="txt1" /><span id="msg"></span>
<input type="button" id="btn1" value="calc" />

使用的时候注意前进、后退按钮和地址栏的变化。

代码下载:http://files.cnblogs.com/rupeng/jqueryhashchangedemo.zip


原创粉丝点击