The math was a little difficult for me to understand at first, so I changed the formula a little. Since the y-position increases as you drag the mouse down, I set the offset = y - (box.top + box.height / 2). Since the top of the box's y-coordinate is given to us, all we need to do is add half of the box's height to it and it finds the middle for us. I understand most people might have understood the original equation, but I just wanted to add this here in case anyone was confused.
That's because it's needlessly complicated for such a simple problem. just get the element your hovering over using document.elementFromPoint(e.clientX, e.clientY) then check if your mouse is in the upper or lower half of the elements rect. Its the only part of an otherwise good tutorial that just seemed to be there for the sake of looking fancy
@@RobertFletcherOBE i have tried this now, but the problem is when you drag an element and your poinyer is between 2 elements, then it defaults to last in the list, until you go over an element. So it looks kind of bad
This is the tutorial I've been waiting for, this is apparently the best drag-and-drop vanilla js tutorial for sure. I have learned a lot. for people who don't want to go deep on technical part, there are a few libraries that simplify the work. But understand how drag and drop works under the hood make developing work more flexible and free. But for people who just want to quickly get started and apply drag-and-drop into their projects then 3rd-party libraries do the work. Anyhow, thank you Mr. Kyle Cook for this tutorial, you seem to know what everybody needs and wants, impressive, amazing and awesome !!!
I've learned so much more from your tutorials. I would recommend for someone like me that is learning Javascript. I've been thru so many tutorials in the last few months but it makes more sense when I watch your videos. Thanks!!!
Hey Online Tutorials, were you able to make a video tutorial with what you've learned here? As a beginner, I would love to see how other creators are teaching this concept from their own perspectives...
We can also listen for drag events globally with event delegation since the only thing that can move around is the tags. document.addEventListener('dragstart', (e) => { e.target.classList.add('dragging'); }) document.addEventListener('dragend', (e) => { e.target.classList.remove('dragging'); })
Now that is a high quality, no nonsense video! I thought vanilla JS was just a pain but you presented this incredibly well and made is simple to follow! Love it.
Man, your videos are so inspiring. My server side is still classic ASP and I should upgrade to some new language, but your client-side applications are still usable in my situation, and I will definitely implement some of the solutions you provide. I've always managed to solve problems by just using Google and find what's available on the web, but what you teach is complete and solid. Thank you so much for all the effort, although I know it's fun to make. Keep up the good work!
I think the main key of your videos is that you don't make a whole pretty and solid toturial to be copy pasted from, I literally wanted to learn that API's basics and that exactly what I got with a little be more tips like getting the rect info with that clientBounding function I'm going library-less approach on all of my personal projects as much as possible and wanted to implement this with my own react custom hook for my needs. Much thanks!!!
I don't think I've ever commented on your channel Kyle. Just wanted to say, YOU ARE THE MAN! Love your content. It's all over my head. Exactly what I need!
I'm not exaggerating but you have the best channel! I watched so many javascript videos but most of them don't go into clear details just like you do.. THANK YOU
Brilliant, just what I needed. Your explanation and examples were clear and easy to understand. I didn't just learn what code to copy, learned how and why it works. Thank you.
Beautifully explained and a far more versatile, functional and more succinct code than some of the other tutorials out there. Excellent stuff. Glad I found this channel and really grateful for you sharing on Git.👍
Thanks for this tutorial. I watched another that also used other events and now I will have to see why the differences. When I incorporate this in my electron/node project, then I will have learned. Thank you so much.
First off great tutorial. I like your use of reduce. My brains are getting old and like others, I struggled a bit with the maths. Drawing it out, I came up with (box.top + box.height / 2) - y for my offset. If the current y point is above the midpoint it is a positive value, and below a negative value. Instead of reduce I used Array.find and a predicate of offset >= 0. This returns the first draggable with a mid point below the current y position. Easy coming up with this, when someone else has done all the hard work :)
I enjoyed your fast paced tutorial, and I couldn't wait to use arrow-functions as event listeners. DON'T DO THIS! The 'this' parameter is handled differently within arrow functions than simple anonymous functions (which as a noob, took me a while to figure out). You avoided this problem by knowing the event target was the only one with the class 'dragging' and you grab it directly with querySelector(), but a more generic handler might want to use 'this', which in an arrow function would have to be evt.target instead.
This is all very true, and well worth noting. One thing I would say, is that the fact that arrow-functions retain the scope of `this` to be that of the outer scope (rather than the same as the scope of the calling function), is its greatest strength. The old way to get around this was to use the `bind()` function to inform the event callback of what you want `this` to represent within said function. This is a pain in the arse after a while (especially when you're nesting functions within functions, with callbacks and recursion; it quickly becomes a mess of what `this` refers to), and arrow functions were introduced to JavaScript to make everything much clearer (arrow functions also have some awesome shorthand properties, that can make your code much more concise, and therefore quicker to write). This is most noticeable when you're following OO (Object-Oriented) design principles, and have all of these events contained within a class, where you might want to use those instance methods within the event callback, just like you would anywhere else within the class. I think wrapping your head around scopes and sync/async are the two major hurdles when transitioning from beginner JavaScript to intermediate JavaScript, but once you know them inside and out, your programming (both writing/coding and conceptualising) will continue to improve in leaps and bounds!
Really amazingly well explained and easy to follow, will definitely be using this in a project at work soon and i was DAUNTING it, thinking it would be super complex/rely on a framework I'm not familiar with but you really broke it down super easily. Can't wait to play with and maybe add x coord too! Thanks again.
I did it by easiest way, my code is complete with IE 6 browser. I used (insertAdjacentElement) and dragenter, dragleave, dragstart, dragend events with if() statement.
Hey Kyle. I'd love a video going over conditional drag and drop. My use case is that I want to make a board game where you can drag cards wherever but when your card is dragged near a certain spot it should snap into place. I'm currently just researching ways of doing that and got here. (Actually just typing this out gave me an idea lol)
Don't know if someone already wrote it but be careful with "drop" event. You will need to prevent default in "dragover" event at least or also in "dragenter". Read some articles about problems of drag api in html 5 Also thank for a video, very accessible narrative
Amazing tutorial, learnt loads about reduce after confusingly working out ever bit of code. Just a note, if you use the insertbefore function you don't have to check if the element is null, as it will automatically append to the end of the parent container if the element is null. Great video though! Thanks.
In this code getDragAfterElement() returns undefined instead of null, so I don't think this code is strictly correct. Because insertBefore() must pass Node or null. > Node.insertBefore() - Web APIs | MDN > developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore > Note: referenceNode is not an optional parameter. You must explicitly pass a Node or null. Failing to provide it or passing invalid values may behave differently in different browser versions. This code is comparing afterElement == null instead of afterElement === null, so it just happens to work correctly. If you want to uncheck whether the element is null, the argument to reduce () should be {offset: Number.NEGATIVE_INFINITY, element: null}.
Really nice video. Allowed me to implement drag/drop in my situation in 15mins. I optimized it by caching the element being dragged and draggables at dragstart so they are not recalculated every dragover event (which happens a lot). I also get the draggables with querySelectorAll('[draggable="true"]) instead of a new class.
Do any math geniuses / smart people know how to change the formula to make it such that - when you click and drag an item, to be able to still move it if you are hovering over anywhere over the full height of the next element, opposed to the top 50% of the element?
Darn. I did a google search for doing this with web components and your video came up. I got very excited when I saw this was one of your videos. I like the pacing, quality and content. Sadly, I'm bummed out because I'm still trying to figure out the nuances of doing this with custom web components. Some detail continues to elude me.
This is great, thank you! Have you done something similar but for a TreeView? Like a serious of nested and ? I am working on building now with my base start using your video but thought I would ask if you already did this. Basically I am building a 'favorites' folder structure with drag and drop.
I implemented a project with similar approach with JavaScript and .NET (in the back end to preserve div’s position). The only difference in my project was that I allowed the div to be placed anywhere on the screen.
Vanilla Javascript looks very easy, compared to the React DnD example (was a very nested -> crazy structure). Can one use the JS code in React pages as well ?
great video. For new learners like me, it would help if you mention which words are built in to Javascript... (ex: closest/ offset/ y) Thanks for everything m8!
Brilliant mate! Thank you very much! Clever stuff. Better than the React libraries I tried and a real feather in the cap for my projects moving forward. Thank You
This is brilliant and EXACTLY what I need for a project I am working on. Thank you very much. Question (if I may): Is there anyway to have the items COPY into the new field, not actually move? Again, Thank you for this tutorial.
In the end Kyle said, and that's all there is to creating this "SIMPLE"...
LOL
Haha
The math was a little difficult for me to understand at first, so I changed the formula a little.
Since the y-position increases as you drag the mouse down, I set the offset = y - (box.top + box.height / 2). Since the top of the box's y-coordinate is given to us, all we need to do is add half of the box's height to it and it finds the middle for us. I understand most people might have understood the original equation, but I just wanted to add this here in case anyone was confused.
the formula is eventually the same, but your explanation is more intuitive. Thanks a lot!
That's because it's needlessly complicated for such a simple problem. just get the element your hovering over using document.elementFromPoint(e.clientX, e.clientY) then check if your mouse is in the upper or lower half of the elements rect. Its the only part of an otherwise good tutorial that just seemed to be there for the sake of looking fancy
@@RobertFletcherOBE I've been doing HTML for 2 years, and its first time I hear about this function :D This makes lots of thing way easier. Thanks!.
@@RobertFletcherOBE i have tried this now, but the problem is when you drag an element and your poinyer is between 2 elements, then it defaults to last in the list, until you go over an element. So it looks kind of bad
@@AndrewTSq this is not HTML though :)
This is the tutorial I've been waiting for, this is apparently the best drag-and-drop vanilla js tutorial for sure. I have learned a lot. for people who don't want to go deep on technical part, there are a few libraries that simplify the work. But understand how drag and drop works under the hood make developing work more flexible and free. But for people who just want to quickly get started and apply drag-and-drop into their projects then 3rd-party libraries do the work. Anyhow, thank you Mr. Kyle Cook for this tutorial, you seem to know what everybody needs and wants, impressive, amazing and awesome !!!
what libaries can you use for drag and drop?
It's necessary to understand what goes on under the hood if you want to know how it works and be able to customize it further.
Nice tutorial, but it can't scale easily
I've learned so much more from your tutorials. I would recommend for someone like me that is learning Javascript. I've been thru so many tutorials in the last few months but it makes more sense when I watch your videos. Thanks!!!
Nice...I need something like this for my next video.....Thanks bro...
your videos are really awesome...Keep it up
Wow , Best tutorial teacher
@Online Tutorials
Nice tutorials you're doing
Hey Online Tutorials, were you able to make a video tutorial with what you've learned here? As a beginner, I would love to see how other creators are teaching this concept from their own perspectives...
@@codingwithkenny6492 hi kenny!
We can also listen for drag events globally with event delegation since the only thing that can move around is the tags.
document.addEventListener('dragstart', (e) => {
e.target.classList.add('dragging');
})
document.addEventListener('dragend', (e) => {
e.target.classList.remove('dragging');
})
you are a very smart programmer, i hope to be like you someday
Now that is a high quality, no nonsense video! I thought vanilla JS was just a pain but you presented this incredibly well and made is simple to follow! Love it.
Man, your videos are so inspiring. My server side is still classic ASP and I should upgrade to some new language, but your client-side applications are still usable in my situation, and I will definitely implement some of the solutions you provide. I've always managed to solve problems by just using Google and find what's available on the web, but what you teach is complete and solid. Thank you so much for all the effort, although I know it's fun to make. Keep up the good work!
I think the main key of your videos is that you don't make a whole pretty and solid toturial to be copy pasted from, I literally wanted to learn that API's basics and that exactly what I got with a little be more tips like getting the rect info with that clientBounding function
I'm going library-less approach on all of my personal projects as much as possible and wanted to implement this with my own react custom hook for my needs.
Much thanks!!!
This! I'm tired of seeing UA-cam videos where the developer spins up react app to do a simple demo. I'm also using as little library as possible.
Damn brother, the way you verbalize as you go, even though you're watching on second screen a finished product, is still amazing.
That's the thing I was requesting long long time ago, thank You, good job!
I don't think I've ever commented on your channel Kyle. Just wanted to say, YOU ARE THE MAN! Love your content. It's all over my head. Exactly what I need!
I'm not exaggerating but you have the best channel! I watched so many javascript videos but most of them don't go into clear details just like you do.. THANK YOU
Brilliant, just what I needed. Your explanation and examples were clear and easy to understand. I didn't just learn what code to copy, learned how and why it works. Thank you.
Amazingly simplified explanation! Your channel is now officially my number one go-to for vanilla JavaScript tutorials.
I was currently working on my own version of trello and this is a great help.
Thank you so much.
Everyone salute for him!
what happened to ur trello project? still working or dropped?
@@meerule I lost motivation. I also gotta do a lot besides this one. So I hope I will make this someday
This man knows, what he's doing.
Love those explaining videos.
Thanks! 😎
I`ve put some of my time on C# for the backend, and now I`m strugling with the front-end. Thanks for the video.
holy moly this is a perfect tutorial. Now I need to figure out how to post the index of each element so as to change their priority level in my DB :)
i think you can make a column in the db that specify the priority level
Beautifully explained and a far more versatile, functional and more succinct code than some of the other tutorials out there. Excellent stuff. Glad I found this channel and really grateful for you sharing on Git.👍
im in internship and you just saved my life. You are a true hero
Thank you so much! I've been trying to get my drag and drop to work for hours and this video showed me how.
Been trying to set up drag and drop in my angular app. Using the offset for determining placement was exactly the hint I was looking for, thanks.
Thanks for this tutorial. I watched another that also used other events and now I will have to see why the differences. When I incorporate this in my electron/node project, then I will have learned. Thank you so much.
First off great tutorial. I like your use of reduce.
My brains are getting old and like others, I struggled a bit with the maths.
Drawing it out, I came up with (box.top + box.height / 2) - y for my offset. If the current y point is above the midpoint it is a positive value, and below a negative value.
Instead of reduce I used Array.find and a predicate of offset >= 0. This returns the first draggable with a mid point below the current y position.
Easy coming up with this, when someone else has done all the hard work :)
I used slightly different naming
return draggables.find((draggable) => {
const { top, height } = draggable.getBoundingClientRect()
const middle = top + height / 2
const offset = middle - currentY
return offset >= 0
})
You explain things in a simple and clear way. Thank you!
I enjoyed your fast paced tutorial, and I couldn't wait to use arrow-functions as event listeners. DON'T DO THIS! The 'this' parameter is handled differently within arrow functions than simple anonymous functions (which as a noob, took me a while to figure out). You avoided this problem by knowing the event target was the only one with the class 'dragging' and you grab it directly with querySelector(), but a more generic handler might want to use 'this', which in an arrow function would have to be evt.target instead.
This is all very true, and well worth noting. One thing I would say, is that the fact that arrow-functions retain the scope of `this` to be that of the outer scope (rather than the same as the scope of the calling function), is its greatest strength.
The old way to get around this was to use the `bind()` function to inform the event callback of what you want `this` to represent within said function. This is a pain in the arse after a while (especially when you're nesting functions within functions, with callbacks and recursion; it quickly becomes a mess of what `this` refers to), and arrow functions were introduced to JavaScript to make everything much clearer (arrow functions also have some awesome shorthand properties, that can make your code much more concise, and therefore quicker to write).
This is most noticeable when you're following OO (Object-Oriented) design principles, and have all of these events contained within a class, where you might want to use those instance methods within the event callback, just like you would anywhere else within the class.
I think wrapping your head around scopes and sync/async are the two major hurdles when transitioning from beginner JavaScript to intermediate JavaScript, but once you know them inside and out, your programming (both writing/coding and conceptualising) will continue to improve in leaps and bounds!
Just don't use 'this' . e.target or e.currentTarget do the same thing
My favorite moment in this video is 15:42 .........Man that was very straight no stop...............................Great Content.
This video really helped me out with a feature I was trying to add to a senior CS university project, so thank you very much!
Man, thats 22 minutes just salved my life! Thank you so much!
I had to watch it twice but I finally understood it.
Thank you! It was very complicated for me, but you explained it excellently!
Starting to follow your channel.
Really amazingly well explained and easy to follow, will definitely be using this in a project at work soon and i was DAUNTING it, thinking it would be super complex/rely on a framework I'm not familiar with but you really broke it down super easily. Can't wait to play with and maybe add x coord too! Thanks again.
This got randomly recommended to me and I need exactly this later for my current project. Perfect!
thank you Kyle, great video, helped me finish a task. 😇
Your videos helped me become a great developer, without going to school. I wanted to ask if you could do some more web security videos! Thank you!
I did it by easiest way, my code is complete with IE 6 browser.
I used (insertAdjacentElement) and dragenter, dragleave, dragstart, dragend events with if() statement.
Kyle you are completely blowing our minds....
Thank you so much for this tutorials. I have learned so much from you. You gave me the inspiration to learn web development.
me too !!!
Hey Kyle. I'd love a video going over conditional drag and drop. My use case is that I want to make a board game where you can drag cards wherever but when your card is dragged near a certain spot it should snap into place. I'm currently just researching ways of doing that and got here. (Actually just typing this out gave me an idea lol)
check ClintX and clientY of your cursor. If it is within the coordinates of certain area, make it snap
This was just awesome. Great work Kyle!
That was professional. Very well and clearly explained, Thank you indeed ,
Thank you, Kyle for the video.
This is an awesome tutorial. You have explained really well. It was very easy to implement it in my code with a slight variation.
This is the only tutorial of yours that i find hard for me
Super helpful. Man, you are awesome, I will watch other videos for sure
Awesome tutorial. I wanted to know how to extend this to 2d layout of draggables where we can't just use y coordinate
Don't know if someone already wrote it but be careful with "drop" event. You will need to prevent default in "dragover" event at least or also in "dragenter". Read some articles about problems of drag api in html 5
Also thank for a video, very accessible narrative
Best drag and drop video
Outstanding tutorial as always, Kyle. I don't know what I'd do without you!
Such a great video! Thank you!!
Your job truly is simplifying the web 👌🏾
You are a literal GOAT
Magic of drag and drop revealed with simple steps
Amazing tutorial, learnt loads about reduce after confusingly working out ever bit of code. Just a note, if you use the insertbefore function you don't have to check if the element is null, as it will automatically append to the end of the parent container if the element is null. Great video though! Thanks.
In this code getDragAfterElement() returns undefined instead of null, so I don't think this code is strictly correct. Because insertBefore() must pass Node or null.
> Node.insertBefore() - Web APIs | MDN
> developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore
> Note: referenceNode is not an optional parameter. You must explicitly pass a Node or null. Failing to provide it or passing invalid values may behave differently in different browser versions.
This code is comparing afterElement == null instead of afterElement === null, so it just happens to work correctly. If you want to uncheck whether the element is null, the argument to reduce () should be {offset: Number.NEGATIVE_INFINITY, element: null}.
Just what I was looking for. Great tutorial
Did you try it, has it succeeded?
This helped out with my project, thanks so much!
Wow due you figured this out on your own? I wouldn't even know where to start!
Thank you a thousand times :)
Thank you so much... Very useful, I applied an addapted version to my project. Very well explained, definitely I will watch more of your videos.
Brooo, You are the best and Beast at the same time
This was really helpful. Thanks Kyle.
Great tutorial. I Always learn new things when I watch your tutorial.
Love your work, I can honestly say I learn a lot from you
Awesome explanation. Exactly what I wanted to learn. Thanks a lot!
Quite simply -- YOU ROCK! Great content. Even better presentation. Thanks for making such an awesome video.
Really nice video. Allowed me to implement drag/drop in my situation in 15mins. I optimized it by caching the element being dragged and draggables at dragstart so they are not recalculated every dragover event (which happens a lot). I also get the draggables with querySelectorAll('[draggable="true"]) instead of a new class.
Great! This helps me so much with my study. You do a wonderful job! :)
Perfect tutorial. Big thanks! Just what I needed.
Great video, man! Really loved it!
you saved my life brother, great content!
This dude is a beast!!!
Do any math geniuses / smart people know how to change the formula to make it such that - when you click and drag an item, to be able to still move it if you are hovering over anywhere over the full height of the next element, opposed to the top 50% of the element?
Darn. I did a google search for doing this with web components and your video came up. I got very excited when I saw this was one of your videos. I like the pacing, quality and content. Sadly, I'm bummed out because I'm still trying to figure out the nuances of doing this with custom web components. Some detail continues to elude me.
Such a cool effect and you make it look easy!
Brilliant video man !!
Thank you for sharing
This tutorial was wonderful, please keep making these.
Very Helpful bro
🙂
This is great, thank you! Have you done something similar but for a TreeView? Like a serious of nested and ? I am working on building now with my base start using your video but thought I would ask if you already did this. Basically I am building a 'favorites' folder structure with drag and drop.
Thanks very simple explanation you saved my day
Amazing tutorial. Like always, learned a lot. Thanks a lot Kyle !
I have an idea...don't think it'll be simple, but it should be doable with your help!! thanks for the video!!
Save my Day bro thx may God bless yu
Thanks. That's awesome. A bit complicated for me but I'll get there. A very well explained tutorial.
Thank you for help may Allah protect you and full fil your dreams Ameen
How do you make it for left and right as well? If I want to move my elements left and move it right how do I go about doing it?
I implemented a project with similar approach with JavaScript and .NET (in the back end to preserve div’s position). The only difference in my project was that I allowed the div to be placed anywhere on the screen.
Great video. Thank you.
Helped me alot in my To-do app.
We would like to know more about you.
How you do such difficult task effortlessly?
Awesome tutorial, you are so smart . Thank you
wow!!! your explanation is incredible, i have learnt a lot ,thanks
Vanilla Javascript looks very easy, compared to the React DnD example (was a very nested -> crazy structure). Can one use the JS code in React pages as well ?
Thanks man. You really create awesome content !!!
You just saved my life ! thanks bro
great video. For new learners like me, it would help if you mention which words are built in to Javascript... (ex: closest/ offset/ y) Thanks for everything m8!
Brilliant mate! Thank you very much! Clever stuff. Better than the React libraries I tried and a real feather in the cap for my projects moving forward. Thank You
This is brilliant and EXACTLY what I need for a project I am working on. Thank you very much.
Question (if I may): Is there anyway to have the items COPY into the new field, not actually move?
Again, Thank you for this tutorial.
Hi Andrew Did u find the answer for this?
@@cuerojr no I didn't actually.
@@andrewbaillie2475 try inserting them twice, on the chosen spot and again in the previous location
I love your content.Thanks!