31

我想要的是拥有改变页面一部分的链接,以及它的动态 URL,我可以在其中指定变量,例如#calendar=10_2010tabview=tab2

Check this for an exact example: 单击此处查看确切演示

所以这是我需要的链接格式:

#calendar=10_2010&tabview=tab2

我需要在链接中有变量,calendar这样tabview我就可以在一个页面上更改多个内容而无需重新加载。


或者像http://www.wbhomes.com.au这样的另一种格式,这正是我想要的,但是第一种格式也很好,但这更漂亮。

  • http://wbhomes.com.au/#/propertiesforsale/houseandland/quinnsbeach-waterland1

要求

  • 需要从例如邮件的任何地方访问,或者如果我只是写在 url 栏中。

  • 该链接应该在历史记录中,因此如果我按下后退或前进按钮,则需要访问该页面。

  • 页面刷新也需要工作。


一些资源:

例子:

一些教程:


请帮我!我从来没有找到任何解决方案来做到这一点,但我不想使用 jquery 或任何 API 或任何库,我想要一个工作Javascript/AJAXPHP脚本。

4

7 回答 7

25

对于您问题中链接的演示,实现该功能实际上非常简单 - 因为它根本不使用任何 AJAX(当您开始将 AJAX 添加到组合中时,它变得更加困难 - 稍后解释)。要实现该功能,您将;升级您的链接以使用哈希,然后绑定到 hashchange 事件。不幸的是,hashchange 事件不是跨浏览器兼容的,尽管幸运的是有许多“历史/远程插件”可用 - 多年来我们首选的一个已被证明是jQuery History,它是开源的,得到了​​很好的支持并且正在积极开发: -)。

虽然,当涉及到向 Facebook、 WBHomesBalupton.com等网站添加 AJAX 功能时,您将开始面临一系列严重困难的问题!(我知道我是最后两个站点的首席架构师!)。其中一些问题是:

  • 如何优雅轻松地升级某些内部链接以使用历史记录和 AJAX 功能,并检测哈希何时更改?同时保持其他链接像以前一样工作。
  • 如何从“www.yoursite.com/myapp/a/b/c”重定向到“www.yoursite.com/myapp/#/a/b/c”?并且仍然为用户保持流畅的体验,以使 3 个必要的重定向尽可能流畅。
  • 如何使用 AJAX 提交表单值和数据并更新哈希?如果他们不支持 Javascript,反之亦然。
  • 如何检测 AJAX 请求需要页面的哪个特定区域?这样子页面就会显示正确的页面。
  • AJAX状态改变时如何改变页面标题?和其他非页面内容。
  • 如何在 AJAX 状态加载和更改时执行漂亮的前奏/后奏效果?这样用户就不会被蒙在鼓里。
  • 通过 AJAX 登录时如何更新侧边栏登录信息?显然我们不希望左上角的登录按钮在那里了。
  • 对于没有启用 JS 的用户,如何仍然支持网站?这样它可以优雅地降级并且仍然可以被搜索引擎索引。

我所知道的唯一一个试图解决所有提到的极其困难的问题的开源且可靠的项目已被证明是jQuery Ajaxy。它实际上是对前面提到的 jQuery History 项目的扩展,提供了一个漂亮优雅的高级界面来添加 AJAX 功能来解决幕后的那些难题,因此我们不必担心它们。这也是前面提到的最后几个商业网站使用的选择解决方案。

祝你好运,如果您还有其他问题,请在此答案上发表评论,我会尽快解决 :-)

更新:现在有 HTML5 History API(pushState、popState),它弃用了 HTML4hashchange功能。History.js现在是 jQuery History 的继承者,并为 HTML5 History API 提供跨浏览器兼容性,并为 HTML4 浏览器提供可选的回退。 hashchangejQuery Ajaxy 将为 History.js 升级

于 2010-07-18T15:57:07.553 回答
1

泽瓦兹.. :)

HTML

<a href="/bye.php?user=abc&page=messages" 
   onclick="return goToWithAjax(this);">bye</a> 

Javascript

function goToWithAjax(hash) {
  hash = hash.href ? hash.getAttribute("href", 2) : hash;
  ajax( hash, function( response ) {
    document.getElementById("content").innerHTML = response;
  });
  hash = ("#!/" + hash).replace("//","/");
  window.location.hash = hash;
  return false;
}

//////////////////////////////////////////////////////////////////////////////

