Chặn gửi biểu mẫu bằng JavaScript và ngăn chặn gửi thông thường


82

Có vẻ như có nhiều thông tin về cách gửi biểu mẫu bằng javascript, nhưng tôi đang tìm giải pháp để nắm bắt khi nào biểu mẫu đã được gửi và chặn nó bằng javascript.

HTML

<form>
 <input type="text" name="in" value="some data" />
 <button type="submit">Go</button>
</form>

Khi người dùng nhấn nút gửi, tôi không muốn gửi biểu mẫu mà thay vào đó tôi muốn một hàm JavaScript được gọi.

function captureForm() {
 // do some stuff with the values in the form
 // stop form from being submitted
}

Một cách nhanh chóng là thêm chức năng onclick vào nút nhưng tôi không thích giải pháp này ... có nhiều cách để gửi biểu mẫu ... ví dụ: nhấn quay lại khi đang nhập dữ liệu đầu vào, điều này không tính đến.

Ty


Câu trả lời:


93
<form id="my-form">
    <input type="text" name="in" value="some data" />
    <button type="submit">Go</button>
</form>

Trong JS:

function processForm(e) {
    if (e.preventDefault) e.preventDefault();

    /* do what you want with the form */

    // You must return false to prevent the default form behavior
    return false;
}

var form = document.getElementById('my-form');
if (form.attachEvent) {
    form.attachEvent("submit", processForm);
} else {
    form.addEventListener("submit", processForm);
}

Chỉnh sửa : theo ý kiến ​​của tôi, cách tiếp cận này tốt hơn là đặt onSubmitthuộc tính trên biểu mẫu vì nó duy trì sự tách biệt giữa đánh dấu và chức năng. Nhưng đó chỉ là hai xu của tôi.

Edit2 : Đã cập nhật ví dụ của tôi để bao gồmpreventDefault()


điều này không làm việc với chrome hoặc như xa như tôi có thể nhìn thấy bằng jsbin.com/ejoyas
Eiyrioü von Kauyf

2
Lưu ý rằng mã sự kiện đính kèm cần được thực thi SAU KHI biểu mẫu có sẵn trong dom. Ví dụ sử dụng window.onload=function() { ... }để bọc nó
mplungjan

khi nào thì processform()hàm được gọi ạ?

Không chắc vì tôi không sử dụng IE, nhưng tôi nghĩ rằng thông số đính kèm phải là "gửi kèm".
Gerard ONeill

điều này không làm việc trong chrome 46, lỗi trên gắn một sự kiện, cần phải tải trang đầu tiên
tsukimi

27

Bạn không thể đính kèm các sự kiện trước khi các phần tử mà bạn đính kèm chúng đã tải

Những công việc này -

JS đơn giản

BẢN GIỚI THIỆU

Được đề xuất sử dụng eventListener

window.addEventListener("load",function() {
  document.getElementById('my-form').addEventListener("submit",function(e) {
    e.preventDefault(); // before the code
    /* do what you want with the form */

    // Should be triggered on form submit
    alert('hi');
  });
});

nhưng nếu bạn không cần nhiều hơn một người nghe, bạn có thể sử dụng onload và onsubmit

// Should only be triggered on first page load
alert('ho');

window.onload=function() {
    document.getElementById('my-form').onsubmit=function() {
    /* do what you want with the form */

    // Should be triggered on form submit
    alert('hi');
    // You must return false to prevent the default form behavior
    return false;
  }
}

jQuery

// Should only be triggered on first page load
alert('ho');

$(function() {
  $('#my-form').on("submit",function(e) {
    e.preventDefault(); // cancel the actual submit

    /* do what you want with the form */

    // Should be triggered on form submit

    alert('hi');
  });
});

Ý tôi là: $ ('# my-form) .on (' submit ', function () {alert (' hi ');});
Michiel

1
@Michiel trong khi những gì bạn cung cấp là những gì bạn sử dụng với jQuery, giải pháp này được cung cấp là giải pháp JS thuần túy không phụ thuộc vào jQuery. Giải pháp ở đây sẽ tương tự như sử dụng<form onsubmit="alert('hi'); return false;">
Chris Marisic

2
@ChrisMarisic - một vài tuổi :) Tôi đã cập nhật câu trả lời anyway để bao gồm jQuery
mplungjan

17

<form onSubmit="return captureForm()"> điều đó nên làm. Đảm bảo rằng captureForm()phương thức của bạn trả về false.


Theo dõi: Có cách nào để nắm bắt một biểu mẫu gửi bằng JavaScript mà không ảnh hưởng đến việc xử lý thuộc tính bắt buộc của trình duyệt không?
Elisabeth

