Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Функция кеширования(трудно :)) (https://javascript.ru/forum/misc/32422-funkciya-keshirovaniya-trudno.html)

dmitry111 16.10.2012 05:37

Функция кеширования(трудно :))
 
Есть страничка, на ней есть элемент-контейнер N с содержимым(картинки), также на страничке присутствуют радиокнопки.

Когда пользователь нажимает на радиокнопку происходит Ajax-запрос и в элемент-контейнер N загружается другое содержимое

Решил сделать автокеширование, чтобы лишний раз не гонять запросы на сервер.
То есть, когда пользователь нажимает на радиокнопку, содержимое элемента-контейнера N сохраняется в объект в виде NodeList и при повторном нажатии это содержимое становится доступно из этого объекта.

Вот сам код:

var N = document.getElementById("imgCont"); // это элемент контейнер
var obj = {}; // объект, в котором будем сохранять содержимое N
var buts = document.getElementById("buttoms"); // контейнер с радиокнопками

var dir = "dir1"; // тут хранятся значения value от радиокнопок. По умолчанию dir1

function getNewContent (e) {

//..тут описан код отфильтровывающий действия на событие, он не представляет интереса...//

    saveObjectIMG(dir); // кешируем

    if (obj[e.target.value]) {

            N.innerHTML = obj[e.target.value]; // возвратим данные в контейнер

    }
    // иначе загрузим AJAXом
    else {
        //*тут ajax запрос, он не представляет интереса*//
    } 

    // В конце изменем название директории та активное
    dir = e.target.value;

}

function saveObjectIMG(param) {

    var result = N.innerHTML;
    obj[param] = result;
 
    return obj[param];

}

buts.onclick = getNewContent; // при клике на радиокнопку


Исправил, должно работать c InnerHTML

Aetae 16.10.2012 06:53

childNodes - это именно активные childNodes. Делая obj[name] = N.childNodes ты присваиваешь obj[name] лишь ссылку на N.childNodes. Соответственно если N умрёт или умрут его childNodes - obj[name] тоже будет пустым.
Надо в случае сокрытия не удалять ноды, а перемещать их в кеширующий documentFragment.

dmitry111 16.10.2012 07:42

Aetae,

спасибо!
Долго не мог понять что значит фраза:
"живое" представление дочерних элементов

в русской версии книжки Флэнагана.

dmitry111 16.10.2012 14:42

Подкиньте кто-нибудь примерчик как закешировать живой childNode..
Или на словах объясните

Оно меня победило, мучаюсь с 5 утра :), и все никак

melky 16.10.2012 15:05

вы пробовали дебажить код с помощью debugger и инструментов разработчика ?

сделайте пример на jsfiddle - там можно делать AJAX запросы. так легче будет разобратсья.

Nekromancer 16.10.2012 20:36

dmitry111,
сохраняй innerHTML. А если уж так хочешься childNodes то:

var cached = Array.prototype.slice.call(element.childNodes, 0);


Только тогда для ие придётся свои кастыли делать.

dmitriymar 16.10.2012 20:41

вопрос нахрена, если картинки?
1 гет аякс запросы кешируются.
2 картинки кешируются.
3 достаточно сохранять параметры запроса+адрес картинки если не гет, чтоб не делать запрос какой уже был

melky 16.10.2012 21:25

Цитата:

Сообщение от dmitriymar
1 гет аякс запросы кешируются.

да? поподробнее, пожалуйста.

dmitriymar 16.10.2012 21:48

melky,
а сам для чего соль добавлял в гет аякс запросы? тема неоднократно была на форуме, хотя это возможно только в ие, но хотя было и не только в нём. но в случае т.с то что он получает адреса изображений. кеширование легко организать как описано у Стефанова.

melky 16.10.2012 22:10

Цитата:

Сообщение от dmitriymar
а сам для чего соль добавлял в гет аякс запросы?

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

dmitry111 16.10.2012 22:45

Цитата:

Сообщение от dmitriymar (Сообщение 210601)
вопрос нахрена, если картинки?
1 гет аякс запросы кешируются.
2 картинки кешируются.
3 достаточно сохранять параметры запроса+адрес картинки если не гет, чтоб не делать запрос какой уже был

не это полюбому надо! Количество элементов меняется по требованию пользователя.
То есть конечное количество картинок не будет соответствовать кешу аякса.

И кстати, не все там так гладко с кешем аякса. Читал, уже не помню, давно было, но там есть какие-то подводные камни

dmitry111 16.10.2012 22:47

Цитата:

Сообщение от dmitriymar (Сообщение 210621)
melky,
а сам для чего соль добавлял в гет аякс запросы? тема неоднократно была на форуме, хотя это возможно только в ие, но хотя было и не только в нём. но в случае т.с то что он получает адреса изображений. кеширование легко организать как описано у Стефанова.

В шаблонах? Мемоизация(стр 106)? :)
уже изучаю :victory:

dmitry111 17.10.2012 17:56

реализовал кеш с помощью мемоизации и innerHTML (Nekromancer спасибо!)

var cache = {}; // тут будут храниться данные и будут доступны по ключу

// сама функция кеширования:
function save (param) {

var result = N.innerHTML;
cache[param] = result;

return cache[param]

}


На самом деле вся загвоздка была в работе с NodeList. Ну никак не получалось сохранить именно данные, а не "живое представление". Возможно, можно это решить с помощью клонирования (cloneNode). Но, думаю это гораздо более затратный процесс, в отличии от innerHTML. Хотя с точки зрения подхода, кеширование с NodeList выглядит более изящным :)

Nekromancer 17.10.2012 20:40

var cache = {}; // тут будут храниться данные и будут доступны по ключу
 
// сама функция кеширования:
function save(node, param) {
var cached = document.createDocumentFragment();
if (node.childNodes.length) {
for (var i = 0, nodes = node.childNodes, len = nodes.length; i < len; i++) {
cached.appendChild(nodes[i]);
}
}

cache[param] = cached;
 
}

function get(param) {
return param in cache ? cache[param].cloneNode(true) : null;
}


Можно ещё примерно так.

dmitry111 17.10.2012 22:03

Nekromancer,

да, спасибо! ;)


Часовой пояс GMT +3, время: 02:56.