在 jQuery Mobile 中使用 Ajax 重新发布表单,以获取后退/前进历史记录

发布于 2024-12-13 08:02:11 字数 3184 浏览 0 评论 0原文

我正在调查 jQM 历史管理对于我组织的移动网站的适用性。我们的部分要求是,当用户发布表单时,它使用 Ajax 进行发布。当用户点击“后退”然后“前进”浏览器按钮时,我们需要再次使用 Ajax 重新发布表单。这是一个图表:

  1. [home.php: post to new.php] =>
  2. [new.php: 发布到 list.php] =>
  3. [从list.php,点击两次返回home.php] =>
  4. [* home.php:单击 fwd,对 new.php 执行 GET 请求 *] =>
  5. [* new.php:单击 fwd,对 list.php 执行 GET 请求 *]

[*] 不是我想要的行为。我想重新发布步骤 1 和 2 中的数据

在步骤 4 和 5 期间,我想在“pagebeforeload”事件(似乎是正确的位置)处拦截 jQM 执行,并修改 data.options.data (以包括传递给事件处理程序的数据对象的序列化后数据)和 data.options.type(至 POST)属性。然后我会让页面加载过程继续使用修改后的值。我认为这会给我带来我想要的行为。

到目前为止,我发现我可以拦截 pagebeforeload 事件并使用以下事件处理程序修改值:

$(document).bind("pagebeforeload",
    function( e, data ) {
        console.log(data.toPage);
        console.log(data.options);
        data.options.type = "POST";
        data.options.data = "edit=Hanford";
    }
);

但缺少的部分是,如何“存储”步骤 1 和 2 中的信息,以便当我拦截 pagebeforeload 事件时在4和5中,我可以知道如何正确修改“type”和“data”属性。

我制作了一个 jquery/浏览器历史原型来说明我希望从 jQuery Mobile 获得的行为。 JavaScript 是:

$(window).load(function() {
    //listen to the history popstate event
    $(window).bind('popstate',
    function(e) {
        if (e.originalEvent.state && e.originalEvent.state.type && e.originalEvent.state.type == "post") {
            //do an ajax post based on what is stored in history state
            $.post(e.originalEvent.state.path,
            e.originalEvent.state.data,
            function(data) {jaxer(data,'POST')});
        } else if (e.originalEvent.state !== undefined){
            //do an ajax get
            $.get(location.pathname,
            function(data) {jaxer(data,'GET')});
        }
    });
    //add event listeners
    addClickHandler();
});
function jaxer(data, msg) {
        if (msg) {console.log(msg+' request made using ajax');}
        $('#slider')[0].innerHTML = data;
        addClickHandler();
}

//hijax hyperlinks and form submissions
function addClickHandler() {
    $('a').click(function(e) {
        history.pushState({
            path: this.path
        },
        '', this.href);
        $.get(this.href,
       function(data) {jaxer(data,'GET')});
       e.preventDefault()
    });
    $('form').submit(function(e) {
        var formData = $(this).serialize();
        console.log('saving serialized form data into historyState: '+formData);
        history.pushState({path: this.action, data: formData, type: "post"},'',this.action);
        $.post(this.action,
        $(this).serialize(),
        function(data) {jaxer(data,'POST')});
        e.preventDefault();
    });
    //add the form submit button to the form as a hidden input such that it will get serialized
    $('form input[type="submit"]').click(function() {
        $(this.form).append("<input type='hidden' name='" + this.name + "' value='" + this.value + "'/>");
    });
    console.log("event handlers added to DOM");
};

当用户启动的 POST 发生时,我将序列化的 POST 数据放入历史记录的状态对象中。然后,当 popstate 事件发生时,我可以查询状态对象以获取此信息。如果我找到它,那么我可以执行 ajax POST。我想在 jQuery Mobile 历史记录处理中获得相同的功能。这样我就可以利用页面更改动画等。

I'm investigating the suitability of the jQM history management for my organization's mobile web site. Part of our requirement is that when a user posts a form, it posts using Ajax. When a user taps "back" and then "forward" browser buttons, we need to re-post the form using Ajax again. Here's a diagram:

  1. [home.php: post to new.php] =>
  2. [new.php: post to list.php] =>
  3. [from list.php, click back twice to home.php] =>
  4. [* home.php: click fwd, does a GET request to new.php *] =>
  5. [* new.php: click fwd, does a GET request to list.php *]

[*] not the behavior I want. I want to re-POST data from steps 1 and 2

During steps 4 and 5, I want to intercept the jQM execution at the "pagebeforeload" event (seems like the right place), and modify the data.options.data (to include the serialized post data) and data.options.type (to POST) properties of the data object which is passed to the event handler. Then I'd let the pageload process move on with the modified values. This, I think, would give me the behavior I want.

So far, I see that I can intercept the pagebeforeload event and modify the values with the below event handler:

$(document).bind("pagebeforeload",
    function( e, data ) {
        console.log(data.toPage);
        console.log(data.options);
        data.options.type = "POST";
        data.options.data = "edit=Hanford";
    }
);

But the missing piece is, how can I "store" the information in steps 1 and 2, such that when I intercept the pagebeforeload event in 4 and 5, I can know to modify the "type" and "data" properties properly.

I've made a jquery/browser History prototype to illustrate the behavior I would like to get from jQuery Mobile. The JavaScript is:

$(window).load(function() {
    //listen to the history popstate event
    $(window).bind('popstate',
    function(e) {
        if (e.originalEvent.state && e.originalEvent.state.type && e.originalEvent.state.type == "post") {
            //do an ajax post based on what is stored in history state
            $.post(e.originalEvent.state.path,
            e.originalEvent.state.data,
            function(data) {jaxer(data,'POST')});
        } else if (e.originalEvent.state !== undefined){
            //do an ajax get
            $.get(location.pathname,
            function(data) {jaxer(data,'GET')});
        }
    });
    //add event listeners
    addClickHandler();
});
function jaxer(data, msg) {
        if (msg) {console.log(msg+' request made using ajax');}
        $('#slider')[0].innerHTML = data;
        addClickHandler();
}

//hijax hyperlinks and form submissions
function addClickHandler() {
    $('a').click(function(e) {
        history.pushState({
            path: this.path
        },
        '', this.href);
        $.get(this.href,
       function(data) {jaxer(data,'GET')});
       e.preventDefault()
    });
    $('form').submit(function(e) {
        var formData = $(this).serialize();
        console.log('saving serialized form data into historyState: '+formData);
        history.pushState({path: this.action, data: formData, type: "post"},'',this.action);
        $.post(this.action,
        $(this).serialize(),
        function(data) {jaxer(data,'POST')});
        e.preventDefault();
    });
    //add the form submit button to the form as a hidden input such that it will get serialized
    $('form input[type="submit"]').click(function() {
        $(this.form).append("<input type='hidden' name='" + this.name + "' value='" + this.value + "'/>");
    });
    console.log("event handlers added to DOM");
};

When a user-initiated POST occurs, I put the serialized POST data into the history's state object. Then, when a popstate event occurs, I can query the state object for this information. If I find it, then I can perform an ajax POST. I would like to get the same functionality within the jQuery Mobile history handling. That way I can take advantage of the page change animations, etc.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文