@Elisabeth Xử lý thuộc tính gì? Nếu bạn muốn không ngăn biểu mẫu thực sự được gửi, bạn chỉ cần captureForm()quay lại truethay vì gửi false.
kba

Trình duyệt xử lý thuộc tính "bắt buộc". Tôi muốn ngăn không cho biểu mẫu được gửi. Nhưng bằng cách trả về false thay vì true (hoặc sử dụng PreventDefault ()), nó sẽ thay đổi cách trình duyệt xử lý thuộc tính "bắt buộc" trên một phần tử đầu vào. Hãy thử nó cho chính mình: thêm <code> bắt buộc </code> vào một phần tử đầu vào, chụp lại nội dung gửi và xem liệu bạn có mất hành vi mặc định cho nó hay không.
Elisabeth

Tôi dường như không mất hành vi mặc định. Nó hoạt động tốt trong Chrome. Bạn sẽ cần đưa ra một ví dụ sai lầm để tôi giúp đỡ.
kba

1
Được rồi, đây là biểu mẫu: <form method = "get" action = ""> <label for = "color"> Màu yêu thích của bạn là gì? </label> <input type = "text" name = "color" placeholder = "blue" started> <input id = "submit" type = "submit" value = "Submit"> </form> và đây là đoạn mã: function processForm (e) {var form = document.querySelector ("form"); for (var i = 0; i <form.childNodes.length; i ++) {var node = form.childNodes [i]; / * thực hiện nội dung với các nút /} / return false; * /} Thử nghiệm trong opera. Bỏ ghi chú dòng cuối cùng, không thành công. (Mã Xin lỗi không hoạt động tốt trong ý kiến)
Elisabeth

6

Một tùy chọn khác để xử lý tất cả các yêu cầu mà tôi đã sử dụng trong thực tế của mình cho các trường hợp khi tải lên không thể giúp được là xử lý các yêu cầu gửi javascript, gửi html, ajax. Những mã này nên được thêm vào phần trên cùng của phần thân để tạo trình xử lý trước khi bất kỳ biểu mẫu nào được hiển thị và gửi.

Trong ví dụ, tôi đặt trường ẩn thành bất kỳ biểu mẫu nào trên trang khi gửi nó ngay cả khi nó xảy ra trước khi tải trang.

//Handles jquery, dojo, etc. ajax requests
(function (send) {
    var token = $("meta[name='_csrf']").attr("content");
    var header = $("meta[name='_csrf_header']").attr("content");
    XMLHttpRequest.prototype.send = function (data) {
        if (isNotEmptyString(token) && isNotEmptyString(header)) {
            this.setRequestHeader(header, token);
        }
        send.call(this, data);
    };
})(XMLHttpRequest.prototype.send);


//Handles javascript submit
(function (submit) {
    HTMLFormElement.prototype.submit = function (data) {
        var token = $("meta[name='_csrf']").attr("content");
        var paramName = $("meta[name='_csrf_parameterName']").attr("content");
        $('<input>').attr({
            type: 'hidden',
            name: paramName,
            value: token
        }).appendTo(this);

        submit.call(this, data);
    };
})(HTMLFormElement.prototype.submit);


//Handles html submit
document.body.addEventListener('submit', function (event) {
    var token = $("meta[name='_csrf']").attr("content");
    var paramName = $("meta[name='_csrf_parameterName']").attr("content");
    $('<input>').attr({
        type: 'hidden',
        name: paramName,
        value: token
    }).appendTo(event.target);
}, false);

2

Sử dụng câu trả lời của @Kristian Antonsen hoặc bạn có thể sử dụng:

$('button').click(function() {
    preventDefault();
    captureForm();
});

3
cho bất cứ ai khác làm điều này 2,5 năm (hoặc hơn) sau đó, bạn cần phải vượt qua sự kiện click như một tham số cho hàm (như trong function(e)và gọie.preventDefault()
digitaljoel

Cũng có thể được ghi lại trong sự kiện "gửi" cho biểu mẫu, nếu thông tin đầu vào [type = "submit"] của bạn được sử dụng và điều đó đặt bạn vào ngữ cảnh biểu mẫu so với ngữ cảnh của nút. Lệnh gọi lại sẽ luôn có ngữ cảnh của sự kiện, vì vậy bạn không nhất thiết phải chuyển 'e' làm đối số, bạn chỉ cần tham chiếu đến 'sự kiện'.
Augurone

1
Điều này không được khuyến khích, vì quá trình gửi có thể được kích hoạt bằng cách nhấn phím.
jhpratt
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.