- 1С-Битрикс. LazyLoad или ленивая загрузка контента при включенном кешировании
- Технические детали
- Способ первый: без кеширования
- Способ второй: с кешированием
- Пример JavaScript кода
- Обновлено 1.12.14
- Способ третий: с включенным композитным режимом
- Похожие записи
- 1C-Битрикс. Кастомизация нового шаблона компонента sale.order.ajax
- 1С-Битрикс. Защита от спама в регистрации без капчи
- 1С-Битрикс. Пишем человеческий шаблон многоуровнего меню каталога
- 58 комментариев
1С-Битрикс. LazyLoad или ленивая загрузка контента при включенном кешировании
В этой заметке я хочу рассказать о технологии LazyLoad или в простонародье «ленивая загрузка»(её ещё называют бесконечный скроллинг или Infinity Scroll) в Битриксе. Метод, описанный мной, будет точно работать в компонентах catalog.section и news.list.
Файлы компонентов, мы конечно же, модифицировать не будем.
«Ленивая загрузка» позволяет снизить нагрузку на сервер, а так же намного быстрее показывать нужный контент пользователю. Зачем ему перезагружать всю страницу целиком, если можно подгрузить только нужный фрагмент страницы. В нашем случаем — это элементы, будь то, элементы новостей или товары каталога.
Суть такого механизма проста: пользователю сначала показывается, например, 15 новостей и потом, как только он докручивает до их конца, сразу же подгружаются следующие 15 элементов. И так, пока не закончатся элементы.
Технические детали
В конце, после списка элементов, мы будем вставлять пустую ссылку, на следующие элементы. В ссылку будем добавлять параметр AJAX_PAGE, он нам ещё понадобится.
Выглядеть она будет примерно так:
Формировать ссылку будем следующим образом:
Способ первый: без кеширования
Этот способ самый простой и первым приходит в голову.
В шаблон компонента, до вывода элементов вставляем такую строку:
А после вывода элементов вставляем это:
Что мы делаем:
Если страницу открываем при помощи AJAX, то перед выводом элементов сбрасываем буфер контента функцией $APPLICATION->RestartBuffer(). А в конце просто выходим. Тем самым мы отдаем только нужный кусок контента при аякс запросе.
Но в этом способе есть большой минус. Функция RestartBuffer() не будет работать при включенном кешировании.
Способ второй: с кешированием
Тут нам на помощь приходит файл component_epilog.php. Он выполняется при каждой загрузке страницы и запускается после того, как отработал шаблон. Как раз то, что нам нужно.
Теперь в шаблон компонента, до вывода элементов и после вывода элементов вставляем html комментарий:
В папке с темой для нужного компонента создаем файл component_epilog.php и вставляем в него этот код:
Пример JavaScript кода
Объясню, что происходит. Теперь при открытии страницы при помощи AJAX запроса, отрабатывает шаблон и вызывается файл component_epilog.php. В нем мы получаем весь контент из буфера, разбиваем его по нашему html комментарию и отдаем клиенту.
Вот такой вот хитрый способ 🙂
Обновлено 1.12.14
В комментариях к заметке и в письмах на почту люди спрашивают, как быть с включенным композитным режимом? Ведь второй способ «с включенным кешированием» не заработает. И совершенно верно.
Способ третий: с включенным композитным режимом
Если посмотреть на блок-схему работы технологии, то можно заметить, что после исполнения страницы и перед записью её в кеш композита, вызывается событие OnEndBufferContent (оно же вызывается и без технологии). На нём мы и сыграем.
Привожу код обработчика для композитного режима:
Добавить его нужно в init.php вашего сайта.
Если в настройках композита стоит галочка «Сохранять на диск только страницы без параметров», то в поле «а также страницы содержащие только следующие параметры» надо добавить параметр AJAX_PAGE.
И хочу заметить, что при этом способе код приведённый во втором пункте для файла component_epilog.php с включенным кеширование нужно удалить.
Ещё теги для роботов: ajax постраничная навигация, ajax пагинация, ajax подгрузка товаров.
Похожие записи
1C-Битрикс. Кастомизация нового шаблона компонента sale.order.ajax
С выходом нового шаблона компонента sale.order.ajax на форумах битрикса разгораются возмущения и недомения. Мол, теперь код всего шаблона на JavaScript и как его кастомизировать непонятно. На самом деле да, код js-скрипта составляет почти семь тысяч строк. Сходу в таком количестве кода, даже хорошо написанного (к сожалению, битрикс этим не балует), соблюдая паттерны программирования, будет непросто.
В этой заметке я покажу способ, как можно кастомизировать основной скрипт логики шаблона оформления заказа (order_ajax.js), не прибегая к его правке. Что нам это даёт? Когда прилетят очередные обновления шаблона, мы просто заменим его и всё. Все наши кастомизации будут работать (в теории).
1С-Битрикс. Защита от спама в регистрации без капчи
Не редкость, когда боты начинают регистрироваться на сайтах и захламлять списки пользователей своим присутствием. В «1С-Битрикс» можно включить капчу для защиты от спама. Но порой и капча не спасает, да и заставлять пользователей вводить код с капчи, я считаю, не гуманно. Воспользуемся другим трюком.
1С-Битрикс. Пишем человеческий шаблон многоуровнего меню каталога
Не буду писать про боль при интегации дефотного шаблона. Давайте просто напишем свой, с блекджеком и вот этим всем.
В заметке будет (интересного):
- построение древовидного массива без рекурсии (неограниченной вложенности)
- анонимная рекурсивная функция
- формирование урлов для секций супер-быстрым способом
- поработаем с сущностями инфоблока через ORM D7
Дальше много кода.
58 комментариев
не работает. как в результате должен выглядеть рабочий темплейт?
Шаблон будет выглядеть примерно так.
К сожалению данная конструкция лишь обновляет содержимое блока news-list, а не добавляет новые новости в конец списка. Хотелось бы что бы загрузка работала как во вконтакте.
Значит что-то делаете не так, а точнее ваш JavaScript обновляет содержимое этого блока, а не дописывает в конец.
А какой скрипт используется? Какой-то из типовых в ядре или что-то ещё?
Скрипт используется свой. Если нужно, могу выложить.
Буду очень благодарен! И наверняка не я один
Обновил заметку. Добавил пример JavaScript кода. По сути — он универсальный. Единственное условие: надо ссылке, формирующую линк к следующим элементам, добавить атрибут data-wrapper-class со значением класса блока, в который надо грузить загружаемые элементы.
пишет Uncaught TypeError: Cannot read property ‘length’ of undefined где может быть ошибка?
Fedor, проверил только что на свежем проекте — работает, ошибок нет.
На какой строке у вас ошибка?
Все уже, спасибо, разобрался. А еще вопрос, в каталоге при скролле таким методом возникает задержка секунд шесть, пока подгрузится новый контент. Как возможно ускорить загрузку?
Fedor, в яваскрипт коде задержки нет. Если долго приходит ответ с сервера, значит дело в нём.
Может я чего-то не понимаю. Но в случае с кешированием, мы разделим буфер на ДО и ПОСЛЕ . В итоге получим то что нужно + то что идет дальше по коду. Ведь снизу код не обрезался. По мне может нужно вставить этот коммент еще и после вывода списка и соответственно в list написать так (, $content_html, ). или я что-то упустил?
Дмитрий, с конструкцией list() в заметке всё верно, а вот в случае с html комментарием
я забыл упомянуть, что его нужно вставить и после вывода элементов. Спасибо за наводку 🙂
Ну да насчет list и как в заметке будет работать. просто для большей наглядности, что код делится на 3 части. А вот меня еще мучает вопрос. Как сделать чтобы при клике на элементе в подгруженном списке и нажатии кнопки назад все вернулось к тому же месту. Допустим пользователь очень много пролистал (подгрузил) ,перешел к какому-нибудь элементу, потом нажимает Назад и попадает снова в начало списка. И опять все сначала. Ломаю голову как такое реализовать по-грамотному)))
Доброго дня! Использовал Ваш скрипт и мне выдало ошибку, что :
Fatal error Call to undefined function htmlspecialcharsbx()
В чем может быть проблема?
Какая версия главного модуля у вас? Функция htmlspecialcharsbx добавлена в версии 11.5.9
Можно попробовать заменить на htmlspecialchars
Использовал ваш скрипт и ваш код но не работает. никаких ошибок, просто все работает как и раньше без этого кода. в чем может быть проблема ?
Алексей, что значит «все работает как и раньше»? Как по вашему должно работать?
я так понимаю при прокрутке вниз должны появляться новые элементы? но этого не происходит
Вариант с включенным кэшированием хорошо. Но не работает при композитном режиме, что актуально на данный момент. Хотелось бы увидеть решение рабочее и для композитного решения.
Владимир, я обновил заметку. Добавил про работу с включенным композитом.
Попробовала сделать по вашему примеру подгрузку элементов при прокрутке. Но чего-то не получилось.
Ссылки так и остались прежние — в них нет «AJAX_PAGE»
Вот мой код шаблона в компоненте catalog.section
Эхо выводиться, а вот ГЕТ пустой.
Что я не так делаю?
Юлия, мне кажется вы не вникли в принцип работы.
В ссылках элементов не должно быть параметра AJAX_PAGE, он должен быть у ссылки для следующих (которая с классом ajax-pager-link).
Использовали 3-й вариант (с включенным композитным режимом), Подгрузка работает, но почему то после создания кэша композита сбивается кодировка у элементов (видимо кэш создается не в кодировке сайта). Сайт работает в кодировке windows-1251. Почему такое происходит и как можно это исправить?
Владимир, в кеш композита записывает само ядро битрикса. Возможно какой-то баг с этой кодировкой. Напишите им в техническую поддержку, обязательно помогут.
Че за нубы 🙂 Все прекрасно работает,когда помимио тупого копипаста еще и мозги включить!
Здравствуйте! А javascript код вставлять так же в шаблон компонента?:)
Alyona, куда вам удобнее
А какие-то дополнительные настройки компонента news:list нужны? Просто эффекта нуль, вот не знаю в чем дело.
Может кому пригодится, у меня при включенном режиме аякс в настройках компонента как раз происходила некоректная работа данного скрипта (товары не догружались, а обновляли полностью страницу), выключив же ее в настройках все стало ОК. Спасибо автору, все чудесно работает!
Подскажите пожалуйста как быть с таким случаем: https://www.olegpro.ru/post/bitriks_LazyLoad_ili_lenivaya_zagruzka_kontenta_pri_vklyuchennom_keshirovanii.html#c171 Спасибо!
Никита, дописывать js-скрипт.
Сделал 3 вариант (с композитом), в итоге получил не совсем корректную работу: 1. элементы подгружаются при каждом скролле, а не по достижению конца списка элементов. 2. в подгруженных элементах навешенные обработчики ссылок.
Код у нас примерно как у Юлии в комментариях. Используется комплексный компонент Каталог. Код внедряем в catalog.section. Но не работает, вообще ничего не происходит.
Надежда, а что вы ожидаете увидеть?
Распишите подробно по шагам: что делаете и что в каждом шаге ожидаете увидеть.
- Большое спасибо за статью. Избавился от большой головной боли и сделал по примеру немного переделав под себя.
Вопрос. Как в этом случае можно перезагружать фильтр?
Кирилл, о каком фильтре речь?
Может я туплю конечно ) Щас вот поеду додумывать. Суть какая, есть у меня элементы они выводятся по столько за раз по сколько надо мне. Собственно так же как и в Вашем примере. Но у меня на странице размещен фильтр. обычный умный фильтр и вот он вчера после реализации подгрузки не работал корректно. Т.е. он не фильтровал элементы. Либо потому что они еще не получены до подгрущки либо еще почему то. Если сталкивались напишите. А так часа через два на работе попробую вникнуть по глубже. Вчера вечером уже не до того было)
Олег Максименко, использую 2-ой способ — с кэшированием. Компонент комплексный, каталог (с фильтрами и прочим), внедряю код формирования ссылки и яваскрипт в шаблон компонента catalog.section, перед foreac и после. В папке с темой для этого компонента создала component_epilog.php с указанным кодом. Затем в адресной строке симулирую ?AJAX_PAGE=Y и скроллю страницу. Элементы выводятся по 6, всего их там 197. Но при скроллинге ничего не происходит. Я еще не проверяла имена массивов и переменных, и вообще сильно не вчитывалась, пока что просто понадеялась, на то, что «Метод будет точно работать в компонентах catalog.section», хотя возможно речь шла о простом, а не о комплексном компоненте. Кстати, у catalog.section есть свой component_epilog.php в корне компонента (а не в теме), наверное, они конфликтуют, надо будет посмотреть, что там написано.
*перед foreach и после. ID с именем news-list присвоила диву, котором перебираются элементы. Вроде ничего не упустила.
Затем в адресной строке симулирую ?AJAX_PAGE=Y
при таком варианте в браузере вы должны видеть только «вырезанную» часть страницы, то есть ни шапки, ни подвала быть не должно. Если вы их видите, то ваш component_epilog.php не отрабатывает. В вашем случае он должен быть в папке с шаблоном catalog.section
Олег Максименко, внесла исправления в component_epilog.php в папке с шаблоном catalog.section. Действительно, при параметре AJAX_PAGE=Y, шапки и подвала теперь не видно, идет чистый html компонента, без стилей, без ничего.. А в каталоге по-прежнему ничего при скролле не появляется. Может, я функцию неправильно подключаю? в яваскрипте я не сильна. разве функция должна быть описана в скобках?
Спасибо всем! Все вопросы решил) Все работает) http://tau.zolotarev-studio.ru/services/prodazha/
Надежда, напишите через обратную связь ссылку на сайт, посмотрю.
Олег Максименко, я попробую внедрить то же самое на ЧИСТОЙ установке магазина битрикс, о результатах сообщу.
Олег Максименко, я попробовала. Тут хотя бы консоль ругается: (index):1463 Uncaught ReferenceError: $ is not defined(anonymous function) @ (index):1463(anonymous function) @ (index):1471 Сейчас погуглю, охоже просто на неподключенную библиотеку, хотя она же там должна быть.
написала данные в обратную связь
Как обновить постраничную навигацию ?
Что делать если на странице два компонента? Указанный метод перестает работать. При клике на 1 показать еще, срабатывает и 2
Добавить дополнительных классов блокам. Дописать js-скрипт.
работает только для 2-х страниц. Подгружается долго. По сути этот тот же переход по ссылке только без перезагрузки. Ожидался эффект именно плавной загрузки по одному товар, а не всей 2-й страницы.
отличный компонент! при правильной настройке, работает как надо.
А можно ли при таком варианте исполнения оставлять url в адресной строке? Кажется что это полезнее для seo.
https://www.olegpro.ru/post/bitriks_LazyLoad_ili_lenivaya_zagruzka_kontenta_pri_vklyuchennom_keshirovanii.html#c686 Николай
К сожалению не работает скрипт, сделал все как указано в примере.
Стандартный компонент и шаблон catalog.section теперь уже и сам умеет в ленивую загрузку. И в композитном режиме и без. Добавляется два параметра при вызове компонента: «LAZY_LOAD»=>»Y» и «LOAD_ON_SCROLL»=>»Y» (обрабатываются на уровне класса ElementList – родителя класса компонента). Код из init.php возвращается в component_epilog.php, а AJAX-запрос вместо самой страницы обращается к файлу ajax.php компонента (который по-умолчанию лежит /bitrix/components/bitrix/catalog.section/ajax.php).
Такой подход несколько сложнее для внедрения, если шаблон переделанный (а если компонент модифицированный, так тем более), есть свои подводные камни, но всё же я лучше не буду лишний раз модифицировать init.php, если этого можно избежать, да и при таком подходе AJAX игнорирует всё, кроме нужного нам компонента, следовательно отработает быстрее. Как минимум обозначит такую возможность всё-таки надо )
Использую по третьему варианту (с композитом) работает, но почему то иногда дублирующийся элементы появляются когда несколько раз кнопку нажимаешь «показать еще». В чем может быть проблема
Источник