roman999 Posted November 17, 2021 Share Posted November 17, 2021 I am attempting to use the code from https://greensock.com/forums/topic/14575-how-to-create-a-sortable-list-with-draggable/ while converting to GSAP 3, es6, and Typescript. The old code works fine and I updated it to GSAP 3 syntax, still no problem. However, when I use the code in a Typescript application with imports in the *.ts file rather than script tags in the HTML file the event handlers do not get added. Developer Tools shows "_emptyFunc" (screenshot attached as comment). This use case is incompatible with CodePen, at least without payment, but here is part of my code. import {gsap} from 'gsap'; import {Draggable} from "gsap/dist/Draggable"; ... addBehavior():void { const rowSize = 100; // => container height / number of items const container = document.querySelector(".container"); const listItems = Array.from(document.querySelectorAll(".list-item")); // Array of elements const sortables = listItems.map(Sortable); // Array of sortables const total = sortables.length; gsap.to(container, { duration: 0.5, autoAlpha: 1 }); function Sortable(element, index) { const animation = gsap.to(element, { duration: 0.3, boxShadow: "rgba(0,0,0,0.2) 0px 16px 32px 0px", force3D: true, scale: 1.1, paused: true }); const dragger = new Draggable(element, { onDragStart: downAction, onRelease: upAction, onDrag: dragAction, cursor: "inherit", type: "y" }); // Public properties and methods const sortable = { dragger: new Draggable(element, { onDragStart: downAction, onRelease: upAction, onDrag: dragAction, cursor: "inherit", type: "y" }), element: element, index: index, setIndex: setIndex }; // gsap.set(element, { y: index * rowSize }); function setIndex(index) { sortable.index = index; // Don't layout if you're dragging if (!dragger.isDragging) layout(); } function downAction() { animation.play(); this.update(); } function dragAction() { // Calculate the current index based on element's position const index = clamp(Math.round(this.y / rowSize), 0, total - 1); if (index !== sortable.index) changeIndex(sortable, index); } function upAction() { animation.reverse(); layout(); } function layout() { gsap.to(element, { duration: 0.3, y: sortable.index * rowSize }); } return sortable; } function changeIndex(item, to) { // Change position in array arrayMove(sortables, item.index, to); // Set index for each sortable const order = []; sortables.forEach((sortable, index) => { sortable.setIndex(index); const content = sortable.element.innerText; order.push(content); }); document.getElementById("selection").innerHTML=order.toString(); } // Changes an elements's position in array function arrayMove(array, from, to) { array.splice(to, 0, array.splice(from, 1)[0]); } // Clamps a value to a min/max function clamp(value, a, b) { return value < a ? a : value > b ? b : value; } } Link to comment Share on other sites More sharing options...
roman999 Posted November 17, 2021 Author Share Posted November 17, 2021 Here's the screenshot. Link to comment Share on other sites More sharing options...
roman999 Posted November 17, 2021 Author Share Posted November 17, 2021 (edited) deleted Edited November 17, 2021 by roman999 no longer applicable Link to comment Share on other sites More sharing options...
OSUblake Posted November 17, 2021 Share Posted November 17, 2021 You are inspecting an element, which has similarly named event handlers, but those aren't the same events as Draggable. You should be inspecting what Draggable returns, i.e. dragger. The event handlers will be in the vars object. 1 Link to comment Share on other sites More sharing options...
roman999 Posted November 17, 2021 Author Share Posted November 17, 2021 18 minutes ago, OSUblake said: You are inspecting an element, which has similarly named event handlers, but those aren't the same events as Draggable. You should be inspecting what Draggable returns, i.e. dragger. The event handlers will be in the vars object. I attached three screen shots: The es6 vars object, as you requested. The js vars object, for comparison. It appears to be identical. The js version of the screenshot posted earlier, showing the onDragStart event of element. It shows a function there. Since GSAP ultimately must set events on dom objects, element in this case, the screenshot I posted earlier may show a problem. Link to comment Share on other sites More sharing options...
roman999 Posted November 17, 2021 Author Share Posted November 17, 2021 When inspecting the HTML of the js version there are event handlers for the list items. In the ts version there are no attached events. I can't post good screenshots because of the quota. Link to comment Share on other sites More sharing options...
OSUblake Posted November 17, 2021 Share Posted November 17, 2021 Are you registering the plugin? If you're having issues, can make a demo CodeSandbox, which allows for imports and TypeScript? 1 Link to comment Share on other sites More sharing options...
roman999 Posted November 18, 2021 Author Share Posted November 18, 2021 14 hours ago, OSUblake said: Are you registering the plugin? If you're having issues, can make a demo CodeSandbox, which allows for imports and TypeScript? I did register the plugin, I neglected to add that line in the code above. I worked on CodeSandbox: https://codesandbox.io/s/little-star-jvkox I don't know if the *.ts file is actually being called or if the sandbox is publicly viewable. The behavior is the same as I see locally, but I had to make some minor adjustments to get it to display the HTML and show the *.ts file without errors. There's still two issues involving this but I think they won't prevent compilation. Contact me through codesandbox and I'll make you an editor if you're willing to explore this more. I suspect a problem exists with gsap's Draggable when used as a module. Link to comment Share on other sites More sharing options...
Cassie Posted November 18, 2021 Share Posted November 18, 2021 Hey @roman999https://codesandbox.io/s/headless-fire-cvbtm?file=/src/index.ts There's no real JS/GSAP issues here that I can see, just some setup errors. The 'src' directory was specified as root in your tsconfig but didn't follow that folder structure. The ts file needed to be actually be called. No need to import from 'dist' with ES Modules. Just import { Draggable } from "gsap/Draggable"; You'd also got rid of the container element and position absolute in the HTML and CSS which were kinda important. All seems to be working now! 2 Link to comment Share on other sites More sharing options...
roman999 Posted November 18, 2021 Author Share Posted November 18, 2021 2 hours ago, Cassie said: Hey @roman999https://codesandbox.io/s/headless-fire-cvbtm?file=/src/index.ts No need to import from 'dist' with ES Modules. Just import { Draggable } from "gsap/Draggable"; Thanks Cassie! I used the dist directory to dispose of this Jest error that occurs when using the import as you showed. Any idea what is going on? /home/kev/control/programming/ts/quiz/node_modules/gsap/Draggable.js:16 import { getGlobalMatrix, Matrix2D } from "./utils/matrix.js"; ^^^^^^ SyntaxError: Cannot use import statement outside a module 5 | import {sort} from '../jsonOut'; 6 | import {gsap} from 'gsap'; > 7 | import {Draggable} from "gsap/Draggable"; | ^ 8 | export class Sort implements Exercise { 9 | inst=""; 10 | ans=[]; at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1350:14) at Object.<anonymous> (src/ts/main/exercise/sort.ts:7:1) Link to comment Share on other sites More sharing options...
Cassie Posted November 18, 2021 Share Posted November 18, 2021 Probably something with your build or setup - If whatever you're using doesn't support ES Modules then carry on using the UMD files in dist then! Link to comment Share on other sites More sharing options...
roman999 Posted November 18, 2021 Author Share Posted November 18, 2021 Well I'm not sure what to do. I copied the css and ts over but the event listeners still are not attaching. Maybe I need to create a new codesandbox containing the minimum code necessary to demonstrate the problem yet exhibiting my configuration. Link to comment Share on other sites More sharing options...
Cassie Posted November 18, 2021 Share Posted November 18, 2021 Really not sure what you mean by 'the event listeners are not attaching' Are you sure the JS is actually running? Can you console log through and work out where it's going wrong? Link to comment Share on other sites More sharing options...
Cassie Posted November 18, 2021 Share Posted November 18, 2021 If you can make a more minimal demo showing the issue we'll be happy to take a look. Sorry this isn't easier to figure out! Link to comment Share on other sites More sharing options...
roman999 Posted November 18, 2021 Author Share Posted November 18, 2021 56 minutes ago, Cassie said: Really not sure what you mean by 'the event listeners are not attaching' Are you sure the JS is actually running? Can you console log through and work out where it's going wrong? You can see what I mean in the screenshots I posted earlier in this thread. When I ran the sorter outside of my code, the ondragstart method on one of the list-items shows a proper value. When run inside my code, it shows _emptyFunc. If the sort code wasn't running, ondragstart would be null but I confirmed the code is running via browser Developer Tools's debugger. Draggable doesn't seem to be setting the list-itemsevent handlers properly in a certain context but I'm not sure what context to change. Hopefully a minimal demo will clarify things but it's going to be some work. Cassie, you're being a great help, I really appreciate it. Link to comment Share on other sites More sharing options...
Cassie Posted November 18, 2021 Share Posted November 18, 2021 I'm afraid I don't understand how to debug the way you are - I still just use good old trusty console logs so the screenshots don't mean much to me. 😂 Your JS wasn't running at all in the example you popped over - I added a script tag to your HTML and also moved your files into a src folder. So maybe that's the issue. I'll try to help when you have a demo though. We'll get to the bottom of it! Link to comment Share on other sites More sharing options...
OSUblake Posted November 18, 2021 Share Posted November 18, 2021 Yeah, I'm totally confused here as the demo Cassie provided works as expected. And again, you shouldn't be inspecting the element for events. Draggable's onDragStart is the not the same as the native one. GSAP overrides ondragstart with an empty function because we don't want to initiate native drag behavior. https://developer.mozilla.org/en-US/docs/Web/API/Document/dragstart_event 1 Link to comment Share on other sites More sharing options...
Solution roman999 Posted November 23, 2021 Author Solution Share Posted November 23, 2021 The problem was a beginner's mistake I made to add another widget: document.body.innerHTML = document.body.innerHTML + ...; That apparently reset gsap's event handling code. Adding the proper way, document.createElement(...) with document.body.append(...) made the problem disappear. I still don't understand why the DOM DnD event handlers were added in particular situations instead of emptyFunc() (which I think cannot be seen by logging since the DOM lacks the necessary tooling) but my immediate problem is resolved. @OSUblake and @Cassie, I appreciate your help. 2 Link to comment Share on other sites More sharing options...
Cassie Posted November 23, 2021 Share Posted November 23, 2021 I hugely recommend popping some console logs in in future to check the JS is running and what it's returning. It's much more effective for JS debugging than poking around in the DOM! Glad you got it sorted though! 🥳 1 Link to comment Share on other sites More sharing options...
OSUblake Posted November 23, 2021 Share Posted November 23, 2021 1 hour ago, roman999 said: The problem was a beginner's mistake I made to add another widget: document.body.innerHTML = document.body.innerHTML + ...; That apparently reset gsap's event handling code. Oh yeah. Using innerHTML will create a brand new set elements, so all references to those elements will be lost. Instead of using innerHTML, you can use insertAdjacentHTML for the same effect, but it won't create new elements. https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML 2 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now