about 5 years ago Syntax Podcast
Hasty Treat - JavaScript's Drag and Drop API
- 04:45 Discussing the drag and drop API in JavaScript
- 06:47 Drag and drop allows communication between web apps
- 09:17 Drag events allow you to store data about the drag
- 10:35 Can store metadata like what app data is coming from
- 13:19 Can customize the drag image shown
- 15:29 Have to handle drag UI yourself
- 18:02 Security concerns around reading drag data
- 20:27 Browser APIs have limitations to prevent abuse
- 23:34 Must handle CSS classes for drag states yourself
- 24:55 Implementing accessibility is easier than drag and drop
- 26:25 Google's Transmat library wraps the data transfer API
Transcript
Scott Tolinski
As always, this is Wes. Hey, mister Dragon himself.
Scott Tolinski
JavaScript's a drag and drop API. Now this is something that Wes has done quite a bit of a deep dive into very recently, and I myself
Wes Bos
only 40% of High schools in the US offer, Pseudo selector. I was gonna say, is there any sort of, like, attributes that you could use or anything? There was one that I found, but it was like a Moz prefix, and I couldn't find any reference To a standard for that, so what I ended up doing is just adding and removing classes of,
Wes Bos
are piloting computer science with code dot org when you buy a domain name. So I I think this is really cool because I started learning to code when I was in grade school, So by default, you don't do anything because it does what what you're Events that happen. Just like you're used to listen for a key op or a, is that as soon as you drag and drop As soon as you drag an element, Man. Yeah. We should do a a a show on that explaining how both speech to text and text to speech work in the browser because then it is not accessible at all. So Yeah. And I had, like, a 1000 people being like, wait till you try to make it accessible.
Announcer
Boss, and Scott, El Toro Loco,
Scott Tolinski
CSF. Well, this is a funny story. One time, I got kicked out of a,
Wes Bos
You need a domain name for your upcoming makes them inaccessible this tasty treat. We also are sponsored by .techdomainnames, data transfer API we just we just talked about.
Wes Bos
and they have a Really cool sponsorship today, In spot 6 of 40, press space to drop. And then you just press space. You dropped it, and then it say it'll say done. You've reordered them. And I I was like, man, This is way easier because there's with drag and drop, there's 8 different events. It's so fussy. It depends on the what the CSS is doing.
Scott Tolinski
That's rough. Yep. Oh, man. Well, let's talk about dragging and dropping. But before we do so, let's take some time to talk about our sponsors and thank them. One of my sponsors today is Sentry at Sentry dot I o. They have for you today a coupon code of tasty treat, all lowercase, all one word, where you'll get 2 months for free of Sentry. Now this is a service that we've been using for a very long time. And one of the best features that we use in it is the performance tracking metrics so that we can see very clearly how each that we've done has positively into Versus Code, those are 2 web apps that should be able to talk to each other because they both know this this base API. A good example might be the, like, if you were let's say you have an application like Figma or something. Right? You're dragging an image onto it. It drops it on your canvas,
Scott Tolinski
penalize me for being goofy?
Wes Bos
computer science and on and worldwide, only 73% saying. But if you want it to be like, if you wanna show it moving around, what I ended up doing is just removing the the ghost image entirely, And I never had any classes on that type of thing. And, apparently, the drag event, which are is kinda interesting. So you can kinda think of it as, like, a a mini database So what you can do is you can store the ID of the item that you're dragging you added some, like, the important thing is is that you get this thing called a data transfer API.
Wes Bos
to July 5, 2021. So visit of the actual element. Because then Then it is literally the element that is moving and not the the ghost image. Right. It kinda stinks that you gotta do that yourself.
Announcer
Tolinski.
Announcer
Monday. Monday. Monday.
Scott Tolinski
built into JavaScript. My name is Scott Talinski. I'm a developer for Denver, Colorado. And with me,
Wes Bos
of the proceeds are doing nothing at all. So there's not a lot of coding going on in your element, speech text to speech. There's a whole set of speech to text APIs. There's Drag and drop copy paste it. But, like, every single area that you get into, it's not something you use every day. But once you get into it, you're like, oh my gosh.
Scott Tolinski
misery scores? And since, you're getting this this performance tracking tools, and every time that anybody loads any of your pages, You're getting a whole lot of data to work with. And I'm a data head. I like having a lot of data. So try out Century's new performance tracking tools at century.iocouponcodastytree,
Scott Tolinski
So let's get into drop to the ground and hit hit some dance moves, but I also drop things pretty regularly because I'm clumsy.
Announcer
soft skill, web development, the hastiest, the craziest, the tastiest TS, web development treats coming in hot. Here is Wes, Barracuda,
Scott Tolinski
which are the slowest and which are the fastest routes on our site, Which ones have the highest and lowest user 11 years. So, There you go. Yeah.
Scott Tolinski
Sick.
Wes Bos
because they're doing a little bit of a collaboration links Then it comes time to accept a drop.
Wes Bos
our favorite sponsor that does what they do in the name of the company.
Scott Tolinski
CSF. Welcome to syntax on this Monday. Hasty treat. We're gonna be talking about
Scott Tolinski
Mister Dragon? Is that your new nickname? Are you mister Dragon? We should have, like, a comedy duo,
Scott Tolinski
I get kicked out of a club for being drunk when I had not had And he think the drink because I dropped my license when the guy asked for it. He's like, you, you're out of here. You're hammered. And I was like, I'm totally sober, man. He's like, Nope. I've been watching you. I'm like, I'm just clumsy. I'm just goofy. Like, you gotta you're gonna
Announcer
Open wide dev fans. Get ready to stuff your face with JavaScript, CSS, node modules, barbecue tips, get workflows, breakdancing,
Scott Tolinski
impacted our page loading times, and we can see definitively
Wes Bos
f. Forward slash syntax.
Wes Bos
according to .techandco.org,
Browser APIs have limitations to prevent abuse
Wes Bos
at this point because It just works from 1 window to another, which is Really, really nice. Mhmm.
Wes Bos
Other things is with all of these things. These events, they do bubble up just like Most events in JavaScript, meaning that I was, like, listening for the get the data That's, Build a fully fleshed out version of this, then probably at that point, you you reach for a library. You kinda get the best of both worlds. You actually understand What's going on under the hood? But then you've also benefited from and that was the point where I was like, okay. So, like, 60 lines of code to, like, make a fun little demo, Their API is a variable on both ends, but you should be able to pass the actual image itself from one app to another, and we'll talk about how to do that in just a second.
Scott Tolinski
It's important to understand how this stuff works, but it's maybe not as important to build it yourself.
Wes Bos
Even with those and that's not even using this API. That's just straight up CSS and JavaScript. Right? I think that's, like, not necessarily a bad thing either. Is that, like, Go ahead and build a very proof proof of concept yourself so you sorta understand how this stuff works. And then if you need to Man, There's so many cool APIs.
Scott Tolinski
understanding the whys. So that way, when you do hit a you are using a library, whether it is, like, Passport order something, or you are using these things, you might understand a little bit more of some of the pitfalls that that you know, air an error pops up, you all of a sudden know Kinda what to do rather than just say, well, screw it. I guess I'm toast.
Scott Tolinski
that's the web. Right? That's, the web in a a nutshell. That's the web in general. Yep. So shortcomings,
Wes Bos
Hover styles, all that is up to you to add or remove classes there. I did find 1 like I mean, yeah. You do kinda. It is. Yeah. It's nuts because, like,
Scott Tolinski
And so, like, when we you you teach that stuff Or you think about learning something like auth, it's it's more or less
Scott Tolinski
and it's funny just even with that, so that you would, like, try to, you know, knock you off your game a little bit. Here. Do this move. And then, like, I was like, I can't believe I built this, and it's just baked into the browser. It's way easier than you'd ever expect.
Wes Bos
and it just started flipping out because it's you're you're you're triggering drag out events all the time.
Wes Bos
Lots of if Statements, lots of, like, little gotchas there, benefit here is that because it's a standard,
Scott Tolinski
how many caveats you have to place on top of Yes. This works in this browser in this way, but if you want touch support, then we have to start thinking about touch events. If you want this, you gotta start thinking about this. It's like, yes. I can show you in a few videos how you can start this process, but, you you know, there's so much more to it if you want this thing to be fully compatible for a full archive of all of our shows. And don't forget to subscribe in your podcast player or Drop a review if you like this show.
Scott Tolinski
somebody else figuring out this other 6 a thousand lines of code. I feel the same way about that with a lot of stuff, whether that is, like, even, like, auth. Right? Yeah. We we have 2 courses on auth, and that to me is like, Yes.
Implementing accessibility is easier than drag and drop
Wes Bos
the state where now you're listening for up and down arrows. And then every single time you press up and down, it just moves the item up and down, And then you you update the ARIA dash live paragraph tag, and it will read to the I I opened it up on Safari. It worked great. It say, like, item
Wes Bos
are you currently reordering, wazoo. So 60 lines of code to make drag and drop work. And then All of a sudden, I added a couple nested elements inside.
Wes Bos
Press space to reenter, and then you hit space. And then you entered a you select 4 emails. You click it. You hold down shift, and you drag them into a tag in the sidebar.
Wes Bos
And with the keyboard stuff, it was simply just like, dragged currently.
Wes Bos
pizza and animate.
Wes Bos
and do you want to go up or down? adds it to your project, those types of things too. Totally. Like, That that's a really good a really good, example. If you've got an image that lives in Notion and you wanna add that to Figma, So you can't store, like like, a A file in there. But if you need to store the reference to something, like the idea of an element that is being dragged, you can stick in the key and parse it out. Bit of a hack, but That's the thing with browser APIs. It's like, we have this amazing browser API, So you know how I told you that you can use the data transfer enters into the drop zone
Wes Bos
And it says it's for seamless cross web interactions.
Can store metadata like what app data is coming from
Wes Bos
Dragged over and drag enter. You can only tell when something is being dragged into, over, and inside of it. So if you want to be able to reference the element that is currently being dragged, there is a event dot data transfer dot get data and dot Set data, and those are the APIs that allow you to get and set the data based on the event. And I thought it was kinda interesting that the event is the carrier of all of this data.
Wes Bos
whether that is a a class, an ID, query selector, security concerns.
Scott Tolinski
Like, maybe, like, what application this is coming from Type of deal? Is that, like, a a use case for this? Yeah. You can set multiple pieces of data. So you could say, all lowercase, all One word. Thank you so much for Sendery for sponsoring
Wes Bos
allow items to be dropped on And I would be dragging, and you'd be drop. Oh, dragging. And we'd be like like slapstick comedy. Yeah. And Scott going around doing tours. Drag and drop. And drop makes sense for me because, I can, drag and drop in the browser is the important thing to to set from the get go Is that it is a set of browser standards
Wes Bos
You can only tell what item is being Peace.
Wes Bos
We have a theme park in Canada called Canada's I was gonna ask about that. Yeah. Canada's Wonderland, and they have, like, this, like The drop zone. The drop zone, which is like a tower that just like, drag. What I did is I took the event type of those 8 events that we said, and I just added and removed them as they were fired on and off.
Wes Bos
If you take that element event, so you've got a let's call it the drop zone, which all my Canadian friends are gonna be really happy about.
Wes Bos
Or a drag over event. Sorry. And if you want to accept items that are being dropped,
Wes Bos
because of the, Then when you drag each of those elements,
Wes Bos
And then you can say, okay. I'll allow it. You may drop on me, and then you say, event dot prevent default. And that allow that then allows the user to, When they let go of their button, that will then trigger the last event, which is the the drop event. And then when in the key.
Wes Bos
with a dragged element, it will fire a drag enter the index of the element that was being transferred.
Wes Bos
you can Call event dot prevent default, and that will essentially text to it, so it would announce In the drag event of when you start to drag something, you're able to say, okay. We're we're doing a drag right now. Let's stick Some information about the thing that is being dragged so that is not there. Again, another reason, if you're just trying to reorder a list of things, probably go for something that has built in mobile port as well. Yeah. Yeah. Last thing, and then I'll I'll, jump off. I know this is getting long. Google has a library called Transmat,
Scott Tolinski
Yeah. Yeah. And and there's, like, the the default for the draggable. That's like the the default. It's like a little ghosty transparent version of it. Yeah. Yeah. And you can set
Wes Bos
you could set the
Wes Bos
event dot data transfer dot set data, to code.org in the period of May 5, 2021 So as you start to drag and drop,
Security concerns around reading drag data
Scott Tolinski
I'm I've also been using it full time for,
Wes Bos
and here are the limitations because people will abuse it. Yeah.
Wes Bos
of what you're dragging, but not the value.
Scott Tolinski
Where
Wes Bos
API to set data and get data? It basically takes this whole data transfer API you drop, and it's super fun. Mhmm. So let's say you have a drop zone. When somebody project, your side project, your new company that you're starting. You want a .tech domain name, and
Wes Bos
when you are simply dragging over. You can only access the data about from app dot set data, Awesome. Well, thank you so much for tuning in, and we'll catch you on Wednesday. Peace.
Scott Tolinski
They shouldn't be able to read that file. That makes a lot of sense. Hey. Do you ever, do this? I know you use TweetDeck occasionally.
Wes Bos
If you got a couple windows open on your computer So the browser
Scott Tolinski
No. No. One of the one of the things that really bugs me about TweetDeck is when you have any kind of image and and you're doing exactly what you're talking about. You're you're dragging a file in. Maybe TweetDeck's just opened. I find her on top of TweetDeck. TweetDeck starts flipping out about the type of thing that you're dragging from one window to another. You're like, TweetDeck, this is not for you. I have not let go of this. Why why are you trying to parse this image or whatever? Yeah. That that always bugs me about tweet deck, but it's funny because it's they can't access the data, but they can access some things like what it is. Right? Like, Yes. Most likely the extension of the file filename. The MIME type. Yeah. Yeah. Yeah. They can get that. And, all in Firefox, I didn't See that limitation. So you might actually be able to do it in Firefox
Wes Bos
You cannot There's probably that's probably too large to to stick into there. But images, sets of links, you entered into mobile,
Discussing the drag and drop API in JavaScript
Wes Bos
Browser tab to browser tab. And I think that's really the the main drag events, Alright. So you've got these drag events. And when you start to drag in this drag and drop API.
Wes Bos
reorder a bunch of stuff in your application, You probably do wanna reach for an existing library that does this type of thing. But if you need you're building a desktop app or something like that, Then you do probably do need to reach for this JavaScript API because it is the standard, and the different standards can can talk to each other. Right? If you drag to control your mouse, then you have to stick a reference string. So, equals true.
Wes Bos
that allow you to communicate You can just put that in there.
Scott Tolinski
So I'm interested to hear what you have to say about the JavaScript's drag and drop API,
Scott Tolinski
Drag and drop, out of the box version.
Scott Tolinski
Largely something I don't know a whole ton about, to be honest.
Scott Tolinski
Drag and drop has never been super fun. And you know there is Jira drag and drop properties for HTML, but I don't know if you ever use them, but the user experience isn't exactly native feeling. It kinda feels kinda cheap. So I don't typically reach for the HTML
Scott Tolinski
drag and drop. Now this is one of those things that anytime you have to code up a drag and drop, It often feels like a a tremendous pain or you know what? Even with tools like React or other things,
Wes Bos
Between both inside of your own application, inside of your own website, but also from application to application, as well. So you feel you feel you got a sweet domain name, and you feel good about it as well. Thanks so much to .tech for sponsoring.
Can customize the drag image shown
Wes Bos
any way to, people set the drop image to nothing, and then they start it's the same same sort of idea. If you if you copy an image from 1 app and you paste the image into another app, it's the same idea with the data transfer API.
Wes Bos
And then give it access to that, and that's what will show up. So you can literally set it to anything you want, which I thought was pretty nifty. But that is Kind of unfortunate if you were trying to build, like, a draggable, droppable list.
Scott Tolinski
physically
Scott Tolinski
because as I was dragging the element around, I was inserting it into the DOM where I wanted it to be. K. That's what I'm wondering. Yeah. So that's the solution there. The is is that image that ghosting that's happened on the image, is that is that created by the browser's Yeah. Image like, is that opacity that's bit baked into the image, so you would have to
Wes Bos
of the absolutely position or maybe even fixed would be better in that case But you probably wanna reach for a battle tested library I occasionally, I've been using it full time for 10 years. Yeah. I know.
Wes Bos
The position so .tech domain names along with GoDaddy Pro are donating And, event add that to your app. I 1000% That's pretty cool that the money is going towards code.org And you just add a, an HTML attribute called draggable Well, like like, what else would you want it to be? Like, if you and it I opened it up to test it in Chrome, and it didn't work. So the way to get around that is you can you can access the key by itself, it's very hard. And And then you also don't get a lot of the, like, niceties, which is the animation and whatnot. So I don't know if, like, React drag and drop uses the drag and drop API under the hood, But I know that a lot of these animation libraries, they're they don't use drag and drop because if you just wanna, like, reorder a list of things, you probably don't need this API. This is, I think what this is for is for sharing data between apps and and browser tabs and things like that. Yeah. I've done a a handful of, Like, UI based drag and drop stuff, for instance, in our Svelte animation course. It one of the things that we did in that course was build a A draggable action on an element, go.tech From one app to another app, and it makes it I guess it just standardizes it. It makes it really, really simple. I thought I looked at it. It was pretty cool. And it's The data transfer API also works with, copy paste API.
Wes Bos
you you couldn't just toggle change that with CSS. Right? That's a good question. The drop, let me let me look that up real quick. I did not see
Scott Tolinski
or is it always just an image? So by default, it will
Wes Bos
stick that into an image Everything yourself.
Scott Tolinski
You have to set that to be an image that goes, Like, if you're if you're dragging a list Oh, yeah. How do you picture that list item to be a nonimage,
Google's Transmat library wraps the data transfer API
Wes Bos
files, text, HTML Flip animation. In all the React libraries. Yeah. So nice. None of that exists Two different applications can talk to each other and send data between each other by the user drag and dropping, data. So So when you when you drag over an element, into Figma I I don't know if this works. It should because
Wes Bos
Alright. Well, look forward to that. Anything else to add here, or should we drag on, drop out of here? We should drag on and drop out or yeah.
Scott Tolinski
This is a whole thing. It's a lot of fun, and I I had a lot of fun with a lot of the voice stuff too, the speech input. And, you know, I I, like, made an app that would, While I was dancing would, like, tell me a a a random move to try And pretty unfamiliar beyond writing some tools using just, like, Framer Motion, those types of things in JavaScript, and React. So we're gonna be talking all about the drag and drop API
Scott Tolinski
agree.
Scott Tolinski
I Specify that. Yeah. That's sort of where I've always been because I've tried it before. What I find most people were doing
Scott Tolinski
Head Turn over to syntax.fm
Wes Bos
that I was talking about, and it puts a wrapper around that. So you can send It's so much easier to implement that type of stuff than the drag and drop, so I was happy to report that the accessibility.
Wes Bos
There's a whole set of audio APIs. There's a whole set of A of the item I was dragging,
Scott Tolinski
feel like you could have a career just exploring all of the in browser APIs that exist.
Wes Bos
So, drag on the list item, but I put the event listener on the unordered list. Mhmm. Yep. Because that allows you to, first, just have 1 event listener instead of the actual element itself. Yep. And you use the x and the y coordinates of the mouse mouse move event, and you can set that. So as you drag it around, it literally is just moving One thing I I was tweeting about it, and, Etienne from Misiv, And when you buy your domain name, you a 100% of the proceeds is going to go towards code.org. So
Have to handle drag UI yourself
Wes Bos
One thing I ran into is possible of the actual image. You can just use regular text. You can Any type of data that you can imagine. I don't know what the actual limit is. So if you were to drag a video, on the way to another tab, because I had it just worked in it just worked entirely. Because what I was doing is I was simply just storing the ID
Wes Bos
As you drag the thing in the data transfer API as well, You can set the effect allowed.
Wes Bos
that is Probably the hardest part is that you wanna position the thing. You wanna show it. You wanna
Wes Bos
An email and your main missive app open in 2 different windows.
Scott Tolinski
Yeah. I thought I'm way more familiar with, like, the animation aspects of all of this process than I am The actual browser API. So it's really interesting to to hear this. That's what surprised me about it is that there's literally nothing
Wes Bos
So you know when you drag something and you let go of it and it you didn't actually drag it anywhere, it just it it kinda goes back. It goes back to where you dragged it from. There's a there's 4 or 5 different effects that you can set Oh. On the event So that when you drop it when you drop it, does it need to go back to where it was, or should it stay where you are?
Wes Bos
What the cursor does when you're hovering over top of the the thing.
Wes Bos
Like, when you move 1 up, you wanna animate the other one down. Like, that's one thing that It works in would you absolutely positioning before I get into that, Let's just talk about the a couple other things here.
Drag and drop allows communication between web apps
Wes Bos
So I went down the rabbit hole of just trying to make a very basic that thing. So, basically, you say, okay. Someone dragged over me. You can tell what is being dragged over that to whatever you want, and it all it has to be is an image, f. Like an actual image tag. So you could create a canvas element and you accidentally drag your, like, taxes over top of syntax.fm
Wes Bos
you will
Wes Bos
drag start, drag, drag enter, drag exit, drag leave, drag over, and drag end. So There's well, I mean, 1, 2, 3, 4, 5, 6, 7 different great schools, high schools right now, And Code .org is trying to change that with their they've got all kinds of programs and stuff for teachers and stuff for students and and and whatnot, which is really cool because, Like, I'm I'm glad that I learned to code on my own, but I know there's a lot of other people that probably would be really good coders only if they had the chance. So Our sponsor today, .techdomainnames,
Wes Bos
40. And second, So
Wes Bos
unordered list with a bunch of items in it, and I wanted to be able to click and drag And reorder them in what whichever order that they wanted. So the very basic, what you do is you go on to your items that you want to be draggable, and That out of the way, I'll say, like, right away, if you are just trying to just make a ghost image of the actual element itself.
Wes Bos
You don't have to add and remove those event listeners as the list items are being deleted and created, which is sometimes a bit of a pain if you're not using something like React.
Wes Bos
plus there is a drop event. So 8 events in total that you can listen to That all uses it. And it's huge for them to use this API because It works multiple windows. It works multiple apps as I said before. So if you've got 2 versions of if you got, The last thing here is mobile. It is not Supported on
Wes Bos
And that will then make your your element draggable.
Wes Bos
a click event, you can add event listener, And you can listen for About the UI in this API Yeah. Which is a pain because
Must handle CSS classes for drag states yourself
Wes Bos
ARIA dash live specifically, it's not even in Ios Safari. Mhmm. And that's just because this again, this is a desktop. Mhmm. This is a desktop API, Totally.
Wes Bos
it was literally it was tabbed to the item that you want, so you add a tab index to each of the items. And then whenever you added a bit of margin to my draggable items, be able to listen for a whole bunch of different drag and drop Edge cases out the link from Notion Yeah. So I went down the rabbit hole of trying to implement my own drag and drop f. With just vanilla JavaScript because, like Scott says, there is an API in the browser that allows you to do it, but you have to code Misiv I kinda do that. Yeah.
Wes Bos
Unless you're using the, like, mouse keys, which you can use on OSX
Wes Bos
Items. 40 items. Press space to reorder. And then every time you tab to 1, it would say item 2 of 42.
Wes Bos
And I was like, alright. I'll try it. And it was A 100 times easier than actually implementing the drag and drop API because The drag and drop once the user has let go of the key the the mouse and dropped it. And the reason behind that is because
Wes Bos
by default because And then the the big one, which is, like, Accessibility. So by default, just making random things draggable
Drag events allow you to store data about the drag
Wes Bos
about what you are dragging you either want it to be a ghost image, you want it to be the element itself, Or you're talking about having to position the thing itself. Yeah. Yeah. I'm just saying, like, it'd be great if, when you dragged a an element, it was It would figure it out for you, the DOM element, the type of things that, like, like, React library would do for you in that regard. Right? Yeah. I I've got a list of, like, the shortcomings here because it does it's so much work to just use this Yeah. Yeah. By itself. You know, like, there's there's no magic in this API at all. It's a very low level set of APIs.
Wes Bos
allows you to stick some information
Wes Bos
into it. So you could take the image it's up to you to do everything. That's CSS classes is dragging.
Wes Bos
and then it has a get data and set data API. So on all of your drag events, When you start dragging that sucker from Notion It's amazing that you as a developer can just
Wes Bos
In base 64, encode the image and put it in there. You can set MIME types and pass data through the drag and drop API
Wes Bos
into And then you can also specify
Wes Bos
Those things can all be encoded and stuck into the data transfer API,
Scott Tolinski
It's interesting. Do you think that maybe could it, like, care?