Javascript 使用javascript形成动作

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

form action with javascript

javascriptforms

提问by whispering_Hyman

I have a form that must execute a javascript function on submit, the function then posts data to my php send mail file and the mail is sent. But it only works in fire fox. The form action does not seem to be doing anything in IE, my question is: Is this the correct way to call a function from an external file from the form action:

我有一个表单,必须在提交时执行 javascript 函数,然后该函数将数据发布到我的 php 发送邮件文件并发送邮件。但它只适用于火狐。表单操作在 IE 中似乎没有做任何事情,我的问题是:这是从表单操作的外部文件调用函数的正确方法:

action="javascript:simpleCart.checkout()"

simpleCart is the .js file and checkout() is the function.

simpleCart 是 .js 文件, checkout() 是函数。

Tips appreciated, struggling to understand why it would work in firefox but not IE, chrome or safari.

提示赞赏,努力理解为什么它可以在 Firefox 中工作,但不能在 IE、chrome 或 safari 中工作。

<form name=form onsubmit="return validateFormOnSubmit(this)" enctype="multipart/form-data" action="javascript:simpleCart.checkout()" method="post">

回答by Ja?ck

A form action set to a JavaScript function is not widely supported, I'm surprised it works in FireFox.

设置为 JavaScript 函数的表单操作并未得到广泛支持,我很惊讶它可以在 FireFox 中使用。

The best is to just set form actionto your PHP script; if you need to do anything before submission you can just add to onsubmit

最好的方法是将表单设置action为您的 PHP 脚本;如果你需要在提交前做任何事情,你可以添加到onsubmit

Editturned out you didn't need any extra function, just a small change here:

编辑原来你不需要任何额外的功能,只是这里的一个小改动:

function validateFormOnSubmit(theForm) {
    var reason = "";
    reason += validateName(theForm.name);
    reason += validatePhone(theForm.phone);
    reason += validateEmail(theForm.emaile);

    if (reason != "") {
        alert("Some fields need correction:\n" + reason);
    } else {
        simpleCart.checkout();
    }
    return false;
}

Then in your form:

然后以您的形式:

<form action="#" onsubmit="return validateFormOnSubmit(this);">

回答by dkellner

Absolutely valid.

绝对有效。

    <form action="javascript:alert('Hello there, I am being submitted');">
        <button type="submit">
            Let's do it
        </button>
    </form>
    <!-- Tested in Firefox, Chrome, Edge and Safari -->

So for a short answer: yes, this is an option, and a nice one. It says "when submitted, please don't go anywhere, just run this script"- quite to the point.

所以简短回答:是的,这是一种选择,而且是一个不错的选择。它说“提交时,请不要去任何地方,只需运行此脚本”- 非常中肯。

A minor improvement

一个小改进

To let the event handler know which form we're dealing with, it would seem an obvious way to pass on the sender object:

为了让事件处理程序知道我们正在处理哪种表单,传递发送者对象似乎是一种显而易见的方式:

    <form action="javascript:myFunction(this)">  <!-- should work, but it won't -->

But instead, it will give you undefined. You can't access it because javascript:links live in a separate scope. Therefore I'd suggest the following format, it's only 13 characters more and works like a charm:

但相反,它会给你undefined。您无法访问它,因为javascript:链接位于单独的范围内。因此,我建议采用以下格式,它仅多出 13 个字符,就像一个魅力:

    <form action="javascript:;" onsubmit="myFunction(this)">  <!-- now you have it! -->

