javascript 使用后退按钮时选择菜单未恢复

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4370819/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 11:11:40  来源:igfitidea点击:

Select menu not being restored when Back button used

javascript

提问by Bill

Consider a web page that has a select menu with a JavaScript event handler tied to the menu's onchange event that when fired reloads the page with a new query string (using the value selected in the menu).

考虑一个网页,它有一个选择菜单,其中一个 JavaScript 事件处理程序与菜单的 onchange 事件相关联,该事件处理程序在触发时使用新的查询字符串(使用菜单中选择的值)重新加载页面。

Issue:when the user hits the Back button, the page DOM is restored from the cache but NOT the state of the select menu.

问题:当用户点击后退按钮时,页面 DOM 会从缓存中恢复,而不是选择菜单的状态。

Browsers affected:Firefox and Safari (which use a back/forward cache)

受影响的浏览器:Firefox 和 Safari(使用后退/前进缓存)

Example:

示例

<script language="javascript" type="text/javascript">
function reloadPage() {
    var menu = document.getElementById("select1");
    var val = menu.options[menu.selectedIndex].value;
    window.location.href = 'test.html?select1=' + val;
} 
</script>
<form action="#" method="get" name="form1">
    <select name="select1" id="select1" onChange="reloadPage();">
    <option value="A" selected>Option A</option>
    <option value="B">Option B</option>
    <option value="C">Option C</option>
    <option value="D">Option D</option>         
    </select>
</form>

View this page and notice that option A is selected. Then select a different option (say option C) - the page is reloaded (with a query string, ?select1=C). Then hit the Back button - the select menu continues to show Option C as selected.

查看此页面并注意选择了选项 A。然后选择一个不同的选项(比如选项 C) - 页面被重新加载(带有查询字符串,?select1=C)。然后点击后退按钮 - 选择菜单继续显示已选择的选项 C。

Question:Does anyone know why the select menu isn't restored and how one could solve this issue? I've used JavaScript in the past to force the form fields on a page to match the query string but there are issues with that approach (i.e., FF and Safari don't normally execute the onload event for the window when loading a page from the cache) and it seems like a hack to me.

问题:有谁知道为什么选择菜单没有恢复以及如何解决这个问题?我过去曾使用 JavaScript 强制页面上的表单字段匹配查询字符串,但这种方法存在问题(即,FF 和 Safari 在从以下位置加载页面时通常不会执行窗口的 onload 事件缓存),这对我来说似乎是一种黑客攻击。

Any suggestions?

有什么建议?

Update:It has just occurred to me that what might be going on is the following:

更新:我刚刚想到可能会发生以下情况:

  1. option C is selected
  2. the page is cached
  3. the JavaScript loads the new URL
  4. hit the back Button
  5. option C is restored because it is what was cached prior to the JavaScript/page reload.
  1. 选择了选项 C
  2. 页面被缓存
  3. JavaScript 加载新 URL
  4. 点击返回按钮
  5. 选项 C 已恢复,因为它是在 JavaScript/页面重新加载之前缓存的内容。

So I think this isn't an issue of the browser not restoring the state of the select menu, it's an issue of timing.

所以我认为这不是浏览器没有恢复选择菜单状态的问题,而是时间问题。

回答by Frank Hoffman

This jQuery code did the trick for me

这个 jQuery 代码对我有用

$(document).ready(function () {
    $("select").each(function () {
        $(this).val($(this).find('option[selected]').val());
    });
})

回答by Mitch

The snippet from @frakhoffy worked for me, but broke normal select behavior in Chrome. When hitting the page without a selected option, the select was blank even though there is not a blank option in the select. I ended up going with:

@frakhoffy 的片段对我有用,但破坏了 Chrome 中的正常选择行为。在没有选择选项的情况下点击页面时,即使选择中没有空白选项,选择也是空白的。我最终去了:

$(document).ready(function () {
  $('select').each(function () {
    var select = $(this);
    var selectedValue = select.find('option[selected]').val();

    if (selectedValue) {
      select.val(selectedValue);
    } else {
      select.prop('selectedIndex', 0);
    }
  });
});

回答by jcolebrand

AFAIK the reason it's not being restored is that DOM isn't the one that was in the cache at the last time of cache-loading. The browser restores what the cached-object was on page-back. You have to maintain state yourself.

AFAIK 没有被恢复的原因是 DOM 不是上次缓存加载时缓存中的那个。浏览器恢复缓存对象在页面返回时的内容。你必须自己维护状态。

I would suggest putting a function in the body proper that will always run as the DOM is parsed (but I've not got a sample environ setup to test this scenario so I'm going on my "it should work" detector)

我建议在主体中放置一个函数,该函数将始终在解析 DOM 时运行(但我没有一个示例环境设置来测试此场景,因此我将继续使用“它应该可以工作”检测器)

<script type="javascript">
  function fix_selects(){
    //do something here to ensure that the select is setup how you want. 
    //Maybe using a window location hash?
  }
  fix_selects();
</script>

回答by Pere

This is what happens by default in forms (not just selects): the browser will keep the last values. I wouldn't add any JavaScript code to alter this behavior unless you want to debug that code with multiple browsers.

这就是表单中的默认情况(不仅仅是选择):浏览器将保留最后一个值。除非您想使用多个浏览器调试该代码,否则我不会添加任何 JavaScript 代码来改变此行为。

The easiest solution, that would fix the problem in most (all?) modern browsers, is to use autocomplete="off"in the <form>tag.

在大多数(所有?)现代浏览器中解决问题的最简单的解决方案是autocomplete="off"<form>标签中使用。

Edit: See answer https://stackoverflow.com/a/14421723/1391963

编辑:见答案https://stackoverflow.com/a/14421723/1391963

回答by juanlu

Here is a vanilla JS version of @Mitch's answer.

这是@Mitch 答案的普通 JS 版本。

let selects = document.getElementsByTagName('select');

for (let i = 0; i < selects.length; ++i) {
    let currentSelect = selects[i];
    let selectedOption = currentSelect.querySelector('option[selected]');
    if (selectedOption) currentSelect.value = selectedOption.value;
}

Here is the performance comparison

这是性能比较

enter image description here

在此处输入图片说明

回答by Christopher

As of January 16, 2020 I had a very similar issue and was unable to find a solution on Stackoverflow.

截至 2020 年 1 月 16 日,我遇到了一个非常相似的问题,并且无法在 Stackoverflow 上找到解决方案。

Here is what fixed this issue for me:

以下是为我解决此问题的方法:

Update Jquery!

更新jQuery!

I updated from an older version (2.x) to 3.4.0. I went with this version since I am running bootstrap 3 and newer versions of Jquery completely break bootstrap 3 any higher than 3.4.0.

我从旧版本 (2.x) 更新到 3.4.0。我使用了这个版本,因为我正在运行 bootstrap 3 和更新版本的 Jquery 完全破坏了 bootstrap 3 任何高于 3.4.0 的版本。

I hope this saves some people some time.

我希望这可以为一些人节省一些时间。