简体   繁体   中英

Why do my other class functions and variables become undefined after a jQuery click event triggers one of my es6 class functions

I am running an es6 class function to redesign my authentication page. When the user clicks on the "register now" link, the showRegisterSection function is supposed to run so that it switches from the login section to the register section of the auth page. However, the problem is that when I try to access local variables that were initialized in the constructor function and the other functions of the class to perform some redesigning tasks, the browser console returns:

"functionName is not a function"

for functions and

"undefined"

value for variables.

I have tried different functions and searched for solutions online but to no avail. Furthermore, if I copy the code inside the function and paste them into my event handler, showRegisterSection , or re-assign the variables within the event handler, everything works as intended.

Bear in mind that the first function that designs the login section called, ShowLoginSection works just fine and isn't called from an event. It is also the function where the click event that calls showRegisterFunction is setup.

The code is provided below:

    removeElement,
    insert_custom_social_login_before_target_Element
 } from './util';

export default class GulaitAuth{
    //if the isLogin variable is true, then we set up the login part else, we set up the register part
    constructor(isLoginSection, loginForm){
        this._isLoginSection = isLoginSection;
        this._loginForm = loginForm;
        this.initLocalVars();
    }

    /**
     * This function initializes local variables to their supposed values
     * except those passed in on creation of class obj.
     * This is due to an unknown issue where variables simply get reset  to undefined
     */
    initLocalVars(){
        this._loginDiv = document.querySelector('.woocommerce #customer_login').firstElementChild;
        this._registerDiv = document.querySelector('.woocommerce #customer_login').lastElementChild;
        this._myAccHeader = document.querySelector( '.woocommerce-account #main #contents header h2' );
        this._socialLoginContainer = document.querySelector( '#customer_login .apsl-login-networks.theme-2.clearfix' );
        this._authPageLoginForm = document.querySelector( '.woocommerce-page #customer_login form.login' );
    }

    setupAuthPage(){
        //setup the authentication page
        //css styles for Auth page if the loginForm exists on the page
        if( this._loginForm ){
            //remove header "MY ACCOUNT" from DOM
            removeElement(this._myAccHeader);

            //center the auth div
            jQuery('body.page-id-29 .container .row.sidebar-row').css('text-align', 'center');

            //style the Auth div - container
            jQuery('.woocommerce-account #contents').css({
                'max-width' : '38.5em',
                'display': 'inline-block',
                'text-align': 'initial',
                'padding': '1.5em',
                'border-top' : '.15em solid #DF1F26e5'
            });

            if( this._isLoginSection ){
                this.showLoginSection();
            } else {
                this.showRegisterSection();
            }

        }
    }

    /**
     * Show Login or Register Section based on _isLoginSection variable
     */
    showLoginOrRegister(){
        if(this._isLoginSection){
            //edit the login div
            jQuery(this._loginDiv).css( {'min-width' : '100%', 'padding' : '0', 'display' : 'block'} );

            //hide the register div
            jQuery(this._registerDiv).css( 'display', 'none' );
        } else {
            //hide the login div
            jQuery(this._loginDiv).css( 'display', 'none' );

            //edit the register div
            jQuery(this._registerDiv).css( {'min-width' : '100%', 'padding' : '0', 'display' : 'block'} );
        }

    }

    showLoginSection(){
        //show loginsection
        this.showLoginOrRegister();

        //remove full width on checkbox
        jQuery('.woocommerce #customer_login form.login input[type="checkbox"]').css('min-width', '0 !important');

        //remove extra spacing to the right
        jQuery('.woocommerce-account #main #contents .type-page').css('padding', '0');

        //row containing login and register forms is slightly pushed to the left with margin
        //this makes styling difficult as it has wierd positioning
        jQuery('div#customer_login.row').css('margin', '0');

        //remove extra space after the 'lost password?' section
        jQuery('.entry .entry-content .entry-summary').css('margin-bottom', '0');

        //remove login form margin
        jQuery('.woocommerce-page #customer_login form.login').css('margin', '0');

        //edit the login text
        jQuery('.woocommerce #customer_login h2')
        .css( { 
            'border-bottom' : '0',
            'margin-bottom' : '0',
            'padding-bottom' : '0.2em'
        } )
        .text('')
        .append(
            '<span id="login-text">Login</span><span id="or-text"> Or </span><span id="register-text">Register</span>'
        );

        jQuery('#or-text, #register-text').css( {
            'opacity' : '.2',
            'font-size' : '16px',
            'word-spacing' : '.12em',
            'font-weight' : '450'
        } );


        //Insert REGISTRATION Link after 'lost password' section
        jQuery("<p style='margin-top: 2em;'>Don't have an account? <strong id='register-link'><a href='#'>Register now</a></strong></p>")
        .insertAfter("#customer_login .login p.lost_password")
        .children("#register-link").click( this.showRegisterSection );

        //add an eventListener on the register link
        //jQuery('#register-link');

        //redesign the input form input fields
        jQuery('#customer_login .login .form-row.form-row-wide input').css( {
            'border' : '1px solid #ccc',
            'background' : 'white'
        } );

        //fb color = #1c74bc

        //Delete original social login and replace with custom version in the 
        //prefered position
        this.relocateSocialLogin();
    }

    showRegisterSection(){
        console.log('Register Link clicked');

        //set isLogin to false in order to show content as designed for the register form
        this._isLoginSection = false;

        //This function initializes local variables to their supposed values except
        //those passed in on creation of class obj. 
        //This is due to an unknown issue where variables simply get reset to undefined
        this.initLocalVars();

        //show register section
        //hide the login div
        jQuery(this._loginDiv).css( 'display', 'none' );

        //edit the register div
        jQuery(this._registerDiv).css( {'min-width' : '100%', 'padding' : '0', 'display' : 'block'} );
    }

    /**
     * Delete original social login and replace with custom version in the 
     * prefered position to fit design
     */
    relocateSocialLogin(){
        //Delete existing social login
        this._socialLoginContainer.parentNode.removeChild( this._socialLoginContainer );

        //Insert custom social login just before login form on auth page = my-account page
        insert_custom_social_login_before_target_Element( this._authPageLoginForm );

    }

}

You have to keep the this reference in the click handler defined inside showLoginSection()

As written: .children("#register-link").click( showRegisterSection );

Either use an arrow function: .children("#register-link").click( e => this.showRegisterSection(e)); Then the this reference of whatever this is inside showLoginSection() will be retained. ( our auth instance )

The alternatives are variations of .bind() So either .children("#register-link").click( this.showRegisterSection.bind(this)); inside showLoginSection()

Or this.showRegisterSection = this.showRegisterSection.bind(this); inside constructor(isLoginSection, loginForm){ .

You'll have to do this for all the functions that will be used as event handlers, or other situations where the function is not called as a method of GulaitAuth class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM