JavaScript: переопределение оповещения ()

207

У кого-нибудь есть опыт переопределения alert()функции в JavaScript?

  • Какие браузеры поддерживают это?
  • Какие версии браузера поддерживают это?
  • Какие опасности в переопределении функции?
cllpse
источник
Разве это не бесконечный цикл?
Бассейн
1
@ Ник - нет, это не так. «Нормальная» функция window.alert будет назначена для window._alert. > После этого функция window.alert переопределяется.
Крис Кричит
@roosteronacid: Ваш код был семантически и синтаксически прекрасным, хотя и надуманным, как указывал @ paper1337 ... нет шансов на рекурсию, лол ... по сути, вы просто поменяли тела функций с _alertпомощью своего рода в расширенном порядке в первой инстанции.
non sequitor
Айя. Я сделал тебе откат, чтобы не затенять вопрос :)
cllpse

Ответы:

210

Это определенно "поддерживается". Это ваша веб-страница, вы делаете с ней все, что хотите.

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

Используйте шаблон прокси:

(function(proxied) {
  window.alert = function() {
    // do something here
    return proxied.apply(this, arguments);
  };
})(window.alert);

Вы также можете обойти вызов исходной функции, если хотите (прокси)

Более подробная информация здесь: JQuery Types # Proxy Pattern

Майк Глисон младший кутюрье
источник
+1 на шаблоне прокси, чтобы по- настоящему переопределить функцию и гарантировать, что он не будет подделан!
Джош Стодола
15
Тьфу! apply()недоступно window.alertв Internet Explorer 8.
cllpse
Мне жаль слышать, что .. applyэто метод Functionобъекта. Таким образом, они должны явно ограничить это для alert?!
Майк Глисон младший Кутюрье
4
Должно быть, они изменили его, используя прокси-шаблон: D
Джош Стодола
Старые браузеры не поддерживают это и выдают исключение для "window.alert ="
Крис Питчманн
23

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

Так как окно оповещения по умолчанию блокирует поток выполнения, некоторые библиотеки, которые полагаются на это поведение, могут больше не работать (в лучшем случае).

Вы должны быть хорошим гражданином и избегать прикосновения к нативному API. Если вы это сделаете, вы можете разбить вещи, используя сторонний код.

Тем не менее, если вы хотите переопределить поведение оповещения в определенном контексте, вы можете заключить его в анонимную функцию, например:

/* new funky alert */
function myFunkyAlert(msg) { 
    /* here goes your funky alert implementation */
    alert("Look ma!\n" + msg);
}

(function(alert) { // anonymous function redefining the "alert"

    /* sample code */
    alert("Hello World!");

})(myFunkyAlert);
Пабло Кабрера
источник
15

В функции оповещения Overring нет опасностей. Каждый браузер поддерживает это.

например:

// function over riding. Redirecting to Console with Firebug installed.
function alert(message) { 
    console.info(message);
} 

alert('This is an override.');
user160820
источник
11
Там может быть опасность, если ваша замена неблокирует. Например, код, который вызывает, alert("Reloading")а затем перезагружает веб-страницу. Пользователь может никогда не увидеть текст предупреждения.
Дариен
13

Я думаю, что каждая реализация Javascript будет поддерживать это, и нет никакой опасности, связанной с этим. Обычно это делается для того, чтобы заменить обычные блоки предупреждений в стиле ОС на что-то более элегантное с HTML / CSS. Выполнение этого означает, что вам не нужно менять существующий код! Тот факт, что это возможно, делает Javascript потрясающим.

Джош Стодола
источник
12

Как сказано во многих других ответах, вы можете просто переопределить функцию с помощью

window.alert = null

или

window.alert = function(){}

однако, это не обязательно переопределяет функцию в прототипе Windowконструктора (обратите внимание на заглавную W), поэтому хакер все еще может набрать:

Window.prototype.alert.apply(window, ["You were hacked!"]);

поэтому вам также нужно переопределить эту функцию с помощью:

Window.prototype.alert = null

или

Window.prototype.alert = function(){}
разъем
источник
Это не обязательно отменяет функцию в других кадрах. см. jsfiddle.net/18znqbjd/1
Роберт
Роберт: Да и по уважительным причинам. Разные фреймы - это в основном разные HTML-документы, каждый со своим «экземпляром» Javascript.
Рольф
Вы уверены, что Window.prototype.alert все еще функционирует в 2017 году? : P
iplus26
6

Ладислав.
Для IE8 вы можете переопределить alert () следующим образом

/** 
 * Definition of global attached to window properties <br/>
 */ 
    (function() {
      nalert = window.alert;
      Type = {
          native: 'native',
          custom: 'custom'
      };
    })();

/**
 * Factory method for calling alert(). 
 * It will be call a native alert() or a custom redefined alert() by a Type param.
 * This defeinition need for IE
 */ 
    (function(proxy) {

          proxy.alert = function () {
          var message = (!arguments[0]) ? 'null': arguments[0];
          var type = (!arguments[1]) ? '': arguments[1];

          if(type && type == 'native') {
           nalert(message);
          }
          else {
               document.write('<h1>I am redefiend alert()<br/>Alert say: '+message+'</h1>');
          }     
      };
   })(this);

и позвонить как

alert('Hello, hacker!');
nalert('I am native alert');
alert('Hello, user!', Type.custom);
Виталий Р.
источник
4

Мой опыт работы с переопределенной функцией alert () заключается в том, что мы однажды использовали ее для «взлома» пробной версии библиотеки JavaScript с надписью «Пожалуйста, зарегистрируйтесь!» время от времени на экране.

Мы только что определили нашу собственную функцию alert () и вуаля.

Это было только для целей тестирования, мы купили полную версию позже, так что ничего аморального здесь не происходит ;-)

Йозеф Сабл
источник
3

Все реализации JavaScript в современных браузерах поддерживают переопределение.

Опасности заключаются в том, что вы просто сводите с ума других членов команды, переопределяя общеизвестные функции, такие как alert ().

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

Кристофер Токарь
источник
2

Это точно работает в Firefox и ie8. Я не вижу, чтобы был какой-либо браузер, в котором бы он не работал. Это в значительной степени основополагающий принцип работы javascript, хотя его часто не используют с такими встроенными функциями =)

Дэвид Хедлунд
источник
1
Браузер, предназначенный для конкретной цели, будет IE6, другие, вероятно, будут в порядке с ним.
AnthonyWJones
1

Быстрый взлом, который я делаю, чтобы найти, откуда приходят оповещения, - перейти в консоль, а затем ввести эту

function alert(message) { 
  console.info(message);
  debugger;
} 
zainengineer
источник
0

Когда дело доходит до функций браузера js, они window.alertвыдающиеся и наиболее известные, люди, которые не знают js, знают alert()- будьте уверены, что он поддерживается во всех браузерах, используемых сегодня, и ваш фрагмент кода также. Однако я бы не стал переопределять (ну, это скорее рефакторинг, а не переопределение в смысле ООП) alert()для конкретного варианта использования, как ваш, потому что, когда вам действительно нужно использовать alert()без шаблона, и, вероятно, вам это понадобится, тогда вам понадобится другая функция без предупреждения для этого.

не секвитор
источник
0

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


    const actualAlertFunc = window.alert;
    window.alert = function(msg) {
         actualAlertFunc('some default message '+ msg);
    }

Я проверил это на хром. Я не уверен, что это хорошая практика, но она служит цели.

Бадри Натх
источник