【问题标题】:Persist variables between page loads在页面加载之间保持变量
【发布时间】:2015-07-11 06:32:39
【问题描述】:

我正在尝试捕获我的表单的提交按钮按下,如果表单已提交,页面会刷新并显示一些隐藏字段。我想捕获之前是否提交过表单,如果它在重新加载时提交,我想取消隐藏隐藏字段。我试图使用全局变量来实现这一点,但是我无法使其正常工作。

这是我尝试过的:

  var clicked = false;

  $(document).ready(function() {

    $("input[type='submit'][value='Search']").attr("onclick", "form.act.value='detailSearch'; clicked = true;  return true;");

    if (clicked == true) {
      // show hidden fields
    } else {
      // don't show hidden fields
    }
  });

对这段代码有什么问题有什么建议吗?

【问题讨论】:

  • 我认为没有某种存储就无法做到这一点。你的 JS 变量都会被清理干净。您的整个示波器将被回收。
  • 为什么不将大部分页面放入“部分”并刷新它?
  • 什么是部分?抱歉,我不知道。
  • 您是否考虑过通过ajax提交表单并在提交后显示字段?
  • 您能否详细说明为什么需要刷新页面?如果我们可以避免它,如果您只是在submit 事件上使用preventDefault(而不是您正在使用的click),您也许可以做您想做的事情。

标签: javascript jquery form-submit persistent-storage


【解决方案1】:

尝试使用$.holdReady()history

function show() {
  return $("form input[type=hidden]")
          .replaceWith(function(i, el) {
            return "<input type=text>"
          });
}

$.holdReady(true);
    if (history.state !== null && history.state.clicked === true) {
       // show hidden fields
       // if `history.state.clicked === true` ,
       // replace `input type=hidden` with `input type=text`
       show();
       console.log(history);

    } else {
        // don't show hidden fields
        console.log(history);
    }
