I just wanted to point out that jQuery is automatically published with all Webflow sites, and you don’t need to add it again. If you do, it will force the user’s browser to download it twice, which is twice as slow.
The green arrow points to the version Webflow already includes, and the red arrow points to your embed - which is safe to remove (from the tutorial as well).
This is a great reminder to upgrade our automatically included version to the v1.11.3
@callmevlad Thanks for your observation. This fixes the “This script doesn’t seem to work when placed in the page (head/footer) custom code, or site-wide (head/footer) custom code.” problem.
So now, there are two options,
If you want to use Embed component, you have to include jQuery before it, as the Embed component will be before the default Webflow’s jQuery include.
Otherwise, you can put the script in the Page settings → Custom Code → Before body tag, but without inserting jQuery
If you want to stick with the first option, you can wrap the code in a $(document).ready(...) block to make sure it only executes after jQuery and the document have loaded
@samliew Neat workaround! Currently the interval/polling approach is probably the best way to accomplish this. As you’ve discovered, many of our components are lacking a public API. This is intentional, as we are working on getting it right.
In the meantime, your polling approach should do the trick. Here’s a slightly more optimized snippet:
<script>
var Webflow = Webflow || [];
Webflow.push(function() {
// Store cached references to nav elements
var sourceNav = $('#sourceNav');
var targetNav = $('#targetNav');
// Every 200ms
setInterval(function() {
// Find the index of source slideNav button's active class
var index = sourceNav.children('.w-active').index();
// Update target slider by triggering a "tap" event on the targetNav corresponding slide button
targetNav.children().eq(index).trigger('tap');
}, 200); // End interval
}); // End ready function
</script>
Using the Webflow.push() wrapper instead of $(document).ready() means you can place the code snippet anywhere on the webflow site (even in embed blocks).
You generally want to avoid using Site Settings as it will apply sitewide. Using that code may degrade performance as the script is being called 5 times per second (200ms), so you only want it to apply to the page itself that needs this feature.
great solution, however I found that other sliders, and/or hover navigations where affected, if you do not check for the current slider before triggering the tap event. Bubbling occurs and every 200ms other elements may be affected.
here’s an updated version of the code:
<script type="text/javascript" >
var Webflow = Webflow || [];
Webflow.push(function () {
// Cache references to nav elements
var sourceNav = $('#sourceNav');
var targetNav = $('#targetNav');
var currentSlide = 0;
// Every 200ms
setInterval(function() {
// Find the index of source slideNav button's active class
var index = sourceNav.children('.w-active').index();
// Prevent tap on current
if(index !== currentSlide){
// Update target slider by triggering a "tap" event on the targetNav corresponding slide button
targetNav.children().eq(index).trigger('tap');
currentSlide = index;
}
}, 200); // End interval
});
</script>
Hello,
Thank you so much for that bit of code. It works great for to sync two sliders together. I am attempting to have this work with two sets of synced sliders which each function independently. In other words I am trying to get the following:
Slider Set 1 contains sourceNav1 and targetNav1. When sourceNav1 is used, targetNav1 syncs with it (Slider set 2 remains unaffected)
Slider Set 2 contains sourceNav2 and targetNav2: When sourceNav2 is used, targetNav2 syncs with it (Slider set 1 remains unaffected)
Curious if anyone has suggestions modifying the code to handle this scenario? Any help would be greatly appreciated!