问题
The following problems:
- I need to simulate a double-click on a div element.
- I need to use/handle MS Internet Explorer 11.
- I cannot change the source code of the target site.
My solution so far:
- I use C# and SHDocVw.InternetExplorer and mshtml
- I can fire "click" events al right, they show up in all handlers
- When trying to simulate the double-click:
-
- the "ondoubleclick" event gets triggered.
-
- the
el.addEventListener('dblclick', handler);
does NOT get triggered
- the
To reduce the complexity of the actual problem site, I have created this HTML code that simulates the problem, too:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>csi dbclick event handler</title>
</head>
<body>
<br>
<br>
<br>
<br>
<br>
<br>
<div
id="baba"
style="position: absolute; left: 80px; width: 100px; border: 2px solid green;"
onclick="console.log('onclick');"
ondblclick="console.log('ondblclick');"
>
GOODBYE!
</div>
</body>
<script>
function printEvent(pEvent1, pEvent2, pEvent3) {
console.log("New Event: " + pEvent1);
console.log(pEvent1);
console.log("Timestamp: " + pEvent1.timeStamp);
}
const el = document.getElementById('baba');
el.addEventListener('click', printEvent);
el.addEventListener('dblclick', printEvent);
</script>
</html>
My C# code is such:
InternetExplorer ie = new InternetExplorer();
HTMLDocument doc = (HTMLDocument) ie.Document;
IHTMLElement el = doc.getElementById("baba");
el.click();
Thread.Sleep(130);
el.click();
Thread.Sleep(5);
IHTMLEventObj eo3 = new MyEvent(el, "dblclick"); // class that extends IHTMLObject, returns values like a mouse click I logged from IE11 earlier, only type is adjusted
IHTMLElement3 el3 = (IHTMLElement3)el;
el3.FireEvent("ondblclick", eo3);
and my event class (which may not be needed at all):
class MyEvent : IHTMLEventObj {
private readonly IHTMLElement mElement;
private readonly String mType;
public MyEvent(IHTMLElement pElement, String pType) {
mElement = pElement;
mType = pType;
}
bool IHTMLEventObj.altKey { get { return false; } }
int IHTMLEventObj.button { get { return 0; } }
bool IHTMLEventObj.cancelBubble { get { return false; } set { } }
int IHTMLEventObj.clientX { get { return 85; } }
int IHTMLEventObj.clientY { get { return 130; } }
bool IHTMLEventObj.ctrlKey { get { return false; } }
IHTMLElement IHTMLEventObj.fromElement { get { return null; } }
int IHTMLEventObj.keyCode { get { return 0; } set { } }
int IHTMLEventObj.offsetX { get { return 3; } }
int IHTMLEventObj.offsetY { get { return 7; } }
string IHTMLEventObj.qualifier { get { return "baba"; } }
int IHTMLEventObj.reason { get { return 0; } }
object IHTMLEventObj.returnValue { get { return null; } set { } }
int IHTMLEventObj.screenX { get { return 353; } }
int IHTMLEventObj.screenY { get { return 305; } }
bool IHTMLEventObj.shiftKey { get { return false; } }
IHTMLElement IHTMLEventObj.srcElement { get { return mElement; } }
object IHTMLEventObj.srcFilter { get { return mElement; } }
IHTMLElement IHTMLEventObj.toElement { get { return mElement; } }
string IHTMLEventObj.type { get { return mType; } }
int IHTMLEventObj.x { get { return 85; } }
int IHTMLEventObj.y { get { return 127; } }
}
When running the code, I get these results:
onclick
New Event: [object PointerEvent]
[object PointerEvent]
{
[functions]: ,
__proto__: { },
altKey: false,
AT_TARGET: 2,
bubbles: true,
BUBBLING_PHASE: 3,
button: 0,
buttons: 0,
cancelable: true,
cancelBubble: false,
CAPTURING_PHASE: 1,
clientX: -396.3999938964844,
clientY: -146.84999084472656,
constructor: { },
ctrlKey: false,
currentTarget: { },
defaultPrevented: false,
detail: 0,
deviceSessionId: 0,
eventPhase: 2,
fromElement: null,
height: 0,
hwTimestamp: 0,
isPrimary: false,
isTrusted: true,
layerX: -396.3999938964844,
layerY: -146.84999084472656,
metaKey: false,
offsetX: -478.3999938964844,
offsetY: -267.25,
pageX: -396.3999938964844,
pageY: -146.84999084472656,
pointerId: 0,
pointerType: "",
pressure: 0,
relatedTarget: null,
rotation: 0,
screenX: 0,
screenY: 0,
shiftKey: false,
srcElement: { },
target: { },
tiltX: 0,
tiltY: 0,
timeStamp: 1612115536885,
toElement: null,
type: "click",
view: { },
which: 1,
width: 0,
x: -396.3999938964844,
y: -146.84999084472656
}
Timestamp: 1612115536885
onclick
New Event: [object PointerEvent]
[object PointerEvent]
{
[functions]: ,
__proto__: { },
altKey: false,
AT_TARGET: 2,
bubbles: true,
BUBBLING_PHASE: 3,
button: 0,
buttons: 0,
cancelable: true,
cancelBubble: false,
CAPTURING_PHASE: 1,
clientX: -396.3999938964844,
clientY: -146.84999084472656,
constructor: { },
ctrlKey: false,
currentTarget: { },
defaultPrevented: false,
detail: 0,
deviceSessionId: 0,
eventPhase: 2,
fromElement: null,
height: 0,
hwTimestamp: 0,
isPrimary: false,
isTrusted: true,
layerX: -396.3999938964844,
layerY: -146.84999084472656,
metaKey: false,
offsetX: -478.3999938964844,
offsetY: -267.25,
pageX: -396.3999938964844,
pageY: -146.84999084472656,
pointerId: 0,
pointerType: "",
pressure: 0,
relatedTarget: null,
rotation: 0,
screenX: 0,
screenY: 0,
shiftKey: false,
srcElement: { },
target: { },
tiltX: 0,
tiltY: 0,
timeStamp: 1612115537021,
toElement: null,
type: "click",
view: { },
which: 1,
width: 0,
x: -396.3999938964844,
y: -146.84999084472656
}
Timestamp: 1612115537021
ondblclick
As you see, the click events all arrive (onclick, click, onclick, click, ondblclick)
, but the addEventListener('dblclick', ...)
does not.
Should be (onclick, click, onclick, click, ondblclick, dblclick)
in the end.
Any ideas how I can accomplish this?
My other solution would be to hijack the mouse and simulate a 'real' click-click, but that's too hackish for my taste.
回答1:
I'm not familiar with SHDocVw.InternetExplorer, but is it possible use something like this? According to this post
How do I double-click on objects using javascript? Do I have to .click() twice?
Sorry when my answer is off topic.
void setupDblClick(HTMLDocument doc)
{
string setupScriptJs = "window.baba_dblclick = function(){" +
"var targLink = document.getElementById ('baba');" +
"var clickEvent = document.createEvent ('MouseEvents');" +
"clickEvent.initEvent ('dblclick', true, true);" +
"targLink.dispatchEvent (clickEvent);}";
doc.parentWindow.execScript(setupScriptJs);
}
void dblClick(HTMLDocument doc)
{
string dblclickScriptJs = "window.baba_dblclick()";
doc.parentWindow.execScript(dblclickScriptJs);
}
来源:https://stackoverflow.com/questions/65982477/how-to-make-shdocvw-internetexplorer-fire-events-that-get-caught-with-js-addeven