... now you can access the sender form properly. (You can write a simple "#" as action, it's quite common - but it has a side effect of scrolling to the top when submitting.)

...现在您可以正确访问发件人表单。(你可以写一个简单的“#”作为动作,它很常见——但它有提交时滚动到顶部的副作用。)

Again, I like this approach because it's effortless and self-explaining. No "return false", no jQuery/domReady, no heavy weapons. It just does what it seems to do. Surely other methods work too, but for me, this is The Way Of The Samurai.

同样,我喜欢这种方法,因为它毫不费力且一目了然。没有“返回假”,没有 jQuery/domReady,没有重型武器。它只是做它似乎做的事情。当然其他方法也有效,但对我来说,这就是武士之道。

A note on validation

关于验证的说明

Forms only get submitted if their onsubmitevent handler returns something truthy, so you can easily run some preemptive checks:

表单仅在其onsubmit事件处理程序返回真实内容时才会提交,因此您可以轻松地运行一些抢先检查:

    <form action="/something.php" onsubmit="return isMyFormValid(this)">

Now isMyFormValidwill run first, and if it returns false, server won't even be bothered. Needless to say, you will have to validate on server side too, and that's the more important one. But for quick and convenient early detection this is fine.

现在isMyFormValid将首先运行,如果它返回 false,服务器甚至不会被打扰。不用说,您也必须在服务器端进行验证,这是更重要的。但是为了快速方便的早期检测,这很好。

回答by IAM_AL_X

It has been almost 8 years since the question was asked, but I will venture an answer not previously given. The OP said this doesn't work:

自从提出这个问题以来已经快 8 年了,但我会冒险提供一个以前没有给出的答案。OP说这不起作用:

action="javascript:simpleCart.checkout()"

And the OP said that this code continued to fail despite trying all the good advice he got. So I will venture a guess. The action is calling checkout()as a static method of the simpleCartclass; but maybe checkout()is actually an instancemember, and not static. It depends how he defined checkout().

OP 表示尽管尝试了他得到的所有好建议,但这段代码仍然失败。所以我大胆猜测一下。动作checkout()作为类的静态方法调用simpleCart;但也许checkout()实际上是一个实例成员,而不是static。那要看他怎么定义了checkout()

By the way, simpleCartis presumably a class name, and by convention class names have an initial capital letter, so let's use that convention, here. Let's use the name SimpleCart.

顺便说一下,simpleCart大概是一个类名,按照约定,类名有一个首字母大写,所以让我们在这里使用这个约定。让我们使用名称SimpleCart

Here is some sample code that illustrates defining checkout()as an instance member. This was the correct way to do it, prior to ECMA-6:

下面是一些示例代码,说明如何定义checkout()为实例成员。在 ECMA-6 之前,这是正确的做法:

function SimpleCart() {
    ...
}
SimpleCart.prototype.checkout = function() { ... };

Many people have used a different technique, as illustrated in the following. This was popular, and it worked, but I advocate against it, because instances are supposed to be defined on the prototype, just once, while the following technique defines the member on thisand does so repeatedly, with every instantiation.

许多人使用了不同的技术,如下所示。这很流行,而且有效,但我反对它,因为实例应该在 上定义prototype一次,而以下技术定义成员this并在每次实例化时重复这样做。

function SimpleCart() {
    ...
    this.checkout = function() { ... };
}

And here is an instancedefinition in ECMA-6, using an official class:

这是ECMA-6 中的一个实例定义,使用官方class

class SimpleCart {
    constructor() { ... }
    ...
    checkout()    { ... }
}

Compare to a staticdefinition in ECMA-6. The difference is just one word:

与ECMA-6 中的静态定义进行比较。区别只有一个字:

class SimpleCart {
    constructor() { ... }
    ...
    static checkout()    { ... }
}

And here is a static definition the old way, pre-ECMA-6. Note that the checkout()method is defined outside of the function. It is a member of the functionobject, not the prototypeobject, and that's what makes it static.

这是 ECMA-6 之前的旧方式的静态定义。请注意,该checkout()方法是在函数之外定义的。它是函数对象的成员,而不是原型对象,这就是它静态的原因

function SimpleCart() {
    ...
}
SimpleCart.checkout = function() { ... };

Because of the way it is defined, a static function will have a different concept of what the keyword thisreferences. Note that instancemember functions are called using the thiskeyword:

由于它的定义方式,静态函数将对关键字this引用的内容有不同的概念。请注意,使用关键字调用实例成员函数this

this.checkout();

Staticmember functions are called using the class name:

使用类名调用静态成员函数:

SimpleCart.checkout();

The problem is that the OP wants to put the call into HTML, where it will be in globalscope. He can't use the keyword thisbecause thiswould refer to the global scope (which is window).

问题是 OP 想要将调用放入 HTML,它将在全局范围内。他不能使用关键字,this因为this会引用全局范围(即window)。

action="javascript:this.checkout()" // not as intended
action="javascript:window.checkout()" // same thing

There is no easy way to use an instance member function in HTML. You can do stuff in combination with JavaScript, creating a registry in the static scope of the Class, and then calling a surrogate static method, while passing an argument to that surrogate that gives the index into the registry of your instance, and then having the surrogate call the actual instance member function. Something like this:

在 HTML 中使用实例成员函数没有简单的方法。你可以结合 JavaScript 做一些事情,在类的静态范围内创建一个注册表,然后调用一个代理静态方法,同时将一个参数传递给该代理,该参数将索引提供给您的实例的注册表,然后让代理调用实际的实例成员函数。像这样的东西:

// In Javascript:
SimpleCart.registry[1234] = new SimpleCart();

// In HTML
action="javascript:SimpleCart.checkout(1234);"

// In Javascript
SimpleCart.checkout = function(myIndex) {
    var myThis = SimpleCart.registry[myIndex];
    myThis.checkout();
}

You could also store the index as an attribute on the element.

您还可以将索引存储为元素上的属性。

But usually it is easier to just do nothing in HTML and do everything in JavaScript with .addEventListener()and use the .bind()capability.

但通常更容易在 HTML 中什么都不做,.addEventListener()而在 JavaScript 中使用并使用该.bind()功能。

回答by vfabre

I always include the js files in the head of the html document and them in the action just call the javascript function. Something like this:

我总是将 js 文件包含在 html 文档的头部,并且它们在操作中只调用 javascript 函数。像这样的东西:

action="javascript:checkout()"

You try this?

你试试这个?

Don't forget include the script reference in the html head.

不要忘记在 html 头中包含脚本引用。

I don't know cause of that works in firefox. Regards.

我不知道在 Firefox 中工作的原因。问候。