I'm a newbie to mobile web applications. I tried to create some mouse draggable divs for a webpage. They work well on desktop. However, when I checked them on mobile devices, none of them works. I searched online for help, but the only thing I got is that I need to set touch events with jquery mobile. Some articles said something about using touchstart, touchmove and touchend, but no examples were ever provided.
Here's my script:
dragElement(document.getElementById("cn"));
dragElement(document.getElementById("ln"));
dragElement(document.getElementById("gn"));
dragElement(document.getElementById("sn"));
function dragElement(elmnt) {
var pos1 = 0,
pos2 = 0,
pos3 = 0,
pos4 = 0;
if (document.getElementById(elmnt.id + "header")) {
// if present, the header is where you move the DIV from:
document.getElementById(elmnt.id + "header").onmousedown = dragMouseDown;
} else {
// otherwise, move the DIV from anywhere inside the DIV:
elmnt.onmousedown = dragMouseDown;
}
function dragMouseDown(e) {
e = e || window.event;
e.preventDefault();
// get the mouse cursor position at startup:
pos3 = e.clientX;
pos4 = e.clientY;
document.onmouseup = closeDragElement;
// call a function whenever the cursor moves:
document.onmousemove = elementDrag;
}
function elementDrag(e) {
e = e || window.event;
e.preventDefault();
// calculate the new cursor position:
pos1 = pos3 - e.clientX;
pos2 = pos4 - e.clientY;
pos3 = e.clientX;
pos4 = e.clientY;
// set the element's new position:
elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
}
function closeDragElement() {
// stop moving when mouse button is released:
document.onmouseup = null;
document.onmousemove = null;
}
}
I've tried to replace the mouse events with corresponding touch events. But it didn't work.
It appears that I have to rewrite the codes in another framework. Thanks in advance.
vmousecancel means mousecancel
vmousedown
vmousemove
vmouseout
vmouseover
vmouseup
for more examples : https://api.jquerymobile.com/category/events/
Before using, you have to get jquery.mobile library in to your workspace.
Related
I'm using drag event for moving an element, but I didn't find a way to make it only move horizontally, it's there any clue for this? Thanks in advance!
There is three steps we need to do
first we get the current mouse x position
second we calculate the distance it has move and the direction by newX = oldX - e.clientX saying subtract old x with current mouse x this way we get something like -3 or 2 or -1 you see we have the distance the direction - or +
Third step we update the element horizontal position by element.style.left = (element.offsetLeft - newX) + "px"
There are more details in the comments in the code. let me know if its not clear
var oldX = 0, newX = 0; // for storing X (horizontal) positions
var element = document.getElementById("mydiv"); // The element you want to drag
// We do the dragging here
function elementDrag(e) {
e = e || window.event;
e.preventDefault();
newX = oldX - e.clientX; // to calculate how much we have moved
oldX = e.clientX; // store current value to use for next move
element.style.left = (element.offsetLeft - newX) + "px"; // update left position
}
// we do this so there is not multiple event handlers
function closeDragElement() {
document.onmouseup = null;
document.onmousemove = null;
}
// when mouse down on element attach mouse move and mouse up for document
// so that if mouse goes outside element still drags
function dragMouseDown(e) {
e = e || window.event;
e.preventDefault();
oldX = e.clientX; // store current value to use for mouse move calculation
document.onmouseup = closeDragElement;
document.onmousemove = elementDrag;
}
element.onmousedown = dragMouseDown;
#mydiv {
position: absolute;
z-index: 9;
background-color: #2196F3;
text-align: center;
border: 1px solid #d3d3d3;
padding: 10px;
cursor: move;
color: #fff;
}
<div id="mydiv">
Click here to move
</div>
Oddly enough I cannot get the problem to be reproducable here however in my own project switching from an svg to a png seems to have fixed the issue, I had wanted to use an svg so that's a little inconvenient but not a huge thing overall.
I've been trying to get a draggable map and I've started messing around first with an svg image that is draggable and then cutoff by a div. My HTML looks like this
dragElement(document.getElementById("map"));
function dragElement(el) {
var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
if (document.getElementById(el.id + "header")) {
// if present, the header is where you move the DIV from:
document.getElementById(el.id + "header").onmousedown = dragMouseDown;
} else {
// otherwise, move the DIV from anywhere inside the DIV:
el.onmousedown = dragMouseDown;
}
function dragMouseDown(e) {
e = e || window.event;
e.preventDefault();
// get the mouse cursor position at startup:
pos3 = e.clientX;
pos4 = e.clientY;
document.onmouseup = closeDragElement;
// call a function whenever the cursor moves:
document.onmousemove = elementDrag;
}
function elementDrag(e) {
e = e || window.event;
e.preventDefault();
// calculate the new cursor position:
pos1 = pos3 - e.clientX;
pos2 = pos4 - e.clientY;
pos3 = e.clientX;
pos4 = e.clientY;
// set the element's new position:
el.style.top = (el.offsetTop - pos2) + "px";
el.style.left = (el.offsetLeft - pos1) + "px";
}
function closeDragElement() {
// stop moving when mouse button is released:
document.onmouseup = null;
document.onmousemove = null;
}
}
<div id="content" style=" width: auto; height: 100%; padding:5px 100px;"></div>
<div id="mapContainer" style="height: 500px; width: auto; overflow: hidden; position: relative;">
<img id="map" draggable="false" src="https://cdn.pixabay.com/photo/2013/07/12/12/54/world-map-146505_1280.png" style="position:absolute;"></img>
</div>
<
And I'm using some js from w3 to do the dragging:
The problem is I need position absolute on the image to move it but that renders the overflow hidden of it's parent div null and void so I have to set the parent div to relative but when I do that the y axis works perfectly but the x axis (left) scales the image? Is there a way to fix this? Or perhaps I should approach this in an entirely different way?
Leaflet.js (https://leafletjs.com/) is the best tool to use for what I'm trying to achieve.
I have successfully managed to connect my external JavaScript file to my angular component, however it doesn't work in some instances.
I connected my src/custom.js file to my app.component.html through angular.json, as illustrated below:
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.css",
"src/styles.css"
],
"scripts": [
"node_modules/jquery/dist/jquery.js",
"node_modules/bootstrap/dist/js/bootstrap.js",
"src/custom.js"
]
Context:
The demo script is a simple alert saying hello that pops every time I connect to my localhost. As far as I'm aware there's no issue with the external js file being referenced.
My issue seems to come from more complex functions.
Here's the example that am trying to implement from w3schools.
And it's set up as follows:
<!-- app.component.html -->
<div id="mydiv">
<div id="mydivheader">Click here to move</div>
<p>Move</p>
<p>this</p>
<p>DIV</p>
</div>
// custom.js
dragElement(document.getElementById("mydiv"));
function dragElement(elmnt) {
var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
if (document.getElementById(elmnt.id + "header")) {
document.getElementById(elmnt.id + "header").onmousedown = dragMouseDown;
} else {
elmnt.onmousedown = dragMouseDown;
}
function dragMouseDown(e) {
e = e || window.event;
e.preventDefault();
pos3 = e.clientX; pos4 = e.clientY;
document.onmouseup = closeDragElement;
document.onmousemove = elementDrag;
}
function elementDrag(e) {
e = e || window.event;
e.preventDefault();
pos1 = pos3 - e.clientX;
pos2 = pos4 - e.clientY;
pos3 = e.clientX;
pos4 = e.clientY;
elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
}
function closeDragElement() {
// stop moving when mouse button is released:
document.onmouseup = null;
document.onmousemove = null;
}
}
Error: Cannot read property 'id' of null at dragElement (custom.js:13) at custom.js:6
I have come across a similar error before.My suspicion is that it has something to do with loading the DOM vs running the js?
Unfortunately I'm very new to Angular, with no experience in setting up basic web pages.
Does anybody have any insight?
You can tag your DOM element using #someTag, then get it with #ViewChild('someTag').
I am creating a page with multiple draggable divs and am looking for a way to finesse my code.
The only way I would know how to apply this JS to each id is to copy & paste the whole block of JS code 4 times and change the id but I know there must be a more efficient way, however, I am not very familiar with JS.
My initial thought was doing something like this
dragElement(document.getElementById("draggable", "draggable2", "draggable3", "draggable4"));
But it doesn't work. How can I achieve what I want in a more efficient way?
Here is my code
<div id="draggable"><div id="draggableimg"></div></div>
<div id="draggable2"><div id="draggable2img"></div></div>
<div id="draggable3"><div id="draggable3img"></div></div>
<div id="draggable4"><div id="draggable4img"></div></div>
JS
//Make the DIV element draggable:
dragElement(document.getElementById("draggable"));
var _curDragEle = "";
function dragElement(elmnt) {
var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
if (document.getElementById(elmnt.id + "img")) {
/* if present, the header is where you move the DIV from:*/
document.getElementById(elmnt.id + "img").onmousedown = dragMouseDown;
} else {
/* otherwise, move the DIV from anywhere inside the DIV:*/
elmnt.onmousedown = dragMouseDown;
}
function dragMouseDown(e) {
e = e || window.event;
e.preventDefault();
_curDragEle = this;
// get the mouse cursor position at startup:
pos3 = e.clientX;
pos4 = e.clientY;
document.onmouseup = closeDragElement;
// call a function whenever the cursor moves:
document.onmousemove = elementDrag;
}
function elementDrag(e) {
_curDragEle.classList.remove("dragstart")
_curDragEle.className = _curDragEle.className + " dragstart";
e = e || window.event;
e.preventDefault();
// calculate the new cursor position:
pos1 = pos3 - e.clientX;
pos2 = pos4 - e.clientY;
pos3 = e.clientX;
pos4 = e.clientY;
// set the element's new position:
elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
}
function closeDragElement() {
var k = document.querySelectorAll(".dragstart")
for(var i=0; i < k.length;i++){
k[0].classList.remove("dragstart")
}
/* stop moving when mouse button is released:*/
document.onmouseup = null;
document.onmousemove = null;
}
}
Forget ids, they lead to exactly the type of problem you are facing. Instead, give all the draggable elements a common class. Then gather all the elements up and loop over them.
// Gather all the draggable elements up into a collection
let draggables = document.querySelectorAll(".draggable");
// Loop over the collection
draggables.forEach(function(el){
dragElement(el);
});
function dragElement(el){
console.log(el + " is now draggable!")
}
<div class="draggable"><div id="draggableimg"></div></div>
<div class="draggable"><div id="draggable2img"></div></div>
<div class="draggable"><div id="draggable3img"></div></div>
<div class="draggable"><div id="draggable4img"></div></div>
So I will simplify the question a bit and provide a simple answer that I think solves your issue. "How do I assign a drag function / listener to multiple elements?"
Basically, IDs must be unique, but you can get elements of the page in bulk by referencing their tags (i.e. "DIV") or class names. It's safer to use classnames. Here's an example that can help your issue.
HTML
<div class="draggable-div" id="div1"><img /></div>
<div class="draggable-div" id="div2"><img /></div>
<div class="draggable-div" id="div3"><img /></div>
<div class="draggable-div" id="div4"><img /></div>
<div class="draggable-div" id="div5"><img /></div>
JS
function onDragEventHandler(e) {
var div = e.target;
// event code to drag here
}
var divs = document.querySelectorAll('.draggable-div');
divs.forEach(function(elem,index) = {
elem.addEventListener('mousemove', onDragEventHandler)
})
How can a function, which is triggered by another function, get the mouse's position? Here's my code:
function myFunction(e){
setTimeout(function(){
if(isMouseDown == true){
mouseX = e.clientX;
mouseY = e.clientY;
document.getElementById('myElement').innerHTML = mouseX + ' , ' + mouseY;
myFunction(event);
} else {}
}, 100);
}
What this does is to display the coordinates when clicked. I need it to display them every 100ms if isMouseDown == true.
Thanks
There is no way in Javascript for a random Javascript function to get the mouse position. The current mouse position only comes from an event object for a mouse-related event. So, if you want to keep track of the mouse position, then you can register an event handler for the mousemove event and for mousedown and mouseup to keep track of the button state.
If you only want to display the mouse position, ever 100ms, then you can set a timer so that it is only displayed that often, but you will need to keep track of the current mouse position in a mousemove event handler.
Here's a simple code example:
var lastMouseX = 0, lastMouseY = 0;
document.addEventListener("mousemove", function(e) {
lastMouseX = e.clientX;
lastMouseY = e.clientY;
});
var mouseTimer;
document.addEventListener("mousedown", function() {
if (!mouseTimer) {
mouseTimer = setInterval(function() {
document.getElementById("x").innerHTML = lastMouseX;
document.getElementById("y").innerHTML = lastMouseY;
}, 100);
}
});
document.addEventListener("mouseup", function() {
clearInterval(mouseTimer);
mouseTimer = null;
});
<div id="x"></div>
<div id="y"></div>
It's a bit fuzzy what you're trying to achieve, however you're not going to get a periodic event if you're usingsetTimeout(). It sounds like you're looking for setInterval(). See the below example:
var mouseX = 0;
var mouseY = 0;
var isMouseDown = true;
document.onmousemove = function(e){
mouseX = e.pageX;
mouseY = e.pageY;
}
setInterval("myFunction()", 100);
function myFunction(){
if(isMouseDown) {
document.getElementById('myElement').innerHTML = mouseX + ' , ' + mouseY;
}
}
<div id="myElement"></div>