@Artur937
junior

Как сохранить в localStorage значения нескольких input[radio]?

Использую следующую HTML разметку

<input type="radio" checked="checked" class="stat_inp_r" name="raz" value="1"/> <input type="radio" name="raz" class="stat_inp_r" value="2"/> <input type="radio" name="raz" class="stat_inp_r" value="3"/>

<input type="radio" checked="checked" name="raz1" class="stat_inp_r" value="1"/> <input type="radio" name="raz1" class="stat_inp_r" value="2"/> <input type="radio" name="raz1" class="stat_inp_r" value="3"/>


Код, который обрабатывает все input (checkbox запоминает отлично, а вот c radio, как выяснилось, проблема)

(function(b) {
        var e = document.querySelectorAll(b),
            a = localStorage.getItem(b),
            a = (a = JSON.parse(a)) || (a = {}, localStorage.setItem(b, JSON.stringify(a)));
            [].forEach.call(e, function(c, d) {
                void 0 !== a[d] && (c.checked = a[d]);
                c.addEventListener("change", function() {
                    a[d] = c.checked;
                    localStorage.setItem(b, JSON.stringify(a))
                });
            });
    })(".stat_inp_r");


В чем ошибка, помогите разобраться. Не могу уловить, как нужно поменять код, чтобы он заработал для input[type=radio]. Первый день знакомлюсь с localStorage, буду очень благодарен :)
  • Вопрос задан
  • 3009 просмотров
Решения вопроса 1
bingo347
@bingo347 Куратор тега JavaScript
Crazy on performance...
Для начала хочу поругаться! Ибо наговнокодят, а потом "браузеры тормозят и жрут память"...
1. Никогда не создавайте функции в циклах! НИКОГДА! Тем более однотипные.
2. Никогда не создавайте объект (тем более такой тяжелый как массив), только ради того, что бы дернуть метод его прототипа!
3. К ошибкам... Вы пробовали запускать свой код с пустым localStorage? Попробуйте...
4. Еще к ошибкам... Что будет с Вашими данными, если придет простая таска: "Добавить еще один радио между первым и вторым"?
5. Ну и не к производительности, а к читабельности и поддерживаемости:
Вы сами то разбираетесь в этих Ваших переменных a, b, c, d, e?

Теперь по теме:
input[type=radio] - это переключатель. Среди нескольких радио с одинаковым name выбран может быть только один. Вам нужно хранить не индекс - checked (чем вообще череват индекс - смотрите п.4 в моей критике), а name - value выбранного радио

Что ж, пожалуй поправлю, а заодно порефакторю Ваш код:
(function(selector) {
    // не дублируем код
    function save(data) {
        localStorage.setItem(selector, JSON.stringify(data));
    }
    // и не создаем тысячи функций в цикле
    // а используем одну общую
    function onChange(event) {
        var element = event.target,
            name = element.name,
            value = element.value;
        data[name] = value;
        save(data);
    }
    var elements = document.querySelectorAll(selector),
        data = localStorage.getItem(selector);
    if(data) { // если в сторадже что-то есть
        // то можем и распарсить
        data = JSON.parse(data);
    } else {
        // иначе парсить нельзя, будет ошибка
        // присвоим дефолтное значение и сохраним
        save(data = {});
    }
    // вместо ненужного создания массива
    // обратимся напрямую к прототипу
    Array.prototype.forEach.call(elements, function(element) {
        var name = element.name,
            value = element.value;
        if(data[name] === value) { // если текущий элемент отмечен в сторадже
            // то отметим и на странице
            element.checked = true;
        }
        // навесим созданый вне цикла хандлер на событие
        element.addEventListener("change", onChange);        
    });
})(/* ".stat_inp_r"
  А еще к селектору вопрос, мы только с этим классом радио будем запоминать?
  или же у нас каждый будет помнится?
  если каждый, то может имеет смысл обработать их все за раз:
*/ "input[type=radio]");
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@Bhudh
Проверьте значение a при первом запуске скрипта перед выполнением forEach.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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