Javascript 单击表单中的按钮会导致页面刷新

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12319758/
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-08-23 07:43:09  来源:igfitidea点击:

Clicking a button within a form causes page refresh

javascriptangularjs

提问by chubbsondubs

I have a form in Angular that has two buttons tags in it. One button submits the form on ng-click. The other button is purely for navigation using ng-click. However, when this second button is clicked, AngularJS is causing a page refresh which triggers a 404. I've dropped a breakpoint in the function and it is triggering my function. If I do any of the following, it stops:

我有一个 Angular 表单,其中有两个按钮标签。一键提交表单ng-click。另一个按钮纯粹用于使用 进行导航ng-click。但是,当单击第二个按钮时,AngularJS 会导致页面刷新,从而触发 404。我在函数中放置了一个断点,它正在触发我的函数。如果我执行以下任何操作,它就会停止:

  1. If I remove the ng-click, the button doesn't cause a page refresh.
  2. If I comment out the code in the function, it doesn't cause a page refresh.
  3. If I change the button tag to an anchor tag (<a>) with href="", then it doesn't cause a refresh.
  1. 如果我删除ng-click,该按钮不会导致页面刷新。
  2. 如果我注释掉函数中的代码,它不会导致页面刷新。
  3. 如果我使用 将按钮标记更改为锚标记 ( <a>) href="",则不会导致刷新。

The latter seems like the simplest workaround, but why is AngularJS even running any code after my function that causes the page to reload? Seems like a bug.

后者似乎是最简单的解决方法,但为什么 AngularJS 甚至在我的函数之后运行任何导致页面重新加载的代码?好像是个bug。

Here is the form:

这是表格:

<form class="form-horizontal" name="myProfile" ng-switch-when="profile">
  <fieldset>
    <div class="control-group">
      <label class="control-label" for="passwordButton">Password</label>
      <div class="controls">
        <button id="passwordButton" class="secondaryButton" ng-click="showChangePassword()">Change</button>
      </div>
    </div>

    <div class="buttonBar">
      <button id="saveProfileButton" class="primaryButton" ng-click="saveUser()">Save</button>
    </div>
  </fieldset>
</form>

Here is the controller method:

这是控制器方法:

$scope.showChangePassword = function() {
  $scope.selectedLink = "changePassword";
};

回答by LOAS

If you have a look at the W3C specification, it would seem like the obvious thing to try is to mark your button elements with type='button'when you don't want them to submit.

如果您查看W3C 规范,似乎显而易见的尝试是type='button'在您不希望按钮元素提交时标记它们。

The thing to note in particular is where it says

特别要注意的是它说的地方

A button element with no type attribute specified represents the same thing as a button element with its type attribute set to "submit"

未指定 type 属性的 button 元素表示与 type 属性设置为“submit”的按钮元素相同的事物

回答by antage

You can try to prevent default handler:

您可以尝试阻止默认处理程序:

html:

html:

<button ng-click="saveUser($event)">

js:

js:

$scope.saveUser = function (event) {
  event.preventDefault();
  // your code
}

回答by Shane Stillwell

You should declare the attribute ng-submit={expression}in your <form>tag.

您应该ng-submit={expression}<form>标签中声明该属性。

From the ngSubmit docs http://docs.angularjs.org/api/ng.directive:ngSubmit

从 ngSubmit 文档 http://docs.angularjs.org/api/ng.directive:ngSubmit

Enables binding angular expressions to onsubmit events.

Additionally it prevents the default action (which for form means sending the request to the server and reloading the current page).

启用绑定角度表达式以提交事件。

此外,它可以防止默认操作(对于表单意味着将请求发送到服务器并重新加载当前页面)。

回答by pleerock

I use directive to prevent default behaviour:

我使用指令来防止默认行为:

module.directive('preventDefault', function() {
    return function(scope, element, attrs) {
        angular.element(element).bind('click', function(event) {
            event.preventDefault();
            event.stopPropagation();
        });
    }
});

And then, in html:

然后,在 html 中:

<button class="secondaryButton" prevent-default>Secondary action</button>

This directive can also be used with <a>and all other tags

该指令也可以与<a>所有其他标签一起使用

回答by Anderson Ferreira

You can keep <button type="submit">, but must remove the attribute action=""of <form>.

你可以保留<button type="submit">,但必须删除该属性action=""<form>

回答by maaartinus

I wonder why nobody proposed the possibly simplest solution:

我想知道为什么没有人提出可能最简单的解决方案:

don't use a <form>

不要使用 <form>

A <whatever ng-form>does IMHO a better job and without an HTML form, there's nothing to be submitted by the browser itself. Which is exactly the right behavior when using angular.

<whatever ng-form>恕我直言,A做得更好,如果没有 HTML 表单,浏览器本身就不需要提交任何内容。使用 angular 时,这正是正确的行为。

回答by Swapnil Patwa

Add action to your form.

向表单添加操作。

<form action="#">

<form action="#">

回答by user1577263

This answer may not be directly related to the question. It's just for the case when you submit the form using scripts.

这个答案可能与问题没有直接关系。这仅适用于您使用脚本提交表单的情况。

According to ng-submit code

根据ng-submit 代码

 var handleFormSubmission = function(event) {
  scope.$apply(function() {
    controller.$commitViewValue();
    controller.$setSubmitted();
  });

  event.preventDefault();
};

formElement[0].addEventListener('submit', handleFormSubmission);

It adds submit event listener on the form. But submit event handler wouldn't be called when submit is initiated by calling form.submit(). In this case, ng-submit will not prevent the default action, you have to call preventDefault yourself in ng-submit handler;

它在表单上添加了提交事件侦听器。但是,当通过调用 form.submit() 启动提交时,不会调用提交事件处理程序。在这种情况下,ng-submit 不会阻止默认操作,您必须在 ng-submit 处理程序中自己调用 preventDefault;

To provide a reasonably definitive answer, the HTML Form Submission Algorithm item 5 states that a form only dispatches a submit event if it was not submitted by calling the submit method (which means it only dispatches a submit event if submitted by a button or other implicit method, e.g. pressing enter while focus is on an input type text element).

为了提供一个合理确定的答案,HTML 表单提交算法第 5 项指出,如果表单不是通过调用 submit 方法提交的,则表单仅调度提交事件(这意味着它仅在通过按钮或其他隐式提交时才调度提交事件)方法,例如,当焦点位于输入类型文本元素上时按 Enter)。

See Form submitted using submit() from a link cannot be caught by onsubmit handler

请参阅无法通过 onsubmit 处理程序捕获使用 submit() 从链接提交的表单

回答by Sahil Sharma

Just add the FormsModulein the importsarray of app.module.tsfile, and add import { FormsModule } from '@angular/forms';at the top of this file...this will work.

只需FormsModule在文件imports数组中app.module.ts添加 ,并import { FormsModule } from '@angular/forms';在此文件的顶部添加...这将起作用。

回答by Amay Kulkarni

First Button submits the form and second does not

第一个按钮提交表单,第二个按钮不提交

<body>
<form  ng-app="myApp" ng-controller="myCtrl" ng-submit="Sub()">
<div>
S:<input type="text" ng-model="v"><br>
<br>
<button>Submit</button>
//Dont Submit
<button type='button' ng-click="Dont()">Dont Submit</button>
</div>
</form>

<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.Sub=function()
{
alert('Inside Submit');
}

$scope.Dont=function()
{
$scope.v=0;
}
});
</script>

</body>