我有一个脚本来防止导航离开该页面,因此所做的更改不会意外丢失。不幸的是,如果通过提交表单激活了脚本,这也会“破坏”页面。因此,在按下提交按钮决定停留在页面上之后,我无法再提交表单。
当导航由提交按钮以外的其他操作完成时,不会禁用提交按钮。
有什么方法可以防止这种情况的发生,并允许我“意外地”多次激活该脚本,同时仍然可以在弹出窗口后使用提交按钮?
<script>
window.onbeforeunload = function() {
var inputs = document.getElementsByTagName('input');
var unfinished = 'false';
for (var i = 0; i < inputs.length; ++i) {
if (inputs[i].value != '') {
unfinished = 'true';
}
}
if (unfinished == 'true') {
return 'Are you sure you want to leave?';
}
}
</script>
在激活退出阻止程序之前(通过提交按钮):
<input type="submit" name="commit" value="Edit product" class="btn btn-warning btn-block" data-disable-with="Edit product">
激活退出阻止程序后(通过提交按钮):
<input type="submit" name="commit" value="Edit product" class="btn btn-warning btn-block" data-disable-with="Edit product" disabled="">
如您所见,由于某种原因,它在我的网站上添加了disabled=""
。
一种形式:
<%= simple_form_for @pack, url: pack_path(@pack), method: :patch do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.input :title, class: "form-control center" %>
<%= f.input :pack_type, class: "form-control center" %>
<%= f.input :category_id, prompt: "Select Category", collection: [ "sample-pack", "vocal-pack", "preset-pack", "track-pixel", "track-indie", "track-orchestral"], input_html: { class: "form-control center" } %>
<%= f.input :price, class: "form-control center" %>
<%= f.input :audio_embed, class: "form-control center" %>
<%= f.input :video_embed, class: "form-control center" %>
<%= f.input :art_link, prompt: "ENTER N/A IF STRACK", class: "form-control center" %>
<%= f.input :download_url, class: "form-control center" %>
<%= f.submit "Edit product", class: "btn btn-warning btn-block" %>
<% end %>
<%= link_to "Cancel", packs_path, class: "btn btn-danger top-drop" %>
答案 0 :(得分:1)
我花了一些时间,并建立了一个如何处理此类问题的示例。有几件事是不应该的;
formSubmitting
,该变量用于查看是否正在提交表单,并且在表单的onsubmit
事件中将其设置为true disabled
属性
// Global variable used to determin if the form is being submitted
// This is used to determine if the user is navigating away from the page
// or trying to submit the form
var formSubmitting = false;
function findNonEmptyInputsInForm(formName) {
// the css selector we are using here breaks down like this
// - form[id="' + formName + '"]
// Find the specific formwe want to check the textboxes in
// - > fieldset
// We are only interested in the fieldsets in that form
// - > input[type="text"]
// we only want the inputs in that fieldset that are textboxes
var cssSelector = 'form[id="' + formName + '"] > fieldset > input[type="text"]';
// Call filter on the Array to only find elements that
return Array.prototype.filter.call(document.querySelectorAll(cssSelector), (e) => e.value != '')
}
window.onbeforeunload = function(e) {
// check if the form is being submitted
// we don't want to block the user from
// submittng the form
if (!formSubmitting) {
// reset the formSubmitting flag
formSubmitting = false;
// pull the disabled attribute from the form
var formDisabled = document.forms["test"].getAttribute('disabled') === "";
// check if the disabled attribute has been added
// to the form, we don't want to prevent navigation
// if the disabled attribute is on the form
if (!formDisabled) {
// find all the textboxes that have a value
var noneEmptyElements = findNonEmptyInputsInForm('test');
// check if the user has entered any values in the textbox
// we don't want to prevent navigation if the user
// hasn't modified the form
if (noneEmptyElements.length > 0) {
// display the confirmation
return 'Are you sure you want to leave?';
}
}
}
// reset the formSubmitting flag
formSubmitting = false;
}
<form id="test" name="test" action="/" onsubmit="formSubmitting = true;">
<fieldset form="test">
<label for="test_input">Test Element 1</label>
<input id="test_input" type="text" /><br/>
<label for="test_input2">Test Element 2</label>
<input id="test_input2" type="text" /><br/>
<label for="test_input3">Test Element 3</label>
<input id="test_input3" type="text" /><br/><br />
<button type="submit">Submit</button>
</fieldset>
</form>
这里是小提琴的链接,您可以使用它并添加/删除disabled
属性。 JsFiddle Example