Запретить js alert () приостанавливать таймеры

Поэтому я сделал несколько таймеров для викторины. Дело в том, что я только что понял, когда поставил

javascript: alert("blah");

в адресе всплывающее окно предупреждения пауза мой таймер. Что очень нежелательно в викторине.

Я не думаю, что есть способ остановить такое поведение ... но я все равно спрошу.

Если нет, подскажите, что мне делать?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
5
0
6 713
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Нет, нет никакого способа предотвратить остановку одного потока предупреждением в JavaScript. Возможно, вы можете использовать другой способ уведомления пользователя, например плавающий слой.

На самом деле это так, похоже, это вопрос из двух частей: 1) могу ли я остановить такое поведение? 2) если нет, то что еще делать для отображения уведомлений?

matt b 13.10.2008 21:20

Это модально и останавливает выполнение. Рассмотрим альтернативу, которая не приостанавливает выполнение, как метод лайтбокса.

Ответ принят как подходящий

Видимо рендеринг предпросмотра отличается от выложенного рендеринга. Этот абзац предназначен для того, чтобы следующие две строки отображались как код.

// Preserve native alert() if you need it for something special
window.nativeAlert = window.alert;

window.alert = function(msg) {
    // Do something with msg here. I always write mine to console.info,
    // but then I have rarely found a use for a real modal dialog,
    // and most can be handled by the browser (like window.onbeforeunload).
};

Примечание. Хотя я знаю, что предупреждение по-прежнему доступно с помощью javascript: nativeAlert (); но, по крайней мере, это требует просмотра исходного кода и некоторого понимания JS, а не слепой попытки alert ();

syaz 13.10.2008 20:28

Вы также можете заключить nativeAlert в закрытие, чтобы сделать его закрытым.

eyelidlessness 13.10.2008 20:41

Это хорошо, но правильный ответ - Филини. Всегда предполагайте, что браузер, не находящийся под вашим контролем немедленный, поврежден, сфальсифицирован и т. д. И под «немедленным контролем» я подразумеваю в пределах расстояния Бить палкой.

Anders Eurenius 13.10.2008 21:22

Собственно, согласен. Но я хотел прямо ответить на конкретный вопрос (как переопределить предупреждение).

eyelidlessness 13.10.2008 21:32

Я думаю, что задающий вопрос пытается предотвратить обман. Поскольку пользователь может ввести javascript: alert ("приостановлено"); в адресную строку или сделайте для этого букмарклет, легко приостановить викторину и обмануть.

Единственное, что я могу придумать, - это использовать Date (), чтобы получить текущее время, и снова проверить его, когда сработает таймер. Затем, если разница во времени не достаточно близка к предполагаемой продолжительности таймера, покажите предупреждение и откажитесь от ответа на этот вопрос или позвольте им провалить тест. Невозможно запретить пользователю приостановить ваш тест, но его можно будет поймать.

Конечно, с помощью любой защиты от читеров вы мотивируете людей становиться лучше. Человек может изменить системное время на своем ПК и обмануть конструктор JavaScript Date (), который получает время от операционной системы.

Вы можете использовать интервал для повторного сравнения часов с длиной интервала в одну секунду. Обработчик интервалов также может обновлять поле оставшегося времени на дисплее пользователя. Тогда пользователи могут почувствовать, как нарастает давление, поскольку время на их викторину заканчивается. Веселые времена!

Рад, что вы задали вопрос. Раньше я не думал об использовании предупреждения в качестве кнопки паузы. Также рад, что вы спросили, потому что выбранный ответ - это то, чего я раньше не видел. Теперь я могу обманывать заданные по времени викторины по javascript, создавая себе букмарклет с предупреждением! (Пока они не прочитают эту страницу)

Mnebuerquo 15.10.2008 11:30

Никогда и никогда не полагайтесь на javascript (или любое другое время на стороне клиента) для расчета времени, прошедшего для операций, выполняемых между обратными передачами или разными страницами.

Если вы всегда будете сравнивать даты серверов, людям будет сложно обмануть:

  1. запрос первой страницы, сохранить время сервера
  2. ping с вызовами javascript каждые N секунд, сравните время 2 серверов и верните истекшее время (только для галочки)
  3. когда пользователь отправляет форму, сравните 2 серверных времени, вычислите прошедшее время и отбросьте те, которые заняли слишком много времени (например, возможные мошенники)

Цикл обратной связи по вопросу SyaZ прояснил поставленные вопросы.

