繁体   English   中英

在 Safari 中提交表单之前更改元素可见性有时不起作用

[英]Changing element visibility just before form submitting in Safari doesn't work sometimes

这是我用来在整个应用程序中显示加载微调器的 html 元素(处于其原始状态)(主要使用 Bootstrap 类):

<div id="loadSpinner" class="overlay d-flex justify-content-center invisible">
  ...
</div>

这是视图中的表格(Rails 6):

  <%= form_with(url: result_path, 
      method: "patch", local: true) do |f| %>

    ...

    <%= f.submit "Finish", class: "btn btn-success btn-lg my-3",
        onclick: "finish();" %>

  <% end %>

这是加载微调器显示的 'finish()' js 函数:

function finish() {
  ...
  document.querySelector('#loadSpinner').classList.remove('invisible');
}

它在 Chrome 和 Firefox 中运行良好,但加载微调器有时不会显示在 Safari 中。

我在删除'invisible' class 之后添加了一些日志( console.log(document.querySelector('#loadSpinner')) )并且可以看到在提交之前实际上删除了'invisible' class。 所以 js 代码工作正常,但微调器只是没有出现。

另外,我尝试在删除“不可见”后添加一个“可见” class - 问题仍然存在。

有人知道为什么它会发生在 Safari 中吗?

我有一个假设,实际上提交是在“不可见” class 被实际删除之前以某种方式发生的,但我不知道检查和修复它的方法。

如果您使用的是 Rails UJS,您可以使用ajax:beforeSendajax:complete事件来切换微调器:

<%= form_with(url: result_path, method: "patch", remote: true, class: 'spinner-form') do |f| %>
let form = document.querySelector('#myForm');
let spinner = document.querySelector('#loadSpinner');

document.addEventListener('ajax:beforeSend', (event)=>{
  if (!event.target.matches('.spinner-form)) return;
  spinner.classList.remove('invisible');
});

document.addEventListener('ajax:complete', (event)=>{
  if (!event.target.matches('.spinner-form)) return;
  spinner.classList.add('invisible');
});

如果你自己做,你想阻止默认事件处理程序:

<%= f.submit "Finish", class: "btn btn-success btn-lg my-3",
        id: "myButton" %>
let btn = document.querySelector('#myButton');
let spinner = document.querySelector('#loadSpinner');

btn.addEventListener('click', (event)=>{
  let form = event.target.form;
  event.preventDefault();
  spinner.classList.add('invisible');

  fetch(form.action)
    .then((response)=>{
       spinner.classList.remove('invisible');
     });
});

如果这不是 XHR (ajax) 请求,那么当页面重新加载时脚本执行停止时,这将无法正常工作。

由于某种原因,Safari 在提交表单之前需要一点延迟。

所以解决方案如下。

  1. 将表单中的提交按钮更改为简单按钮:
<%= form_with(url: result_path, 
    method: "patch", local: true) do |f| %>

...
    
<%= button_tag "Finish", type: "button",
          class: "btn btn-success btn-lg my-3",
          onclick: "finish();" %>

<% end %>
  1. 稍微延迟提交数据:
function finish() {
  ...
  document.querySelector('#loadSpinner').classList.remove('invisible');
  
  // submit form
  setTimeout(function() {
    document.querySelector('form').submit();
  }, 300);  
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM