How to trigger Webflow interactions using JavaScript

How to run webflow actions (animations) from code.
As I understood binding is in “Webflow: Interactions: Init”. But how to run this actions by code?

2 Likes

You can manually trigger IX objects by following these steps:

  1. First locate the trigger object that you want to use. At the bottom of webflow.js, you will see a list of them in an array called triggers.

  2. A trigger object looks something like this:
    {"type":"load","stepsA":[{"wait":200},{"opacity":1,"transition":"transform 500ms ease 0ms, opacity 500ms ease 0ms","x":"0px","y":"0px"}],"stepsB":[]}

  3. Using the above trigger code, we can run it with the ix module:

var ix = Webflow.require('ix');
var $el = $('.your-selector-here');

var trigger = {"type":"load","stepsA":[{"wait":200},{"opacity":1,"transition":"transform 500ms ease 0ms, opacity 500ms ease 0ms","x":"0px","y":"0px"}],"stepsB":[]};

ix.run(trigger, $el);

That’s about it.

Not sure what your use case is, but you might want to bypass the IX system and use the core animation library that we use under the hood, called tram.

Tram examples can be found here: GitHub - BKWLD/tram: Cross-browser CSS3 transitions in JavaScript.

14 Likes

I want to run the IX via code. This is my page with the issues am facing with dynamic content. Oceanic Health Management

Apologies if I may be posting twice.

THANKS!!! THANKS!!! THANKS!!! You ROCKS!

Please can you share how you implemented this. Please. Am struggling with it. Thanks.

This is how my code looks like now:

JS:
            <script>
                var Webflow = Webflow || [];
            Webflow.push(function () {
            
            var ix = Webflow.require('ix');
            var $el = ('.mgtdetailprofile-block');
            var trigger = {"type":"click","stepsA":[{"height":"auto","transition":"height 800ms ease-in-out-expo 0ms"}],"stepsB":[]}
            
            ix.run(trigger, $el);
              
                });
                
            </script>
 

       HTML:
            <a class="moretext-span" data-ix="show-management-detail-profile" href="#">MORE</a>
    
    My Target Div:
    
    <div class="w-clearfix mgtdetailprofile-block" id="{tag_itemid}"><a class="mgtprofile-closelink" href="#" data-ix="close-management-detail-profile"><strong>X</strong></a>
            <div class="w-row mgtdetailedrow">
                <div class="w-col w-col-6 mgtdetailedpix-col" id="mgtpixdetailed{tag_itemid}" style="background-image: url({tag_managementpicture_value}); background-size: cover; background-position: 50% 50%; background-repeat: no-repeat no-repeat;">
              </div>
              <div class="w-col w-col-6">
                <h2 class="mgtnametitle detail">{{name}}</h2>
                  <p class="mgt-p detail">{{description}} </div>
            </div>
          </div>

But it is not working. What could I be doing wrongly?

Oops! My mistake, there was a typo in the original code:

var $el = ('.your-selector-here'); is wrong :frowning:

should be…

var $el = $('.your-selector-here');

Thanks Danro, I quite appreciate your look at my post, but am still having the same issue. These are questions and challenges:

  1. Must the selector be a class. Can I use an id?
  2. Is it compulsory to add the data-attribute data-ix=“name”
  3. How do you handle the Slug? Is it compulsory to add the slug or must the slug be done via code?

Hi @topelovely, give the following demo a try: JS Bin - Collaborative JavaScript Debugging

Basically whenever you ix.run() an element, it no longer cares about the data-ix attribute, the event type or any of the other configuration. It simply looks at the animation steps in the trigger object, and runs the animation on the element you provide. Hope that helps!

Thanks Danro, this works and rocks. Not a js guru, but would like to know if conditions can be attached to IX so that the code can be used for dynamic contents.

Hi Danro, I faced a minor challenge when I was adapting the demo, so I decided to show you what I intend to create similar to this: http://codepen.io/gabrieleromanato/pen/dDyzH

You would ask, why don’t you just go and use it and plug it in. I’m not ok with js overload. I will love using Webflow IX for all interactions. Is this doable? I mean making all the images “on click” to be directed to one large preview. Would want to know if it is possible. Thanks

And what is the correct syntax to run StepsB part of the animation?

Also, I’d like to place some variable as one of the parameters, like:

...{"width":"' + window_width + 'px","height":"250px"...

is that possible?

how to add value

{"slug":"fade-down","name":"Fade down","value":{"style":{"opacity":0,"x":"0px","y":"-35px","z":"0px"},"triggers":[{"type":"load","stepsA":[{"opacity":1,"transition":"transform 1000ms ease 0ms, opacity 1000ms ease 0ms","x":"0px","y":"0px","z":"0px"}],"stepsB":[]}]}},

like this

@danro Does this still work the way you described? When I try to run ix.run(trigger, el); it returns undefined.

Also, what does the second argument do exactly? As I understood the trigger object itself contains DOM selectors so why do I need to pass an element into the run method?

Maybe the examples you described are out of date. If that’s the case, would you mind updating the instruction :slight_smile:

I’m trying to use the Webflow IX system with a web application, that’s why I’d like to trigger interactions from code.

Thanks!

At first don’t forget to place the line

var ix = Webflow.require('ix'); above all.

Then I usually take the ix code from the bottom of webflow.js and clean it like this:

var ixItemHover = {
  'stepsA': [{
    'opacity': 0.59,
    'transition': 'transform 200ms ease 0ms, opacity 200ms ease 0ms',
    'scaleX': 0.9,
    'scaleY': 0.9,
    'scaleZ': 1
  }]
};

Then it’s possible to fire the ix animation on any DOM node (not jQuery element);

var el = document.querySelector('#hoveredElement');
ix.run(ixItemHover, el);

Easy

So… firing ix.run() doesn’t actually run the animation, but it binds it to the element?

Isn’t there a way to make the animation run without binding it to DOM element?

For example, I have this trigger object:

{
	"slug": "show-modal",
	"name": "Show Modal",
	"value": {
		"style": {},
		"triggers": [
			{
				"type": "click",
				"selector": ".modal-background",
				"stepsA": [
					{
						"display": "flex"
					},
					{
						"opacity": 1,
						"transition": "opacity 200 ease 0"
					}
				],
				"stepsB": []
			},
			{
				"type": "click",
				"selector": ".modal",
				"preserve3d": true,
				"stepsA": [
					{
						"display": "block"
					},
					{
						"opacity": 1,
						"transition": "opacity 200 ease 0, transform 200 ease 0",
						"x": "0px",
						"y": "0px",
						"z": "0px"
					}
				],
				"stepsB": []
			},
			{
				"type": "click",
				"selector": ".modal-wrap",
				"stepsA": [
					{
						"display": "flex"
					}
				],
				"stepsB": []
			}
		]
	}
}

As far as I understand, the default Webflow’s mechanism of animating anyway binds the animation to all the elements, marked with “slug”.

@ma11k
Thank you so much! You helped me realize that the animation has to start with ‘stepsA’ and can’t contain ‘stepsB’ or no animation will happen. For anyone else who needs some help, this is an example of what my code looks like. I had a shrinking menu triggered when users scroll down the page, but if they pressed the back or reload buttons the menu would go back to full size when the page was reloaded and they were halfway down the page. This function shrinks the menu if they’re more than 90 pixels scrolled down the page when it loads (that’s how tall my invisible scroll trigger at the top is). Hope this helps someone.


// The animation code
var ix = Webflow.require('ix');
var ixAnimation = {
	"stepsA":[{
		"height":"60px",
		"transition":"height 1100ms ease 0"
	}]
};
var el = $('.navcontainer');
ix.run(ixAnimation, el);

// The complete function that checks if the page is scrolled & if it is, shrinks the menu
function shrinkMenuIfScrolled() {
	if (window.pageYOffset > 90) {
		var ix = Webflow.require('ix');
		var ixAnimation = {
			"stepsA":[{
				"height":"60px",
				"transition":"height 1100ms ease 0"
			}]
		};
		var el = $('.navcontainer');
		ix.run(ixAnimation, el);
	}
}
shrinkMenuIfScrolled();