Использование событий более коротким способом

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

У меня есть форма, которая отвечает на событие oninput

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

Вот мой код JavaScript:

    firstname.oninput = function () {
    updatePreview();
    updatePostHeader();
    showPreview();
};
lastname.oninput = function () {
    updatePreview();
    showPreview();
};
age.oninput = function () {
    updatePreview();
    showPreview();
};
job.oninput = function () {
    updatePreview();
    showPreview();
};
avatar.oninput = function () {
    updateAvatar();
    showPreview();
};
message.oninput = function () {
    updatePreview();
    showPreview();
};

Как вы можете видеть, это много избыточности.

Могу ли я упростить это, как я сделал ниже или что-то в этом роде?

    for(var i=0; i<inputFields.length; i++) {
    inputFields[i].oninput = function() {
        updatePreview();
        showPreview();
    };
}

Заранее спасибо!

4 ответа

Я не совсем уверен, как вы получаете переменные, такие как: lastname, age и т.д. Но самым чистым способом было бы поместить их в массив, как вы предлагали. Подобно:

var controlIds = [
    {"id": 'id1', "functions": [updatePreview, showPreview]},
    {"id": 'id2', "functions": [updatePreview, updatePostHeader, showPreview]}
];
controlIds.map(function (item){
    item["element"] = document.getElementById(item["id"]);
    return item;
}).forEach(function(elem) {
    elem["element"].oninput = function () {
        elem["functions"].forEach(function(fn) { fn(); });
    }
});

Если поля принадлежат одной и той же форме / родителю, вы можете зарегистрировать событие oninput для родителя и передать его всем его дочерним элементам.

parent.on('event', childType, handler);

Рассматривайте приведенный выше фрагмент как псевдокод, поскольку я не знаю, используете ли вы определенную библиотеку и как работает обработка событий. Добавьте немного больше контекста, и мы можем разработать дальше.

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

Вы можете двигаться showPreview() функция в общий родительский обработчик событий в связи с тем, что oninput событие будет пузыриться до родительского элемента. Тогда код упростится до:

firstname.oninput = function () {
    updatePreview();
    updatePostHeader();
};
lastname.oninput = updatePreview;
age.oninput = updatePreview
job.oninput = updatePreview;
avatar.oninput = updateAvatar;
message.oninput = updatePreview;

form.oninput = showPreview;

Проверьте упрощенную демонстрацию ниже.

lastname.oninput = updatePreview;
form.oninput = showPreview;

function updatePreview() {
    alert('update preview');
}

function showPreview() {
    alert('show preview');
}
<form id="form">
    <input type="text" id="lastname" />
</form>

У меня есть следующий ответ на мой вопрос:

form.oninput = function () {
    for (var i = 0; i < inputFields.length; i++) {
        inputFields[i].oninput = function () {
            updatePreview();
            showPreview();
        };
    }
};

Можно зацикливаться на событиях.

Всем вам, ребята, спасибо за ваши ответы!

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