При нажатии на цветные поля на этой странице примера MDN URL показывает координаты клика.
При использовании document.querySelector("input").click() URL показывает координаты x=0&y=0.
Я хочу программно нажать кнопку, используя консоль или пользовательский скрипт, чтобы URL-адрес отображал указанные мной координаты.
Что я пробовал:
document.querySelector("input").dispatchEvent(new MouseEvent("click", {
x: 55, // And also `offsetX` and `clientX`.
y: 55
}));
В документации к MouseEvent отмечается, что они на самом деле не перемещают курсор, и это нормально.
Я попытался поставить над ним <div>, пропуская клик.
const newdiv = document.createElement("div");
newdiv.style.position = "fixed";
newdiv.style.height = "1px";
newdiv.style.width = "1px";
newdiv.style.top = "55px";
newdiv.style.left = "55px";
newdiv.style.pointerEvents = "none";
document.querySelector("div").prepend(newdiv);
newdiv.click();
Это работает для ручных кликов, но .click() ничего не делает (потому что это родственный элемент?).
document.querySelector("input").prepend(newdiv); будет пузыриться, но все еще (0, 0).
Как я могу нажать на координату?
Я уже пробовал ответы на предложенный вопрос Как имитировать щелчок, используя координаты x, y в JavaScript? прежде чем задать этот вопрос (это был один из первых результатов Google, которые я нашел). Этот вопрос не является дубликатом, потому что отмеченный ответ сначала получает элемент, а затем щелкает его:
document.elementFromPoint(x, y).click();
что точно так же, как
document.querySelector("input").click();
Комментарии предполагают, что это невозможно, поскольку это может заставить пользователей нажимать на объявления. Неужели этого нельзя делать?
Другие решения «кликают» по странице/элементу, но не отправляют форму (URL-адрес не меняется, чтобы показать, где была нажата кнопка).
Рассматривали ли вы вместо этого отправку формы с пользовательским URL-адресом?
document.elementFromPoint(x, y).click(); не то же самое, потому что он получает элемент (то есть входное изображение) в любой указанной вами координате, а затем щелкает (он все равно будет показывать 0,0)
@KonradLinkowski Я думал об этом, но не уверен, как указать координаты. document.querySelector("form").submit(); Можете ли вы использовать приведенный выше URL-адрес и консоль, чтобы изменить URL-адрес соответствующим образом?
@ user900901 Я думаю, что вставки двух элементов <input type = "hidden"> с соответствующими атрибутами name должно быть достаточно, например. yourFormElement.append(Object.assign(document.createElement("input"), { type: "hidden", name: "x", value: x }), Object.assign(document.createElement("input"), { type: "hidden", name: "y", value: y })); yourFormElement.submit();.
@SebastianSimon Это работает и меняет URL. Спасибо за комментарий. Я не уверен в этикете SO в этом случае: вы предоставили удовлетворительное для меня решение, но это не обязательно «ответ» на исходный вопрос. Однако, поскольку мой вопрос касался именно изменения координат URL-адреса, щелчок и отправка не являются для меня важным отличием. Я бы отметил это как ответ, если бы вы опубликовали его. В любом случае, примите мою благодарность.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Для этого вы можете использовать MouseEvent и установить его координаты x и y. Я также добавил функцию обнаружения движений мыши, чтобы показать, что она работает.
// detect the mouse movement
document.addEventListener('click', function (event){
console.info(event.clientX, event.clientY)
})
//
function click(x, y, element){
var click = new MouseEvent("click", {
"view": window,
"bubbles": true,
"cancelable": false,
"clientX":x,
"clientY":y
});
element.dispatchEvent(click);
}
click(10, 20, document)Вы пробовали этот код на примере URL? Это Хотя обнаружение кликов в порядке, форма/ввод не отправляются. При этом страница не перезагружается/URL не меняется.
Какой именно код вы ввели в консоль? у меня возникли проблемы с воссозданием проблемы. Для контекста я использую хром и устанавливаю цель на "document.getElementById('image')"
Кажется, Firefox и Chrome по-разному ведут себя (понятно). И поведение консоли отличается от поведения пользовательского скрипта (?). Пользовательский скрипт Firefox щелкнет элемент в точке 0,0 независимо от координат (даже если эти координаты выходят за границы элемента, например, 1000,1000), но отправит. Пользовательский скрипт Chromium будет щелкать элемент в указанных координатах, но 0,0 находится в левом верхнем углу страницы, а не элемент, но он отправляется. Как в Firefox, так и в Chromium при использовании консоли для запуска этого кода координаты отображаются в журнале консоли, но не отправляются (отмечено в моем первом комментарии).
В любом случае, спасибо за ваш ответ и комментарии.
Кажется, что установка координат на <form> при отправке через <input type = "image"> происходит только для событий, инициированных пользователем, а не для синтетических событий.
Однако можно имитировать поведение другими способами.
Когда форма отправляется через <input type = "image">, в запросе есть еще два поля запроса (или поля данных формы), x и y, представляющие координату щелчка.
Но если вход имеет атрибут name, обе координаты имеют префикс значения атрибута name и ..
Мы можем определить функцию для отправки формы с указанными координатами на основе заданного <input type = "image"> и вызвать ее.
Функция в основном должна вставить два элемента <input type = "hidden"> с правильными свойствами name и value.
При отправке формы эти два поля учитываются автоматически.
Вот демонстрация этой функции в действии.
const submitViaImage = (() => {
const insertedElements = new WeakMap();
return (button, x, y) => {
if (button.form){
if (insertedElements.has(button.form)){
Array.from(insertedElements.get(button.form))
.forEach((element) => element.remove());
}
else{
insertedElements.set(button.form, new Set());
}
const prefix = (button.name
? `${button.name}.`
: ""),
hiddenX = Object.assign(document.createElement("input"), {
name: `${prefix}x`,
type: "hidden",
value: x
}),
hiddenY = Object.assign(document.createElement("input"), {
name: `${prefix}y`,
type: "hidden",
value: y
});
insertedElements.get(button.form)
.add(hiddenX)
.add(hiddenY);
button.form.append(hiddenX, hiddenY);
button.form.submit();
}
};
})();
// Here, some event is bound to something that submits the form,
// just demonstrating how to use the function above.
const target = document.querySelector("input[name='last']");
document.getElementById("somethingThatSubmitsTheForm")
.addEventListener("click", () => submitViaImage(target, 40, 60));<form>
<label>Some other data: <input name = "someData" type = "text"></label>
<div>
Submit:
<input name = "first" type = "image" src = "//picsum.photos/100?1">
<input name = "last" type = "image" src = "//picsum.photos/100?2">
</div>
</form>
<input id = "somethingThatSubmitsTheForm" type = "button" value = "Click here to submit the form via the second image at (40, 60).">После нажатия любой из кнопок вы можете проверить iframe фрагмента стека, чтобы убедиться, что его внутренний documentURI действительно установлен на ожидаемый URL-адрес с полями someData, first.x или last.x, first.y или last.y.
К сожалению, форму действительно нужно отправлять напрямую через .submit(); на самом деле невозможно делегировать отправку через button.click(), потому что это попытается перезаписать координаты x и y, что приведет к чему-то вроде ?last.x=0&last.y=0&last.x=40&last.y=60.
Однако button.click() предпочтительнее, если вы ожидаете, что отправка формы будет обрабатываться прослушивателем событий с вызовом preventDefault.
Координаты x и y в этом случае не заданы, но среди прочего он правильно устанавливает submitter из SubmitEvent.
Функция закрывает WeakSet с именем insertedElements.
Это используется для отслеживания элементов, добавленных к любому <form>, чтобы их можно было удалить перед добавлением новых.
В противном случае к <form> добавляется все больше и больше скрытых входных данных, которые будут частью отправленных данных формы, содержащих устаревшие данные.
Вставленные элементы исчезнут после перезагрузки страницы после отправки формы, но теоретически все еще возможно загрузить ответ на отправку в другом месте, поэтому удаление элементов по-прежнему важно.
Это помогает? Как имитировать щелчок, используя координаты x,y в JavaScript?