模拟键盘输入/向文本框插入字符串(AdWords)。

8
我正在尝试使用CefSharp(43版本)从https://adwords.google.com/ko/KeywordPlanner/Home中爬取关键词。
我能够通过编程方式登录广告门户网站。
然而,每当我尝试通过将element.valueelement.innerTextelement.innerHtml分配给所需的字符串来将一些文本(搜索关键字)插入到特定的文本区域(id="gwt-debug-keywords-text-area")时,什么也不会发生。
var txtElem = document.getElementById("gwt-debug-keywords-text-area");
txtElem.addEventListener("keydown", onKeyPress, false);

function onKeyPress(e) {
    alert(e.keyCode);
}

function triggerKeyboardEvent(el, keyCode) {
    var evt = document.createEventObject ?
        document.createEventObject() : document.createEvent("Events");

    if (evt.initEvent) {
        evt.initEvent("keydown", true, true);
    }

    evt.keyCode = keyCode;
    evt.which = keyCode;

    el.dispatchEvent ? el.dispatchEvent(evt) : el.fireEvent("onkeydown", evt);
}

triggerKeyboardEvent(txtElem, "s".charCodeAt(0));

在上面的代码中,虽然弹出了警报消息,但文本框仍然为空。
显然,该文本区域上的键盘按键事件被谷歌自己庞大的JS代码截获。不幸的是,谷歌的源代码高度混淆,对于像我这样的JS新手来说,很难进行调试和跟踪逻辑。
我该如何向文本区域插入/模拟键盘输入?
我尝试过的其他一些代码(还可以查看注释部分):
var txtElem = document.getElementById("gwt-debug-keywords-text-area");
txtElem.focus();

function simulateKeyEvent(character) {
    var e = new KeyboardEvent("keydown", { bubbles: true, cancelable: true, key: character.charCodeAt(0), char: character, shiftKey: false });
    //var e = new KeyboardEvent("keydown", { bubbles: true, cancelable: true, key: "a".charCodeAt(0), char: "a", shiftKey: true });
    return !document.getElementById("gwt-debug-keywords-text-area").dispatchEvent(e);

    var evt = document.createEvent("KeyboardEvent");
    /*
    if (e.initKeyboardEvent) {  // Chrome, IE
        e.initKeyboardEvent("keydown", true, true, document.defaultView, "Enter", 0, "", false, "");
    } else { // FF
        e.initKeyEvent("keydown", true, true, document.defaultView, false, false, false, false, character.charCodeAt(0), 0);
    }
    */
    //(evt.initKeyEvent || evt.initKeyboardEvent)('keypress', true, true, document.defaultView, 0, 0, 0, 0, 0, character.charCodeAt(0));
    evt.initKeyboardEvent("keypress", true, true, document.defaultView, 0, 0, 0, 0, 0, character.charCodeAt(0));
    return !document.getElementById("gwt-debug-keywords-text-area").dispatchEvent(evt);
}

simulateKeyEvent("s");

这些方法都无效....

3个回答

19

好的,我找到了解决方法:

function setKeywordText(text) {
    var el = document.getElementById("gwt-debug-keywords-text-area");
    el.value = text;
    var evt = document.createEvent("Events");
    evt.initEvent("change", true, true);
    el.dispatchEvent(evt);
}

setKeywordText("test");

这个有效,它可以通知页面上的JS框架发生了变化。 - Pavel Maximov

15

@masroore编写的代码运行良好,今天帮了我很大忙。但是后来我发现 这个方法已经被弃用并且在逐渐淘汰中。

使用新方法更新了代码,它可以达到同样的效果:

function setKeywordText(text) 
{
    var el = document.getElementById("gwt-debug-keywords-text-area");
    el.value = text;
    var evt= new Event('change');
    el.dispatchEvent(evt);
}

8

感谢@kentcdodds

你需要使用Textarea的valueSetter。

    const textarea = document.getElementsByTagName('textarea')[0]
    function setNativeValue(element, value) {
      const { set: valueSetter } = Object.getOwnPropertyDescriptor(element, 'value') || {}
      const prototype = Object.getPrototypeOf(element)
      const { set: prototypeValueSetter } = Object.getOwnPropertyDescriptor(prototype, 'value') || {}

      if (prototypeValueSetter && valueSetter !== prototypeValueSetter) {
        prototypeValueSetter.call(element, value)
      } else if (valueSetter) {
        valueSetter.call(element, value)
      } else {
        throw new Error('The given element does not have a value setter')
      }
    }
    setNativeValue(textarea, 'some text')
    textarea.dispatchEvent(new Event('input', { bubbles: true }))

setNativeValue 函数用于设置 DOM 元素(例如 textarea)的值。它通过使用元素或其原型的 "value" 属性 setter 来实现此操作。如果找不到 setter,则会抛出错误。


1
谢谢!对我来说,关键是"new Event('input', { bubbles: true })"。 - GerritElbrink
同样!("new Event('input', { bubbles: true })") - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接