Вот попытка обобщить хорошие ответы на данный момент:

  • Клиентскими скриптами по своей природе легко манипулировать, чтобы обмануть онлайн-викторину. СМОТРЕТЬ Серверный подход @Filini

  • window.alert = function (msg) {} переопределит тревога() и, возможно, победит низко висящий результат размещения в адресной строке: javascript: alert («Приостановка страницы, чтобы я мог найти ответ в Google») или я воспользуюсь своим телефоном друга.Предоставлено @eyelidlessness

  • Если вы должны использовать подход на стороне клиента, вместо использования setTimeOut (), вы можете использовать настраиваемую функцию паузы на основе сравнения дат, подобную этой (концепция от @Mnebuerquo, пример кода мой (@micahwittman)):

Пример:

var beginDate = new Date();

function myTimeout(milsecs){
  do { curDate = new Date(); }
    while((curDate-beginDate) < milsecs);
}

function putDownYourPencils(milsecs){
  myTimeout(milsecs);
  var seconds = milsecs / 1000;
  alert('Your '  + seconds + ' seconds are up. Quiz is over.');
}

putDownYourPencils(3000);

В конце концов, вы не можете доверять пользовательскому вводу. Без отслеживания времени, прошедшего на сервере, просто нет гарантии, что данные не были изменены.

Однако, если вы уверены, что ваши тестирующие не разбираются в JavaScript и просто полагаются на «трюк», который они где-то нашли, вы можете проверить на читерство (приостановку) с помощью следующего кода, который не требует изменения window.alert:

var timer = {
    startDatetime: null,
    startSec: 0,
    variance: 1,
    exitOnPause: true,
    count: function (config) {
        var that = this;

        if (typeof config == "object" && typeof parseInt(config.seconds) == "number" && !isNaN(parseInt(config.seconds)))
        {
            if (typeof parseFloat(config.variance) == "number" && !isNaN(parseFloat(config.variance))) this.variance = config.variance;
            if (typeof config.exitOnPause == "boolean") this.exitOnPause = config.exitOnPause;

            if (config.seconds > 0)
            {
                if (!this.startSec) this.startSec = config.seconds;
                if (!this.startDatetime) this.startDatetime = new Date();
                var currentDatetime = new Date();

                if (currentDatetime.getTime() - this.startDatetime.getTime() > (this.startSec - config.seconds) * this.variance * 1000)
                {
                    if (typeof config.onPause == "function") config.onPause();

                    if (!this.exitOnPause)
                    {
                        this.startDatetime = new Date();
                        this.startSec = config.seconds--;
                        window.setTimeout(function () { that.count(config); }, 1000);
                    }
                }
                else
                {
                    config.seconds--;
                    window.setTimeout(function () { that.count(config); }, 1000);
                }
            }
            else
            {
                if (typeof config.onFinish == "function") config.onFinish();
            }
        }
    }
};

Этот объект таймера имеет единственный метод count (), который принимает объект в качестве входных данных. Он ожидает как минимум свойство секунд во входном объекте.

По какой-то причине window.setTimeout не всегда работает должным образом. Иногда на моей машине window.setTimeout (x, 1000), который должен выполнить код через 1 секунду, требовалось более 2 секунд. Итак, в таком случае вы должны разрешить дисперсию, чтобы люди, которые не жульничали, не были помечены как читеры. По умолчанию дисперсия равна 1, но ее можно переопределить во входном объекте. Вот пример того, как использовать этот код, который дает 2,5 секунды "пространства для маневра" для медленных нажатий:

timer.count({
    seconds: 10,
    onPause: function () { alert("You cheated!"); window.location.replace("cheatersAreBad.html"); },
    onFinish: function () { alert("Time's up!"); },
    variance: 2.5
});

С таким решением вы можете использовать Ajax, чтобы сообщить серверному сценарию, что пользователь приостановил таймер, или перенаправить пользователя на страницу, объясняя, например, что он был пойман на мошенничестве. Если по какой-то причине вы хотите разрешить пользователю продолжить тест после того, как его поймали на мошенничестве, вы можете установить для exitOnPause значение false:

timer.count({
    seconds: 10,
    exitOnPause: false,
    onPause: function () { recordCheaterViaAjax(); },
    onFinish: function () { alert("Time's up!"); },
    variance: 2.5
});

Сеанс сервера может истечь, скажем, через 1 час. Javascript можно использовать только как инструмент отображения, чтобы пользователь знал, сколько времени осталось. Если он решит обмануть, приостановив таймер, он может быть удивлен, когда публикует свой тест, что его сеанс истек.

Другие вопросы по теме