当Recaptcha显示拼图而不是复选框时,我正在尝试调整容器div的大小。这通常在单击复选框后发生。我怎么能这样做?
我知道某些条件会迫使Recaptcha V2显示拼图而不是复选框。然而,Api不会返回表明此更改已发生的属性或事件。有没有办法在JavaScript或通过API,我可以识别Recaptcha V2是否显示拼图?
注意 :如果我在API网址中未指定fallback = true,则会出现这种情况。
答案 0 :(得分:1)
很遗憾,Google没有API事件来跟踪此事件,但是我们可以使用Mutation Observer Web API来通过Google API自行跟踪DOM更改。 浏览器很好地支持它:
首先,我们需要创建一个目标元素,以观察Google iframe的外观。我们将以document.body为目标,因为iframe将被附加到它:
const targetElement = document.body;
然后,我们需要为MutationObserver创建一个配置对象。在这里,我们可以指定在DOM更改中将要跟踪的内容。请注意,默认情况下所有值均为'false',因此我们只能保留'childList'-这意味着我们将仅观察目标元素-document.body的子节点更改:
const observerConfig = {
childList: true,
attributes: false,
attributeOldValue: false,
characterData: false,
characterDataOldValue: false,
subtree: false
};
然后,我们需要创建一个函数,当观察者检测到我们在config对象中指定的特定类型的DOM更改时将调用该函数。第一个参数表示Mutation Observer个对象的数组
function DOMChangeCallbackFunction(mutationRecords) {
mutationRecords.forEach((mutationRecord) => {
if (mutationRecord.addedNodes.length) { //check only when notes were added to DOM
var reCaptchaParentContainer = mutationRecord.addedNodes[0];
var reCaptchaIframe = reCaptchaParentContainer.querySelectorAll('iframe[title="recaptcha challenge"]');
if (reCaptchaIframe.length) { // Google reCaptcha iframe was loaded
console.log('Yay!');
reCaptchaObserver.disconnect(); // We don't want to observe more DOM changes for better performance
// Challenge was loaded -- DO SOMETHING HERE
}
}
});
}
就差不多了。剩下的唯一事情-实例化观察者本身并开始观察DOM变化:
const reCaptchaObserver = new MutationObserver(DOMChangeCallbackFunction);
reCaptchaObserver.observe(targetElement, observerConfig);
我希望能对您有所帮助:)
答案 1 :(得分:0)
以下是使用setInterval
执行此操作的方法。如果用户从未选中该框,则可能会终止浏览器。您可能希望延迟运行它,直到它们开始填写表单或等到它们鼠标悬停/聚焦在reCaptcha元素上。您可能还需要一个更具体的选择器(通过将您的recaptcha包装在div中),如果您有其他可以在代码中使用相同标题的iframe。如评论中所述,使用mutationObserver是一个更好的主意。
希望这能满足您的需求。
function isPuzzleDisplayed (selector) {
/**
* @param {string} selector
* @returns boolean - if the specified element exists
*/
return document.querySelectorAll(selector).length >= 1;
}
var timer = setInterval(function () {
/**
* Check if element exists every 0 seconds.
* If it does, kill timer, else keep running forever!
* WARNING! This is not performant.
*/
if (isPuzzleDisplayed('iframe[title*="recaptcha challenge"]')) {
console.log('But this is how you do it!');
/* run your code here */
clearInterval(timer);
timer = 0;
} else {
console.log('It is true the Api however does not return a property or event that would indicate that this change has happened. >', timer);
}
}, 0);