How can I ensure HTML5 drag and drop items stay within the boundaries of the document window?

Currently, I am experimenting with an HTML5 drag-and-drop feature. You can view my work using this JSFiddle link: http://jsfiddle.net/e4ogxcum/3/

My goal is to modify the functionality so that it prevents the toolbar from being dropped halfway off the page. Is there a way to achieve this?

In simpler terms, I want to restrict the option of dropping the toolbar in a position where it's partially off the page, as shown below:

Below you will find the complete code:

function drag_start(event) {
    console.log('drag_start', event);
    var style = window.getComputedStyle(event.target, null);
    event.dataTransfer.setData("text/plain",
    (parseInt(style.getPropertyValue("left"),10) - event.clientX) + ',' + (parseInt(style.getPropertyValue("top"),10) - event.clientY));
} 
function drag_over(event) { 
    event.preventDefault(); 
    return false; 
} 
function drop(event) { 
    event.preventDefault();
    var offset = event.dataTransfer.getData("text/plain").split(',');
    dm.style.left = (event.clientX + parseInt(offset[0],10)) + 'px';
    dm.style.top = (event.clientY + parseInt(offset[1],10)) + 'px';
    return false;
} 

var dm = document.getElementById('taskbar'); 
dm.addEventListener('dragstart',drag_start,false); 
document.body.addEventListener('dragover',drag_over,false); 
document.body.addEventListener('drop',drop,false)

;

Answer №1

To restrict the toolbar's drag range, modify the drop event in the following way:

function drop(event) { 
  event.preventDefault();
  var offset = event.dataTransfer.getData("text/plain").split(',');

  var x= event.clientX + parseInt(offset[0],10);
  var y= event.clientY + parseInt(offset[1],10);
  var w= dm.offsetWidth;
  var h= dm.offsetHeight;

  dm.style.left= Math.min(window.innerWidth -w/2,Math.max(-w/2,x))+'px';
  dm.style.top = Math.min(window.innerHeight-h/2,Math.max(-h/2,y))+'px';

  return false;
} 

The values of x and y should be adjusted according to your specific calculations, ensuring that at least half of the toolbar remains visible on the screen.

Fiddle


Another approach is to replicate the drag-drop functionality using mousedown, mouseup, and mousemove events.

During mousedown, capture the left and top coordinates of the toolbar (stored in variables x and y), its width and height (variables w and h), as well as the mouse's pageX and pageY values (represented by variables px and py).

In the mousemove function, compute the new left and top positions while constraining them to ensure a portion of the element is always within view:

newx= x+(ev.pageX-px);
newy= y+(ev.pageY-py);
this.style.left= Math.min(window.innerWidth -w/2,Math.max(-w/2,newx))+'px';
this.style.top = Math.min(window.innerHeight-h/2,Math.max(-h/2,newy))+'px';

Fiddle

Code:

(function() {
  var tb= document.querySelector('aside'),
      moving,
      w, h,
      x, y,
      newx, newy,
      px,py;

  tb.addEventListener('mousedown',function(ev) {
    this.style.cursor= 'move';
    x= tb.offsetLeft;
    y= tb.offsetTop;
    w= tb.offsetWidth;
    h= tb.offsetHeight;
    px= ev.pageX;
    py= ev.pageY;
    moving= true;
  });

  document.addEventListener('mouseup',function() {
    tb.style.cursor= '';
    moving= false;
  });

  tb.addEventListener('mousemove',function(ev) {
    if(moving) {
      newx= x+(ev.pageX-px);
      newy= y+(ev.pageY-py);
      this.style.left= Math.min(window.innerWidth -w/2,Math.max(-w/2,newx))+'px';
      this.style.top = Math.min(window.innerHeight-h/2,Math.max(-h/2,newy))+'px';
    }
  });

  document.addEventListener('mousemove', function(ev) {
    if(moving) {
      ev.preventDefault();
    }
  });
})();

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Can a designated Angular2 component be customized with CSS in terms of its appearance while employing ViewEncapsulation?

I am looking for a way to dynamically change the appearance of Angular2 components with just the click of a button, making them appear completely different each time. This is similar to implementing various CSS "Skins" or "Themes". It would also be conveni ...

Menu options are unresponsive to clicks in the dropdown

Need help fixing my dropdown menu issue. Whenever I hover over the dropdown, it disappears before I can click on any items. Here is a snippet of the code causing the problem: #navContainer { margin: 0; padding: 0; padding-top: 17px; width: 220 ...

Is there a way to eliminate the gap between two horizontal rule tags?

