Рендеринг Recaptcha V2 Challenge в указанном c контейнере - PullRequest
0 голосов
/ 06 января 2020

Я пытаюсь исправить проблемы с отзывчивым дизайном Recaptcha, и я думаю, что лучшим решением было бы включить вызов Recaptcha в то же самое всплывающее окно (контейнер), где отображается Checkaptcha Checkbox , но я не знаю, как. Он всегда присоединяется как последний тег div к телу.

Страница (.CS HTML):

             <div class="vote-email__field">
                            <div class="vote-email__captcha" data-dc-component="recaptcha" data-dc-recaptcha-options='{"sitekey" : "@Model.RecaptchaSiteKey", "id" : "vote-modal-id"}'>
                            </div>
                            <div class="vote-email__error isDisabled" data-dc-vote-email-ref="errors[]">Error: Please check recaptcha</div>
              </div>

компонент recaptcha (. JS):

import BaseComponent from '../../../general/js/base-component';
import eventBus from '../../../general/js/event-bus';
import onReady from './loadRecaptcha';
import { RECAPCHA_RESET, UPDATE_RECAPCHA_GUID } from './events';

export default class RecaptchaComponent extends BaseComponent {
    constructor(...args) {
        super(...args);
        this.voteButton = document.getElementById("js-vote-button");
        this.recaptchaChallenge = null;

        this.captchaId = null;

        onReady(this.init);

        if (this.voteButton) {
            this.addListener(this.voteButton, "click", () => this.changeChallengeStyleWhenDisplayed(1000));
        }
    }

    changeChallengeStyleWhenDisplayed(timeout) {
        window.setTimeout(() => {
            try {
                if (document.querySelector("body").lastElementChild.lastElementChild.style.zIndex === "2000000000") {
                    //console.log(true)
                    //TODO: if recaptcha challenge container is not last element, it will break                 
                    document.querySelector("body").lastElementChild.lastElementChild.setAttribute("id", "js-recaptcha-challenge")
                    this.recaptchaChallenge = document.getElementById("js-recaptcha-challenge");
                    this.recaptchaChallenge.classList.add("recaptcha__viewport--center");
                    return;
                }
                else {
                    //console.log(false)
                    this.changeChallengeStyleWhenDisplayed(500);
                }
            }
            catch (error) {
                console.error(error);
                this.changeChallengeStyleWhenDisplayed(500);
            }
        }, timeout);
    }

    init = (grecaptcha) => {
        this.grecaptcha = grecaptcha;

        this.captchaId = grecaptcha.render(this.element, {
            sitekey: this.options.sitekey,
            callback: this.successCallback,
            'expired-callback': this.reset
        });

        eventBus.addListener(RECAPCHA_RESET, id => this.onError(id));
    };

    successCallback = (response) => {
        console.log(successCallback);
        eventBus.emit(UPDATE_RECAPCHA_GUID, this.options.id, response);
    };

    onError = (id) => {
        if (this.options.id === id) {
            this.grecaptcha.reset(this.captchaId);
            this.reset();
        }
    };

    reset = () => {
        eventBus.emit(UPDATE_RECAPCHA_GUID, this.options.id, null);
    };
}

Загрузчик рекапчи (. JS):

const callbackName = 'onRecatpchaLoad';

let isLoaded = false;
const onloadQueue = [];

window[callbackName] = () => {
    isLoaded = true;
    onloadQueue.forEach(callback => callback(window.grecaptcha));
};

export default function onReady(callback) {
    if (isLoaded) {
        callback(window.grecaptcha);
    } else {
        onloadQueue.push(callback);
    }
}

function insertScript() {
    const script = document.createElement('script');
    script.async = true;
    script.defer = true;
    script.src = `https://www.google.com/recaptcha/api.js?onload=${callbackName}&render=explicit`;
    const s = document.getElementsByTagName('script')[0];

    s.parentNode.insertBefore(script, s);
}

insertScript();
...