$.holdReady(false);

  $(document).ready(function() {

    $("input[type=submit][value=Search]")
    .on("click", function(e) {
        e.preventDefault();
        if (history.state === null) {
          // do stuff
          history.pushState({"clicked":true});
          // replace `input type=hidden` with `input type=text`
          show();
          console.log(history);
        } else {
          // do other stuff
        };
    });

  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form method="POST">
    <input type="text" name="name" value="" />
    <input type="submit" value="Search" />
    <input type="hidden" />
    <input type="hidden" />
</form>

【讨论】:

    【解决方案2】:

    由于 HTTP 是无状态的,因此每次加载页面时,它都会使用您在 JavaScript 中设置的初始值。您不能在 JS 中设置全局变量,并在再次加载页面后简单地保留该值。

    有几种方法可以将值存储在另一个位置,以便在加载时使用 JavaScript 对其进行初始化


    查询字符串

    当使用GET 方法提交表单时,URL 会使用查询字符串 (?parameter=value&amp;something=42) 进行更新。您可以通过将表单中的输入字段设置为某个值来利用它。这是最简单的例子:

    <form method="GET">
        <input type="hidden" name="clicked" value="true" />
        <input type="submit" />
    </form>
    

    在页面初始加载时,没有设置查询字符串。当您提交此表单时,输入的namevalue 组合将作为clicked=true 在查询字符串中传递。因此,当页面再次使用该查询字符串加载时,您可以检查按钮是否被单击。

    要读取这些数据,您可以在页面加载时使用以下脚本:

    function getParameterByName(name) {
        name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
        var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
            results = regex.exec(location.search);
        return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
    }
    
    var clicked = getParameterByName('clicked');
    

    (Source)

    能否使用它取决于您的表单当前的工作方式,如果您已经使用 POST,那么这可能会出现问题。

    此外,对于较大的数据集,这不是最佳的。传递字符串并不是什么大问题,但对于数组和数据对象,您可能应该使用 Web Storage 或 cookie。虽然不同浏览器的细节有所不同,但 URI 长度的实际限制约为 2000 characters


    网络存储

    随着 HTML5 的引入,我们还获得了 Web Storage,它允许您跨页面加载在浏览器中保存信息。 localStorage 可以将数据保存更长时间(只要用户不手动清除它)和sessionStorage 仅在您当前的浏览会话期间保存数据。后者在这里对您很有用,因为您不想在用户稍后返回时将“clicked”设置为 true。

    这里我设置了按钮点击事件的存储,但你也可以将它绑定到表单提交或其他任何东西。

    $('input[type="submit"][value="Search"]').click(function() {
        sessionStorage.setItem('clicked', 'true');
    });
    

    然后,当您加载页面时,您可以使用以下方法检查它是否设置:

    var clicked = sessionStorage.getItem('clicked');
    

    即使此值仅在此浏览会话期间保存,您也可能希望提前重置它。为此,请使用:

    sessionStorage.removeItem('clicked');
    

    如果您想保存一个 JS 对象或数组,您应该将其转换为字符串。根据规范,应该可以保存其他数据类型,但这还没有在浏览器中正确实现。

    //set
    localStorage.setItem('myObject', JSON.stringify(myObject));
    
    //get
    var myObject = JSON.parse(localStorage.getItem('myObject'));
    

    浏览器支持是pretty great,所以除非你需要支持非常老的/晦涩的浏览器,否则你应该可以安全地使用它。网络存储是未来。


    Cookies

    Web 存储的替代方法是将数据保存在 cookie 中。 Cookies 主要用于读取服务器端的数据,但也可以用于纯粹的客户端数据。

    您已经使用了 jQuery,这使得设置 cookie 变得非常容易。同样,我在这里使用click 事件,但可以在任何地方使用。

    $('input[type="submit"][value="Search"]').click(function() {
        $.cookie('clicked', 'true', {expires: 1}); // expires in 1 day
    });
    

    然后在页面加载时,您可以像这样读取 cookie:

    var clicked = $.cookie('clicked');
    

    在您的情况下,由于 cookie 在会话中持续存在,因此您需要在完成任何您需要对其执行的操作后立即取消设置它们。您不希望用户在一天后回来,仍然将 clicked 设置为 true。

    if(clicked === "true") {
        //doYourStuff();
        $.cookie('clicked', null);
    }
    

    (可以在right here找到一种非jQuery设置/读取cookie的方法)

    我个人不会将 cookie 用于记住单击状态这样简单的事情,但如果查询字符串不是一个选项,并且您需要支持不支持 sessionStorage 的非常旧的浏览器,这将起作用。您应该首先通过检查 sessionStorage 来实现它,并且只有在失败时才使用 cookie 方法。


    window.name

    虽然这对我来说似乎是一种可能起源于 localStorage/sessionStorage 之前的 hack,但您可以将信息存储在 window.name 属性中:

    window.name = "my value"
    

    它只能存储字符串,所以如果你想保存一个对象,你必须像上面的localStorage例子一样将它字符串化:

    window.name = JSON.stringify({ clicked: true });
    

    主要区别在于,此信息不仅会在页面刷新时保留,而且还会在不同的域中保留。但是,它仅限于您所在的当前标签页。

    这意味着您可以在您的页面上保存一些信息,并且只要用户停留在该标签中,即使他浏览到另一个网站并返回,您也可以访问相同的信息。一般来说,我建议不要使用它,除非您需要在单个浏览会话期间实际存储跨域信息。

    【讨论】:

    • 呃,写完之后我才读到你的赏金描述,上面写着“没有 cookie 或本地存储”。对于可能需要它的其他人,我会保留此评论,但您只需要使用我猜的查询字符串。
    • 基本上我已经在很多情况下为我的 Web 应用程序使用 localStorage,我想避免使用太多的 localStorage 变量。但是,我确实喜欢在完成后删除 localStorage 项目的想法。这是我在使用 localStorage 变量时没有想到的。
    • 在 post 请求的情况下,您可以修改操作 -attribute $("#formid").attr("action", url+"&clicked=1") 并从 $( "#formid").attr("method") 但它可能无法解决如何检测重载问题
    • @TheNewbie 我写这个答案已经有一段时间了,但我刚刚添加了一个新选项(window.name)。不使用 cookie/localStorage,它可能会完全满足您的需求。
    • 我想补充一点,本地和会话存储在较新的浏览器上也不是完全可靠的。通常有一个回退到 window.name。
    【解决方案3】:

    你可以试试这个:

     $("input[type='submit'][value='Search']").click(function(){
         form.act.value='detailSearch'; 
         clicked = true;  
         return true;
    });
    

    【讨论】:

    • 当页面重新加载时,仍然将点击值设为false。
    • @TheNewbie 你认为你可以传递一个查询字符串吗?刷新页面时,当前的方法将不起作用。
    【解决方案4】:

    使用localeStoragesessionStorage 似乎是最好的选择。

    不要将clicked 变量保存在全局范围内,以这种方式存储它:

    if(localeStorage.getItem("clicked") === null)
        localeStorage.setItem("clicked", "FALSE"); // for the first time
    
    $(document).ready(function() {
    
        $("input[type='submit'][value='Search']").attr("onclick", "form.act.value='detailSearch';return true;");
    
        var clicked = localeStorage.getItem("clicked") == "FALSE" ? "TRUE" : "FALSE";
    
        localeStorage.setItem("clicked", clicked);
    
        if (clicked == "TRUE") {
          // show hidden fields
        } else {
          // don't show hidden fields
        }
    
    });
    

    【讨论】:

    • 我打算最好不要使用 localstorage 或 sessionStorage。
    猜你喜欢
    • 2023-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多