function getXmlHttpObject() {
    var xmlHttp;
    try {
        xmlHttp = new XMLHttpRequest();
    } catch (e) {
        try {
            xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
    }
    return xmlHttp;
}

function ajax(url, onSuccess, onError) {
    var xmlHttp = getXmlHttpObject();
    xmlHttp.onreadystatechange = function () {
        if (this.readyState == 4) {
            // onError
            if (this.status != 200) {
                if (typeof onError == 'function') {
                    onError(this.responseText);
                }
            }
            // onSuccess
            else if (typeof onSuccess == 'function') {
                onSuccess(this.responseText);
            }
        }
    };
    xmlHttp.open("GET", url, true);
    xmlHttp.send(null);
    return xmlHttp;
}​
于 2010-07-08T16:48:44.533 回答
1

我认为您可以使用 HTML5 中存在的onHashChange事件或使用在不完全支持 HTML 5 的浏览器中模拟“哈希”行为的 JavaScript 库来非常轻松地做到这一点。一个这样的库可能是MooTools onhashchange,但也有许多其他库。

如果您有一个支持 HTML 5 的浏览器,或者模拟行为的此类库,则只需使用:

window.setash("#newsection");
根据您的用例场景,从 javascript 更改为新内容,和/或对该 onHashChange 事件进行回调以拦截它。

于 2010-07-18T21:10:22.300 回答
1

CorMVC Jquery 框架就是以这种方式完成的,它是开源的,你可以挖掘源代码并从中获取逻辑。

实际上它非常简单。创作者在下面的视频中很好地讲述了这一点。

http://www.bennadel.com/resources/jing/2009-12-21_0933.swf

PS抱歉不能发布第二个链接,因为我是新用户。

于 2010-07-18T21:30:58.603 回答
0

这是大多数新的 AJAXian 开发人员都无法解决的问题。这是一个相当简单的问题。

你需要的第一件事是 jQuery 核心,它在 jquery.com 上是免费的

接下来,您将需要 Ben Alman 的 jQuery 哈希更改甚至插件,您可以在此处找到:http ://benalman.com/projects/jquery-hashchange-plugin/对于支持 html5 的较新版本的浏览器,您将不需要它hashchange 事件,但你会为旧版本的浏览器。您无需执行任何操作,只需将此脚本包含在您的页面中,其余部分由它处理。

现在对于您的链接,您需要以查询字符串的方式构造它们,如下所示:

<a href="user.php?q=/topic/article" class="dynlnk">Link Text/Image</a>

现在您有了指向页面的链接,并且可以在 php 中处理,以防 javascript 被关闭。您所要做的就是使用超级全局 $_GET 并解析查询字符串来处理页面内容。

现在在页面上的 javascript 中,您需要使链接触发 hashchange。您可以通过将 ?q= 替换为这样的 # 来做到这一点。

$(".dynlnk").each(function(){
    $(this).attr("href", $(this).attr("href").replace("?q=", "#"));
});

现在您的链接将触发 hashchange,剩下要做的就是将 hashchange 绑定到执行某些操作的函数。这可以使用 jQuery 非常简单地完成,如下所示:

$(window).bind( 'hashchange', function(e){

    //this splits the part after the hash so you can handle the parts individually.
    //to handle them as one just use location.hash
    pageparts = location.hash.split("/");

});

现在只需添加您所做的任何代码来处理您的 ajax 和内容。

现在您只需要最后一点 javascript 来触发 hashchange,以防页面加载时使用哈希开始,因此您只需在页面加载时调用 windows 触发函数

$(window).trigger( 'hashchange' );

希望这足够清楚,如果没有,请随时与我联系以提出更多问题。

于 2010-07-20T15:46:51.550 回答
0

使用哈希链接允许可收藏/可共享的链接触发 JavaScript 代码,而不是重新加载页面。Ben Almans jQuery hashchange 事件允许您将事件处理程序绑定到 hashchange 事件,该插件适用于通常不支持此功能的旧浏览器。绑定到 hashchange 的事件处理程序可以读取 url 的哈希部分,并调用任何函数。

// register event handler
function bindHashchange() {

    $(window).bind('hashchange', function(event) {
        event.preventDefault();
        var label = location.hash.substring(1);
        handleLabel(label);
    });

    // trigger event so handler will be run when page is opened first time
    // otherwise handler will only run when clicking on hash links
    $(window).trigger('hashchange');
}

// read and handle hash part of url
function handleLabel(label) {

    if ( label.length > 0 ) {
        // using label from url
        switchPage(label);
    } else {
        // use the default label, if no hash link was present
        switchPage('start');
    }
}

// in this case, load hidden <div>'s into a <div id="content">
function switchPage(label) {
    if ( label == 'start ) {
        $('div#content').html($('div#start'));
    } else if ( label == 'some_other_page' ) {
        // do something else
    }
}

这个其他事件处理程序可以处理同一 url 中由点 ('.') 分隔的 2 个参数。

function processHash() {

    var str = location.hash.substring(1);
    var pos = $.inArray('.', str);

    var label = '';
    var arg = '';

    if ( pos > -1 ) {
        label = str.substring(0, pos);
    } else {
        label = str.substring(0);
    }

    if ( pos > 1 ) {
        arg = str.substring(pos+1);
    }

    if ( label.length == 0 ) {
        // the default page to open of label is empty
        loadContent('start');
    } else {
        // load page, and pass an argument
        loadContent(label, arg);
    }
}

如果使用正则表达式,则可以解析任意字符组合。

var registry = {};

// split on character '.'
var args = label.split(/\./g);

for ( i in args ) {
    var arg = args[i];

    // split on character '='
    var temp = arg.split('=');
    var name = temp[0];
    var value = temp[1];

    // store argument in registry
    registry[name] = value;
}
// registry is loaded, ready to run application that depends on arguments

这将转换网址:

mysite/#company.page=items.color=red

进入以下 JavaScript 对象:

对象 { company=undefined, page="items", color="red"}

然后只需在您选择的元素上运行 jQuery 的 show() 或 hide() 函数即可。

这可以转换为非 jQuery JavaScript,但是您将失去 Ben Alman 提供的功能,这对于可移植解决方案至关重要。

于 2010-07-23T00:27:51.943 回答
0

您想要的是一种支持历史的方法AJAX,可以使用许多现有的库来完成。我建议阅读有关历史的 YUI 3 页

于 2010-07-24T03:47:50.917 回答