Tampermonkey script to wait for elements then fill them in

只愿长相守 提交于 2019-12-02 00:24:38

Refer to Choosing and activating the right controls on an AJAX-driven site, and use a utility like waitForKeyElements().

Here's how to wait for elements and chain states (in case it's needed) for the submit click:

// ==UserScript==
// @name     _Wait for elements overkill and on separate pages
// @match    https://checkout.bigcartel.com/*
// @match    *://*.bigcartel.com/product*
// @match    *://*.bigcartel.com/cart*
// @require  http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
// @require  https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant    GM_addStyle
// ==/UserScript==
//- The @grant directive is needed to restore the proper sandbox.

//-- Track form field state, just in case. *Might* be needed for multistage forms...
var glblFlags = {firstFlld: false, lastFlld: false, emailFlld: false};

if (location.hostname === "checkout.bigcartel.com") {
    /*-- Fill first three form fields.
        Use separate WFKE's for multistage.  (Fun overkill for simpler forms.)
    */
    waitForKeyElements ("#buyer_first_name", jNd => {SetValue (jNd, "firstFlld", "John"); }, true);
    waitForKeyElements ("#buyer_last_name",  jNd => {SetValue (jNd, "lastFlld",  "Smith"); }, true);
    waitForKeyElements ("#buyer_email",      jNd => {SetValue (jNd, "emailFlld", "john@doe.com"); }, true);

    //-- Click button for next section
    waitForKeyElements (
        "form[action='/shipping'] button:contains('Next')",
        clickWhenFormIsReady, true
    );
}
else if (location.pathname === "/cart") {
    //-- On "/cart" page click checkout button
    waitForKeyElements ("[name='checkout']", clickNode, true);
}

function clickNode (jNode) {
    var clickEvent  = document.createEvent ('MouseEvents');
    clickEvent.initEvent ('click', true, true);
    jNode[0].dispatchEvent (clickEvent);
}

function SetValue (jNode, flagVarName, newValue) {
    jNode.val (newValue);
    glblFlags[flagVarName] = true;
}

function clickWhenFormIsReady (jNode) {
    //-- Keep waiting if all flags are not true (form not yet filled out):
    for (let prpName in glblFlags) {
        if (glblFlags.hasOwnProperty (prpName) ) {
            if (glblFlags[prpName] === false)
                return true;
        }
    }
    clickNode (jNode);
}

To add additional form fields, you would:

  1. Add a new "filled" property to the glblFlagsobject. For example:

    var glblFlags = {firstFlld: false, lastFlld: false, emailFlld: false, phoneFlld: false};
    
  2. Add a new waitForKeyElements line to the first if section. For example:

        waitForKeyElements ("#buyer_phone", jNd => {SetValue (jNd, "phoneFlld", "800-867-5309"); }, true);
    

    The second parameter to SetValue() is the name of the property you added in step 1.
    The third parameter to SetValue() is the value you wish to fill in the form field with.

  3. Some form controls may require special handling. That's beyond the scope of this question. Search around and then open a new question, if needed.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!