What causes the space between two <hr> tags to remain? Despite setting the width of the <hr> tags to 49%, there is still a gap between them. How can this space be removed from the <hr> tags? Shown below is the HTML and CSS code: *{mar ...

Dynamic hovering over isotopic elements

I'm looking to create a webpage where images are arranged dynamically like on this website: . I also want each image to have a hover effect displaying specific information about the image. After some research, I came across a JavaScript library calle ...

Disable the hover effect on the add to cart button by utilizing HTML and CSS

I'm currently developing an E-commerce application, but the theme I am using displays the "Add to Cart" button only on hover. I want to make the "Add to Cart" button always visible. You can view the live version of the website at the following URL: ...

"Enhancing user experience with jQuery hover effects on table

This is an example of the HTML structure: <tr class="row-1 row-first"> <td class="col-1 col-first"> <div class="views-field views-field-field-logo-image"></div> <div class="views-field views-field-field-logo-title"> ...

Locating username and password elements using Python and Selenium

Attached are 2 screenshots displaying the html code of a website. I am curious about the "find driver element" formats needed to input my username and password into the proper boxes. View Image1 View Image2 Your assistance is greatly appreciated. ...

Disappearance of attribute in asp .net TextBox

Here is my asp .net code snippet: <asp:TextBox CssClass="siteinput required" ID="TextTitle" runat="server" Width="100%" MaxLength='<%# int.Parse(Request.QueryString["id"]) == 49 ? 40 : 15 %>' placeholder="Title" required="required">& ...

Position the label to the left of the form-switch using Bootstrap

I have been struggling to align the label to the left of my switchbox. Despite searching through stackoverflow and other websites, I haven't been successful in achieving the desired alignment. Here is a trimmed down version of the code for reference: ...

What is the best way to conceal a DOM element by utilizing the [hidden] attribute instead of relying on the display property in

public toggleVisibility(){ this.isVisible = !this.isVisible; } .h1{ display: flex; } <button (click)="toggleVisibility()">Toggle Visibility</button> <h1 class="h1" [hidden]="!isVisible"> ...

Using jQuery to smoothly animate a sliding box horizontally

Is there a way to smoothly slide a div left and right using jQuery animation? I have been trying to achieve this by implementing the code below, which can be found in this fiddle. The issue I am facing is that every time I click on the left or right butto ...

recognizing a specific attribute of a website

Apologies for the unclear heading. I am on the lookout for a specific feature that has become a common sight on numerous websites lately. It's an animation used by freelancers when showcasing "projects worked on" or "hours spent coding". A counter s ...

Why is it that when the form is submitted, the value becomes unclear?

This is a form with HTML and TypeScript code that I am working on. <form> <div class="form-group"> <input class="form-control" ([ngModel])="login" placeholder="Login" required> </div> <div class="form-group"> &l ...

Tips for adding an HTML code snippet to an HTML iframe with the help of jQuery

Is there a way to dynamically append an HTML code snippet to an HTML iframe using jQuery? I have stored an HTML code snippet in a MySQL Database using PHP, and I am now attempting to retrieve that snippet and add it to the iframe using jQuery. $( document ...

How would you go about creating a VueJS component that displays a table with a set number of columns and automatically distributes the cells within them?

Hey there! I'm currently working with a VueJS component that looks like this: <template> <div> <table> <tbody> <tr v-for="(item, index) in items" :key="index"> <t ...

Dynamic Column Image and Text Display

I am working on a website where I am trying to have an image on the left and a paragraph on the right, but when the screen size is reduced, I need the layout to switch so that the image is at the top and the paragraph is at the bottom. Even though I have ...

Hide the HTML DIV without altering the position of the current div

My goal is to conceal elements 1, 3 and 2 & 4 without changing their position. div{ width: 10%; float: left; } <div style="background-color: blue"><p>1</p></div> <div style="background-color: yellow"><p>2</ ...

The Chrome browser on iOS does not fire the Image onLoad event

In my web application, I am utilizing Scala.js and d3.js (scala-js-d3) to generate an SVG. However, I have encountered a problem with the background image not triggering the load event when using Chrome on iOS (iPhone), even though it works fine on Windows ...

Customizing SharePoint Web Part Styles with CSS: Header Alignment Issue with Body_TEXT

I am currently working on branding a SharePoint website and have encountered an issue with aligning background colors for the title area and body of some web parts. Despite applying background colors, the alignment between the title and body areas is off ( ...

Flipping the switch to illuminate or darken a room

I am working on a project where I want to create a program that turns on a lightbulb when you click on it, and then turns it off when you click on it again. However, I am facing an issue where no matter which light I click on, the first one always turns ...