Discuss and resolve questions on Liquid, JavaScript, themes, sales channels, and site speed enhancements.
If I use a custom section with JS code then it only works the first section .if I used multiple times then JS it is not working. any solution ?? . I also put JS code in Theme and global.js liquid file but it is not working.
It really depends on what your trying to do an what section you are trying to add custom code for. Best practice if code is for a specific page such as item or blog etc, so that your shop is able to be updated without having to trace back to snipet etc.
But again hard to provide any specific advice without more information.
I've created video with text section and added java script for the forward video and backwards video. it's working only first section if I've add some more video with section there are not working another sections.
here is Java script and liquid code
{%- style -%}
.section-{{ section.id }}-padding {
padding-top: {{ section.settings.padding_top | times: 0.75 | round: 0 }}px;
padding-bottom: {{ section.settings.padding_bottom | times: 0.75 | round: 0 }}px;
}
@media screen and (min-width: 750px) {
.section-{{ section.id }}-padding {
padding-top: {{ section.settings.padding_top }}px;
padding-bottom: {{ section.settings.padding_bottom }}px;
}
}
{%- endstyle -%}
<div class="image-with-text image-with-text--{{ section.settings.content_layout }} page-width isolate{% if settings.text_boxes_border_thickness > 0 and settings.text_boxes_border_opacity > 0 and settings.media_border_thickness > 0 and settings.media_border_opacity > 0 %} collapse-borders{% endif %}{% unless section.settings.color_scheme == 'background-1' and settings.media_border_thickness > 0 and settings.text_boxes_shadow_opacity == 0 and settings.text_boxes_border_thickness == 0 or settings.text_boxes_border_opacity == 0 %} collapse-corners{% endunless %} section-{{ section.id }}-padding">
<div class="image-with-text__grid grid grid--gapless grid--1-col grid--{% if section.settings.desktop_image_width == 'medium' %}2-col-tablet{% else %}3-col-tablet{% endif %}{% if section.settings.layout == 'text_first' %} image-with-text__grid--reverse{% endif %}">
<div class="image-with-text__media-item image-with-text__media-item--{{ section.settings.desktop_image_width }} image-with-text__media-item--{{ section.settings.desktop_content_position }} grid__item">
<div class="video-section__media new_media">
{% if section.settings.videourl != blank %}
<div class="video-container ">
<video class="player__video viewer" playsinline disablePictureInPicture controlsList="nofullscreen" controls loop src="{{ section.settings.videourl }}"></video>
<div class="video-rewind-notify rewind notification">
</div>
</div>
{% endif %}
</div>
</div>
<div class="image-with-text__text-item grid__item">
<div id="ImageWithText--{{ section.id }}" class="image-with-text__content image-with-text__content--{{ section.settings.desktop_content_position }} image-with-text__content--desktop-{{ section.settings.desktop_content_alignment }} image-with-text__content--mobile-{{ section.settings.mobile_content_alignment }} image-with-text__content--{{ section.settings.height }} gradient color-{{ section.settings.color_scheme }} content-container">
{%- for block in section.blocks -%}
{% case block.type %}
{%- when 'heading' -%}
<h2 class="image-with-text__heading {{ block.settings.heading_size }}" {{ block.shopify_attributes }}>
{{ block.settings.heading | escape }}
</h2>
{%- when 'caption' -%}
<p class="image-with-text__text image-with-text__text--caption {{ block.settings.text_style }} {{ block.settings.text_style }}--{{ block.settings.text_size }} {{ block.settings.text_style }}" {{ block.shopify_attributes }}>{{ block.settings.caption | escape }}</p>
{%- when 'text' -%}
<div class="image-with-text__text rte {{ block.settings.text_style }}" {{ block.shopify_attributes }}>{{ block.settings.text }}</div>
{%- when 'button' -%}
{%- if block.settings.button_label != blank -%}
<a{% if block.settings.button_link == blank %} role="link" aria-disabled="true"{% else %} href="{{ block.settings.button_link }}"{% endif %} class="button{% if block.settings.button_style_secondary %} button--secondary{% else %} button--primary{% endif %}" {{ block.shopify_attributes }}>
{{ block.settings.button_label | escape }}
</a>
{%- endif -%}
{%- endcase -%}
{%- endfor -%}
</div>
</div>
</div>
</div>
<script>
const video = document.querySelector('.player__video');
const notifications = document.querySelectorAll('.notification');
const forwardNotificationValue = document.querySelector('.video-forward-notify span');
const rewindNotificationValue = document.querySelector('.video-rewind-notify span');
let timer;
let rewindSpeed = 0;
let forwardSpeed = 0;
//function for double click event listener on the video
//todo change those variable to html5 data attributes
function updateCurrentTime(delta){
let isRewinding = delta < 0;
if(isRewinding){
rewindSpeed = rewindSpeed + delta;
forwardSpeed = 0;
}else{
forwardSpeed = forwardSpeed + delta;
rewindSpeed = 0;
}
//clear the timeout
clearTimeout(timer);
let speed = (isRewinding ? rewindSpeed : forwardSpeed);
video.currentTime = video.currentTime + speed;
let NotificationValue = isRewinding ? rewindNotificationValue : forwardNotificationValue ;
NotificationValue.innerHTML = `${Math.abs(speed)} seconds`;
//reset accumulator within 2 seconds of a double click
timer = setTimeout(function(){
rewindSpeed = 0;
forwardSpeed = 0;
}, 2000); // you can edit this delay value for the timeout, i have it set for 2 seconds
console.log(`updated time: ${video.currentTime}`);
}
function animateNotificationIn(isRewinding){
isRewinding ? notifications[0].classList.add('animate-in') : notifications[1].classList.add('animate-in');
}
function animateNotificationOut(){
this.classList.remove('animate-in');
}
function forwardVideo(){
updateCurrentTime(5);
animateNotificationIn(false);
}
function rewindVideo(){
updateCurrentTime(-5);
animateNotificationIn(true);
}
//Event Handlers
function doubleClickHandler(e){
console.log(`current time: ${video.currentTime}`);
const videoWidth = video.offsetWidth;
(e.offsetX < videoWidth/2) ? rewindVideo() : forwardVideo();
}
function togglePlay(){
video.paused ? video.play() : video.pause();
}
//Event Listeners
video.addEventListener('click', togglePlay);
video.addEventListener('dblclick', doubleClickHandler);
notifications.forEach(function(notification){
notification.addEventListener('animationend', animateNotificationOut);
});
</script>
1. You should not use inline scripts, especially for sections that can be included several times on one page.
2. Use web components (aka custom elements) and query selectors inside component using reference to context (this.querySelector(...)).
3. You can use:
querySelectorAll('.player__video').forEach(player => {
const notifications = player.querySelectorAll('.notification');
...
})
Last variant the most fastest solution for you but not really recommended.
Shopify and our financial partners regularly review and update verification requiremen...
By Jacqui Mar 14, 2025Unlock the potential of marketing on your business growth with Shopify Academy's late...
By Shopify Mar 12, 2025Learn how to increase conversion rates in every stage of the customer journey by enroll...
By Shopify Mar 5, 2025