Discussions » Développement

Click from JS does not work on my script

§
Posté le: 2020-10-16

Hi everybody,
I was trying to create a very simple script to allow maps zooming on Here.com with the + and - keys of the numpad.
My idea was to create an event listener for the + and - keys, and when they are clicked, the click() function (or an event dispatcher) should "click" on the corresponding button as if the user was clicking on it using the mouse and not the keyboard.
Here is the code:

// ==UserScript==
// @name (Not working) HERE Maps zoom with numpad
// @version 1
// @grant none
// @match https://wego.here.com/?map=*
// ==/UserScript==
document.addEventListener('keydown',zoom);
var zoomOut=document.getElementsByClassName('map_control_zoom_out')[0];
var zoomIn=document.getElementsByClassName('map_control_zoom_in')[0];
function zoom(e){
if(e.code=='NumpadSubtract'){
console.log(e.code);
zoomOut.click();
}
else if(e.code=='NumpadAdd'){
console.log(e.code);
zoomIn.click();
}
}

By the way, the keyboard key is registered, but the map doesn't zoom, as if the click event was not fired. Do you have any idea of why does this happen? I also tried the eventDispatcher method, but the results are the same.

§
Posté le: 2020-10-19
Édité le: 2020-10-19

This command doesn't work at all document.getElementsByClassName('map_control_zoom_out')[0].click() that's why your script didn't work. The first thing you need to do is to figure out what js commands can zoom in/out.

I also tried to see their event listeners and changing the html of the zoom in/out button, but I'm not sure why click() doesn't work, neither what can simulate something similar to click().

I noticed that the url is always modified when I clicked on zoom in or on zoom out, perhaps you could make the keyboard symbols + - change the url and reload the website when they are pressed...

What happens when the user clicks on zoom in/out is that the website sends an xhr request to an website like www.api.amplSOMETHING... I copied the fetch of that and pasted into the browser console to see if the zoom in/out action would/could be simulated that way, but I didn't have success, perhaps because something like an timestamp is sent in that request, so the request can't be "reused".

I think that you can try to simulate that xhr request and see if that will/can simulate the js command click(), (I tried to replay tat xhr request but that didn't work). Maybe you will need to figure out all of the parameters that will need to be added and sent in that xhr request. Or maybe you will be luck and find the API documentation for the website www.api.amplSOMETHING

You could also try to do something like, making a js script that will copy all the node event listeners of the zoom in/out button, then you can hide that somewhere and make the + - keyboard symbols click() the button that you created. I mean, just make a full copy of the zoom in/out button, hide that copy button you made, and try to see if that button can be clicked with click()

§
Posté le: 2020-10-24

Thank you for your suggestions! Recreating the whole request is not an option for me, it would take way more time than this script deserves.
Copying the event listeners from another element is possible? I thougth that when you clone an element, the event listeners get lost and this is sometimes used on purpose to get rid of unwanted listeners. Is there a way to add existing listeners to another element, even if they are not assigned to a public variable?
By the way, I'm still puzzled about the reason why click() does not work.

§
Posté le: 2020-10-24
Édité le: 2020-10-24

You are welcome!

It's not possible unless you know what function is being called and then call it yourself. A trick here is to trigger the event yourself. Let's say you want to do a click event:

const ElemThatHasListener = document.querySelector("CSS of Elem with listener");
const ElemWithoutListener = document.querySelector("CSS of Elem without listener");

ElemWithoutListener.addEventListener("click", e => {
ElemThatHasListener.click();
});

Yeah, this depends on what js command you use to clone, you can do something like innerHTML to get rid of all the advent listeners, or use another command that I forgot now, but there are "3 advent listener copying levels" that you can choose from cloning, perhaps I'm talking about the nodeclone command? I'm not sure haha. Yes, sometimes that's done on purpose, sometimes not.

I'm also still puzzled about the reason why click() does not work, but I think that it's because the button doesn't "do anything", it "gathers" all the needed info to do the xhr request, and the xhr request does everything, "not the button" I guess...

Poster une réponse

Connectez-vous pour poster une réponse.