vorm actie met javascript

Ik heb een formulier dat een javascript-functie moet uitvoeren bij het indienen, de functie plaatst vervolgens gegevens in mijn php-mailbestand voor verzenden en de e-mail wordt verzonden. Maar het werkt alleen in fire fox. De formulieractie lijkt niets te doen in IE, mijn vraag is: Is dit de juiste manier om een functie aan te roepen vanuit een extern bestand vanuit de formulieractie:

action="javascript:simpleCart.checkout()"

simpleCart is het .js-bestand en checkout() is de functie.

Tips gewaardeerd, moeite om te begrijpen waarom het zou werken in Firefox, maar niet in IE, Chrome of Safari.

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

Antwoord 1, autoriteit 100%

Een formulieractie die is ingesteld op een JavaScript-functie wordt niet breed ondersteund, het verbaast me dat het werkt in FireFox.

Het beste is om gewoon actionin te stellen op je PHP-script; als je iets moet doen voordat je het inzendt, kun je gewoon toevoegen aan onsubmit

Bewerkenbleek dat je geen extra functie nodig had, alleen een kleine verandering hier:

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;
}

Vervolgens in uw formulier:

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

Antwoord 2, autoriteit 85%

Absoluut geldig.

   <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 -->

Dus voor een kort antwoord: ja, dit is een optie, en een mooie. Er staat “wanneer ingediend, ga alsjeblieft nergens heen, voer gewoon dit script uit”– heel ter zake.

Een kleine verbetering

Om de gebeurtenishandler te laten weten met welke vorm we te maken hebben, lijkt het een voor de hand liggende manier om het afzenderobject door te geven:

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

Maar in plaats van wat logisch zou zijn, verwijst thisnaar het Window-object. Blijkbaar leven javascript:links in een aparte scope. Daarom raad ik het volgende formaat aan, het is slechts 13 tekens meer en werkt als een tierelier:

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

… nu heb je goed toegang tot het afzenderformulier. (Je kunt een simpele “#” als actie schrijven, het is vrij gebruikelijk – maar het heeft als bijwerking dat je naar boven scrollt bij het indienen.)

Nogmaals, ik hou van deze aanpak omdat het moeiteloos en vanzelfsprekend is. Geen “return false”, geen jQuery/domReady, geen zware wapens. Het doet gewoon wat het lijkt te doen. Natuurlijk werken andere methoden ook, maar voor mij is dit The Way Of The Samurai.

Een opmerking over validatie

Formulieren worden alleen ingediend als hun gebeurtenishandler onsubmitiets naar waarheid retourneert, dus je kunt gemakkelijk wat preventieve controles uitvoeren:

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

Nu wordt isMyFormValidals eerste uitgevoerd, en als het false retourneert, heeft de server er niet eens last van. Onnodig te zeggen dat je ook aan de serverkant moet valideren, en dat is de belangrijkste. Maar voor een snelle en gemakkelijke vroege detectie is dit prima.


Antwoord 3, autoriteit 6%

Het is bijna 8 jaar geleden dat de vraag werd gesteld, maar ik waag me aan een antwoord dat nog niet eerder is gegeven. De OP zei dat dit niet werkt:

action="javascript:simpleCart.checkout()"

En de OP zei dat deze code bleef falen ondanks het proberen van al het goede advies dat hij kreeg. Dus ik waag een gok. De actie roept checkout()aan als een statische methode van de klasse SimpleCart; maar misschien is checkout()eigenlijk een instantielid, en niet statisch. Het hangt ervan af hoe hij checkout()heeft gedefinieerd.

Trouwens, SimpleCartis vermoedelijk een klassenaam, en volgens afspraak hebben klassenamen een beginhoofdletter, dus laten we die conventie hier gebruiken. Laten we de naam SimpleCartgebruiken.

Hier is een voorbeeldcode die het definiëren van checkout()als instantielid illustreert. Dit was de juiste manier om het te doen, vóór ECMA-6:

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

Veel mensen hebben een andere techniek gebruikt, zoals hieronder wordt geïllustreerd. Dit was populair en het werkte, maar ik pleit ertegen, omdat instanties geacht worden slechts één keer te worden gedefinieerd op het prototype, terwijl de volgende techniek het lid op thisen doet dit herhaaldelijk, bij elke instantiatie.

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

En hier is een instantiedefinitie in ECMA-6, met een officiële class:

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

Vergelijk met een statischedefinitie in ECMA-6. Het verschil is slechts één woord:

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

En hier is een statische definitie op de oude manier, pre-ECMA-6. Merk op dat de methode checkout()buiten de functie wordt gedefinieerd. Het is een lid van het functionobject, niet het prototypeobject, en dat maakt het statisch.

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

Vanwege de manier waarop deze is gedefinieerd, zal een statische functie een ander concept hebben van waar het trefwoord thisnaar verwijst. Merk op dat ledenfuncties van instanceworden aangeroepen met het trefwoord this:

this.checkout();

Statischelidfuncties worden aangeroepen met de klassenaam:

SimpleCart.checkout();

Het probleem is dat de OP de aanroep in HTML wil plaatsen, waar het in algemeenbereik zal zijn. Hij kan het trefwoord thisniet gebruiken omdat thiszou verwijzen naar het globale bereik (dat is window).

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

Er is geen gemakkelijke manier om een instantielidfunctie in HTML te gebruiken. U kunt dingen doen in combinatie met JavaScript, een register maken in het statische bereik van de klasse en vervolgens een surrogaat-statische methode aanroepen, terwijl u een argument aan dat surrogaat doorgeeft dat de index in het register van uw instantie geeft, en vervolgens de surrogaat oproep de werkelijke instantie lid functie. Zoiets als dit:

// 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();
}

Je zou de index ook als een attribuut op het element kunnen opslaan.

Maar meestal is het gemakkelijker om gewoon niets in HTML te doen en alles in JavaScript te doen met .addEventListener()en de .bind()-mogelijkheid te gebruiken.


Antwoord 4, autoriteit 2%

Ik neem altijd de js-bestanden op in de kop van het html-document en roep ze in de actie gewoon de javascript-functie aan. Zoiets als dit:

action="javascript:checkout()"

Probeer je dit?

Vergeet niet de scriptreferentie in de html-kop op te nemen.

Ik weet niet waarom dat werkt in Firefox.
Met vriendelijke groet.

Other episodes