Как максимально быстро кликнуть на элемент в браузере?

Привет, хабр. Есть потребность реализовать расширение-кликер для хрома. У меня есть АМО CRM в ней нам падают лиды, далее, кто первый успел взять лид нажатием кнопки "принять" на всплывающем окне, тот и будет с ним работать. У моей коллеги, написан, какой-то софт/расширение, которое кликает на эту кнопку ещё до появления её в визуальной части сайта. Написал такой скрипт:
// Функция для отслеживания появления и нажатия на элемент
function observeAndClickElement() {
    const targetSelector = '.f5-notifier-notification-action_btn';

    // Функция для нажатия на элемент
    function clickElement(element) {
        if (element) {
            // Вызов функции клика
            element.click();
            console.log("Кнопка в уведомлении была нажата");
        }
    }

    // Функция для рекурсивной проверки наличия элемента
    function checkForElement() {
        const notificationButton = document.querySelector(targetSelector);
        clickElement(notificationButton);

        // Запуск следующей проверки
        requestAnimationFrame(checkForElement);
    }

    // Запуск первой проверки
    checkForElement();
}

// Запуск отслеживания и нажатия на элемент
observeAndClickElement();

С таким скриптом, коллега всё равно берёт все заявки, а значит каким-то образом раньше меня получает информацию, о полявлении кнопки. Дсотупа к какой-либо серверной части нет ни у меня, ни у неё.
Как можно оптимизировать/переписать код чтобы стать первым или хотябы забирать часть её заявок, если вдруг потолком будет скорость интернета и другие факторы на которые я не смогу повлиять?
  • Вопрос задан
  • 2354 просмотра
Пригласить эксперта
Ответы на вопрос 8
@Antonosyan
Для таких вещей советую использовать MutationObserver вместо рекурсивной проверки наличия элемента. MutationObserver позволяет отслеживать изменения в DOM-дереве и вызывать функцию обратного вызова при их возникновении. Это может существенно ускорить работу функции, так как она не будет постоянно проверять наличие элемента.

Вот по вашему примеру будет примерно так

function observeAndClickElement() {
  const targetSelector = '.f5-notifier-notification-action_btn';
  const observer = new MutationObserver((mutationsList) => {
    for (let mutation of mutationsList) {
      if (mutation.type === 'childList') {
        const notificationButton = document.querySelector(targetSelector);
        if (notificationButton) {
          notificationButton.click();
          console.log("Кнопка в уведомлении была нажата");
        }
      }
    }
  );


observer.observe(document.body,  childList: true, subtree: true );
observeAndClickElement();


В этой функции мы создаем новый экземпляр MutationObserver и передаем ему функцию обратного вызова. Затем мы запускаем отслеживание изменений в DOM-дереве, указав, что мы хотим отслеживать изменения в дочерних элементах body. Когда происходит изменение, мы проверяем наличие элемента и, если он есть, нажимаем на него.

Такой подход должен работать гораздо быстрее
Ответ написан
Комментировать
kawabanga
@kawabanga
vadimeasy,
КРЫСА она) Это ответ.
Представь, что разница в 70 лидов стоят условные 1К за лид.
За откат в 30-50% она может и начальника обработать и группу разработчиков.

Т.е. на ее аккаунт может заявка сразу уходить, если она проходит по параметрам (Жирная заявка). А вы пытаетесь найти способ вытащить несуществующие лиды из системы. В этом и проблема.

Вы можете даже проверить, если ваш скрипт работает, и в среднем будет у всех 30 лидов, а у вас допустим 45, а у этой коллеги так же 100 - это будет означать как минимум то, что ваш скрипт работает. И дело тут не в скорости скрипта.

Ответ 2
Появление кнопки - это следствие.
Ищите событие, которое его запускает, там либо соединение с сокетом, и вам надо будет внедриться в функцию сокета, либо в ajax проверку. Так вы сможете ускорить получение ответа.
+
Пинг до сервера проверяйте. 20-30мс разницы - уже громадная.
Ответ написан
Попробуй для начала в тупую в бесконечном цикле пытаться находить эту кнопку при помощи
document.querySelector()
document.querySelectorAll()
и нажимать, если нашлась.
Ответ написан
А это точно единственная кнопка с таким классом на всю страницу и других таких не бывает?
Если да, то вот один из самых простых вариантов
setInterval(() => {
    document.querySelector('.f5-notifier-notification-action_btn')?.click()
}, 10)

Если всё же классов таких несколько, то надо либо во все такие кнопки тыкать, либо привязываться по более конкретному пути
Ответ написан
@tltary
Может попробовать без проверки?
Сразу напрямую кликать, элемент появится он кликнет

типо такого
setInterval(() => {
    document.querySelector('knopka')?.click()
}, 100)


Пока браузер не обновишь оно и будет кликать, сделать отдельно маленькое окно, пусть себе висит
Кажется пока ты пытаешься проверить, она в тупую бьет по кнопке
Ответ написан
@rPman
Необходимо реверсинженерингом выявить способ, которым события доходят до клиента.

Для начала открой консоль разработчика (f12) и зайди на вкладку networks
- если там будут периодические события (например с секундным интервалом) по названию (в url или еще как) похожие на получение статуса, то это значит используется медленный метод http get (это значит клиент получает информацию о событии со случайной задержкой порядка этой секунды), значит дальше можно искать в коде способ как чаще делать запросы (обычно это вызов метода по setTimeout его можно тупо повторить из консоли руками).
- если там будет подключение типа websocket, тогда странно, обычно это самый оперативный метод, но бывает что бакэнд писали странные люди (или их поставили в странные условия) и там события обрабатываются линейно что то типа 'sleep;читаем базу;отправляем на клиента' то тогда достаточно открыть одновременно несколько окон браузера к одной и той же страничке, и с некоторыми шансами получишь на каждого клиента по циклу со sleep а значит со своей случайной задержкой (она зависит от интервала между открытиями страниц) а значит какая то страница получит обновление статуса раньше с вероятностью тем выше чем больше страниц.

Я привел пример простых методов, которые потребуют минимальное программирование, но мало ли как там в реальности все сделано, для этого и нужен реверсинженеринг.

По правильному можно разобраться как все работает и на javascript написать максимально эффективное приложение (прямо тут же в консоли браузера) по опросу сервера.
Ответ написан
@smn_fox
В вопросе есть инфа, что коллега "кликает на кнопку" еще до ее пояления, а код завязан на поиске кнопки уже в dom. Может в этом и суть?
Стоит поискать какое нибудь событие, которое запускает на фронте появление попапа, или может через вебсокет сообщение приходит?
Ответ написан
Комментировать
@Leihtman
ui тесты на протоколе devtools типа playwright работают быстрее чем на вебдрайвере, как вариант написать скрипт на playwright.
Но самым быстрым будет, как уже писали, через апи запросы работать: запрашивать список лидов, если чот есть в респонсе - отправлять запросом подтверждение. Тем более, если до появления на фронте она забирать умудряется, вероятно такой способ уместнее
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы