Назначение значений по умолчанию в вызове функции - это запах кода.
def a(b=[]):
pass
Это сигнатура функции, которая не подходит. Не только из-за проблем, описанных в других ответах. Я не буду вдаваться в это.
Эта функция направлена на то, чтобы сделать две вещи. Создайте новый список и выполните функциональность, скорее всего, в указанном списке.
Функции, которые делают две вещи, являются плохими функциями, поскольку мы учимся на чистых практиках кода.
Атака на эту проблему с полиморфизмом мы будем расширять список python или переносить его в класс, а затем выполнять свою функцию на нем.
Но подождите, пока вы скажете, мне нравятся мои однострочные.
Ну , Угадай, что. Код - это не просто способ управления поведением оборудования. Это способ:
Не оставляйте бомбы замедленного действия для себя
Отделяя эту функцию от двух вещей, которые она делает, нам нужен класс
class ListNeedsFives(object):
def __init__(self, b=None):
if b is None:
b = []
self.b = b
def foo():
self.b.append(5)
Выполнено
a = ListNeedsFives()
a.foo()
a.b
И почему это лучше, чем слияние всего вышеописанного кода с одной функцией.
def dontdothis(b=None):
if b is None:
b = []
b.append(5)
return b
Почему бы не сделать это?
Если вы не сработаете в своем проекте, ваш код будет жить. Скорее всего, ваша функция будет делать больше, чем это. Правильный способ создания поддерживаемого кода состоит в том, чтобы разделить код на атомные части с должным образом ограниченным объемом.
Конструктор класса является очень общепризнанным компонентом для всех, кто сделал объектно-ориентированное программирование. Размещение логики, которая обрабатывает экземпляр списка в конструкторе, делает когнитивную нагрузку понимания того, что делает код меньше.
Метод foo()
не возвращает список, почему бы и нет?
При возврате отдельного списка вы можете предположить, что безопасно делать то, что вам хочется. Но это может быть не так, поскольку он также разделяется объектом a
. Заставляя пользователя ссылаться на него как a.b
, он напоминает, где находится список. Любой новый код, который хочет изменить a.b
, естественно, будет помещен в класс, где он принадлежит.
Функция подписи def dontdothis(b=None):
не имеет ни одного из этих преимуществ.
Я рекомендую использовать monitorEvents
. Это функция, предоставляемая консолью javascript в обоих веб-инспекторе и firebug , который выводит все события, которые генерируются элементом. Вот пример того, как вы его используете:
monitorEvents($("input")[0]);
В вашем случае Firefox и Opera генерируют событие input
, когда пользователь выбирает элемент из автозаполнение. В IE7-8 событие change
создается после изменения пользователем фокуса. Последний Chrome создает аналогичное событие.
Подробную таблицу совместимости браузера можно найти здесь: https://developer.mozilla.org/en-US/docs/Web/Events/input
Я понял через monitorEvents
, что по крайней мере в Chrome событие keyup
запускается перед событием автозаполнения input
. На обычном вводе клавиатуры последовательность keydown
input
keyup
, поэтому после ввода.
То, что я сделал, тогда:
let myFun = ()=>{ ..do Something };
input.addEventListener('change', myFun );
//fallback in case change is not fired on autocomplete
let _k = null;
input.addEventListener( 'keydown', (e)=>_k=e.type );
input.addEventListener( 'keyup', (e)=>_k=e.type );
input.addEventListener( 'input', (e)=>{ if(_k === 'keyup') myFun();})
Нужно проверить с другим браузером, но это может быть без интервалов.
Как объяснил Xavi , для этого нет 100% -ного кросс-браузера, поэтому я создал трюк самостоятельно (5 шагов для продолжения): 1. Мне нужна пара новых массивов:
window.timeouts = new Array();
window.memo_values = new Array();
2. в фокусе ввода текста, который я хочу вызвать (в вашем случае «электронная почта», в моем примере «имя») я установил интервал, например, используя jQuery (не требуется мысль):
jQuery('#name').focus(function ()
{
var id = jQuery(this).attr('id');
window.timeouts[id] = setInterval('onChangeValue.call(document.getElementById("'+ id +'"), doSomething)', 500);
});
3. на размытии я удаляю интервал: (всегда с использованием jQuery не требуется мысль), и я проверяю, изменилось ли значение
jQuery('#name').blur(function ()
{
var id = jQuery(this).attr('id');
onChangeValue.call(document.getElementById(id), doSomething);
clearInterval(window.timeouts[id]);
delete window.timeouts[id];
});
4. Теперь основная функция, которая проверяет изменения, следующая
function onChangeValue(callback)
{
if (window.memo_values[this.id] != this.value)
{
window.memo_values[this.id] = this.value;
if (callback instanceof Function)
{
callback.call(this);
}
else
{
eval( callback );
}
}
}
Важное примечание: вы можете использовать «это» внутри указанной функции, ссылаясь на ваш инициированный входной элемент HTML. Для работы этой функции должен быть указан идентификатор, и вы можете передать функцию или имя функции или строку команды в качестве обратного вызова.
5. Наконец вы можете что-то сделать, когда вход значение изменяется, даже если значение выбрано из раскрывающегося списка автозаполнения
function doSomething()
{
alert('got you! '+this.value);
}
Важное примечание: снова вы используете «это» внутри указанной функции, ссылаясь на ваш инициированный входной элемент HTML. РАБОЧИЙ ФИДДЛ !!! Я знаю, что это звучит сложно, но это не так. Я подготовил рабочую скрипту для вас, вход для изменения называется «имя», поэтому, если вы когда-либо вводили свое имя в онлайн-форме, у вас может быть раскрывающийся список автозаполнения вашего браузера для тестирования.
Использование: вход события. Для выбора предложений (ввода или текстового поля)
ДЛЯ ПРИМЕРЫ ДЛЯ JQUERY:
$(input).on('input', function() {
alert("Number selected ");
});
ДЛЯ ПРИМЕРА JAVASCRIPT:
<input type="text" onInput="affiche(document.getElementById('something').text)" name="Somthing" />
Этот запуск ajax-запроса ...
Добавьте «размытие». работает во всех браузерах!
$("input").on('blur keyup change click', function () {
Я не думаю, что для этого вам нужно событие: это происходит только один раз, и для этого нет хорошей поддержки браузера, как показано в ответе @xavi.
Просто добавьте функция после загрузки тела, которая проверяет поля один раз для любых изменений значения по умолчанию, или если это просто вопрос копирования определенного значения в другое место, просто скопируйте его, чтобы убедиться, что он инициализирован правильно.
Вот удивительное решение.
$('html').bind('input', function() {
alert('test');
});
Я тестировал Chrome и Firefox, а также будет работать и для других браузеров.
Я пробовал много событий со многими элементов, но только это срабатывает при выборе из автозаполнения.
Надеюсь, что это сэкономит время.
change
не запускается, поэтому вам нужно всего лишь добавить прослушиватель в change
и input
события. $field.on('change input', changeFunction)
– MarthyM
24 February 2017 в 16:25
$input.on('keyup input change paste', callback)
. Работает очень хорошо.
– Sorin C
30 August 2017 в 13:11
Единственный верный способ - использовать интервал.
Ответ Луки слишком сложный для меня, поэтому я создал свою короткую версию, которая, надеюсь, поможет кому-то (может быть, даже мне из будущего):
$input.on( 'focus', function(){
var intervalDuration = 1000, // ms
interval = setInterval( function(){
// do your tests here
// ..................
// when element loses focus, we stop checking:
if( ! $input.is( ':focus' ) ) clearInterval( interval );
}, intervalDuration );
} );
Проверено на Chrome, Mozilla и даже на IE.
change
по-прежнему срабатывает при размытии, поэтому мне не нужно смотреть размытие. – Explosion Pills 18 December 2011 в 01:36input
также помогает Opera. – Xavi 18 December 2011 в 12:49input
, и он работает для всех браузеров, которые я установил. Версии: Firefox 21.0, Opera 12.15, Chrome 27, Safari 5.1.7 и IE 9. – awe 18 June 2013 в 13:51