Error mousemove event can't show button in other frame? - javascript

I have a sample code:
<div id="background-1" style="background: url('image1.png') no-repeat left center; width: 200px; height: 200px; float: left;">
<div id="button-wrapper" style="position: absolute; opacity: 1; z-index: 100;">
<input type="button" value="submit">
</div>
</div>
<div id="background-2" style="background: url('image2.png') no-repeat right center; width: 200px; height: 200px; float: right;">
<div id="button-wrapper" style="position: absolute; opacity: 1; z-index: 100;">
</div>
</div>​
And my script:
jQuery(document).ready(function(){
jQuery("div[id^=\'button-wrapper\']").parent().mousemove(function(e){
var _top = e.pageY - 5;
var _left = e.pageX - 5;
var _c = jQuery(this);
var _p = _c.position();;
if (_top > (_p.top + _c.height())) _top = _p.top + _c.height();
if (_left > (_p.left + _c.width())) _left = _p.left +_c.width();
jQuery("div[id^=\'button-wrapper\']").css({
top: _top,
left: _left
});
});
});​
Error when I hover background-2 is event mousemove not run button submit, how to fix it? demo here

You can see demo here , hope help you !!!
var yellow = $('div[id^=\'yellow\']');
var offset = yellow.offset();
var offsetWidth = offset.left + yellow.width();
var offsetHeight = offset.top + yellow.height();
var red = $('#red');
yellow.on('mousemove', function (e) {
red.css("left", e.pageX);
red.css("top", e.pageY);
});
red.on('mousemove', function (e) {
if(e.pageX >= offset.left && e.pageY >= offset.top &&
e.pageX <= offsetWidth && e.pageY <= offsetHeight) {
red.css("left", e.pageX);
red.css("top", e.pageY);
}
});

Related

Javascript (vanilla) drag and drop does not work the second time an element is dragged and dropped

I am trying to implement a drag and drop functionality using vanilla Javascript on my web app, where element gets moved to a new position within a div, once it's dragged and dropped.
But I am having an issue where I can drop the element fine the first time, but I can no longer do it the second time onwards.
After debugging, I have noticed that the first time I drop an element, it does not have any inline style (see Appendix A). But when I try and do it the second time, it now has an inline style (see Appendix B) and for some reason, I cannot chnage the values of it. That was also the case after I manually added inline style to my draggable element- I could not drop the item even the first time when I did it.
I am completely out of ideas as to what I could be doing wrong and no similar questions yielded a solution.
Thank you very much in advance for your time.
Code (Unnecessary parts ommitted)
const list = document.querySelector("#list");
const rect = list.getBoundingClientRect();
let oldLeft, oldTop, mouseXStart, mouseYStart;
function dragStart(event) {
event.dataTransfer.setData("plain/text", event.target.id);
const item = document.querySelector("#" + event.target.id);
mouseXStart = event.clientX - rect.left;
mouseYStart = event.clientY - rect.top;
oldLeft = item.style.left;
oldTop = item.style.top;
console.log(item);
}
function dragOver(event) {
event.preventDefault();
event.dataTransfer.dropEffect = "move";
}
function dropItem(event) {
event.preventDefault();
const mouseXEnd = event.clientX - rect.left;
const mouseYEnd = event.clientY - rect.top;
//Calculate by how much mouse has been moved
const newLeft = mouseXEnd - mouseXStart;
const newTop = mouseYEnd - mouseYStart;
const item = document.querySelector('#' + event.dataTransfer.getData("plain/text"));
item.style.left = oldLeft + newLeft + "px";
item.style.top = oldTop + newTop + "px";
}
#list {
position: relative;
top: 60px;
height: 600px;
width: 100%;
border: 2px solid rgb(107, 14, 14);
display: block;
}
#list>div {
position: absolute;
height: 200px;
width: 200px;
background-color: blue;
margin: 10px;
overflow: hidden;
text-align: left;
}
<div id="list" ondrop="dropItem(event)" ondragover="dragOver(event)">
<div id="test" draggable="true" ondragstart="dragStart(event)">
<button type="button"></button>
<div>
<p>Test</p>
</div>
</div>
</div>
Appendix A
console.log() output on the first dragStart() call:
<div id="test" draggable="true" ondragstart="dragStart(event)">
Appendix B
console.log() output on the second dragStart() call:
<div id="test" draggable="true" ondragstart="dragStart(event)" style="left: 853px; top: 147px;">
Problem
This code
oldLeft + newLeft + "px"
evaluated to something like
123px40px
because
oldLeft = item.style.left
returned string with px at the end
Solution
Parse the value to float
oldLeft = item.style.left ? parseFloat(item.style.left) : 0;
oldTop = item.style.top ? parseFloat(item.style.top) : 0;
const list = document.querySelector("#list");
const rect = list.getBoundingClientRect();
let oldLeft, oldTop, mouseXStart, mouseYStart;
function dragStart(event) {
event.dataTransfer.setData("plain/text", event.target.id);
const item = document.querySelector("#" + event.target.id);
mouseXStart = event.clientX - rect.left;
mouseYStart = event.clientY - rect.top;
oldLeft = item.style.left ? parseFloat(item.style.left) : 0;
oldTop = item.style.top ? parseFloat(item.style.top) : 0;
}
function dragOver(event) {
event.preventDefault();
event.dataTransfer.dropEffect = "move";
}
function dropItem(event) {
event.preventDefault();
const mouseXEnd = event.clientX - rect.left;
const mouseYEnd = event.clientY - rect.top;
//Calculate by how much mouse has been moved
const newLeft = mouseXEnd - mouseXStart;
const newTop = mouseYEnd - mouseYStart;
const item = document.querySelector('#' + event.dataTransfer.getData("plain/text"));
item.style.left = oldLeft + newLeft + "px";
item.style.top = oldTop + newTop + "px";
}
#list {
position: relative;
top: 60px;
height: 600px;
width: 100%;
border: 2px solid rgb(107, 14, 14);
display: block;
}
#list>div {
position: absolute;
height: 200px;
width: 200px;
background-color: blue;
margin: 10px;
overflow: hidden;
text-align: left;
}
<div id="list" ondrop="dropItem(event)" ondragover="dragOver(event)">
<div id="test" draggable="true" ondragstart="dragStart(event)">
<button type="button"></button>
<div>
<p>Test</p>
</div>
</div>
</div>

How to get Elements to Follow Cursor After Scrolling Vertically in Web Page

I'm trying to get a HTML element to follow my mouse cursor as I scroll down a web page, but when I scroll down, the HTML element gets 'misaligned'. I get the impression this is due to my cursor's new x,y positions but I don't know how to proceed from here.
The Code - HTML:
<div id="mouseOverElement">
<h3 id="mouseOverText">
test text
</h3>
</div>
The Code - JavaScript:
let root = document.documentElement;
root.addEventListener("mousemove", e =>
{
root.style.setProperty('--mouse-x', e.clientX + "px");
root.style.setProperty('--mouse-y', e.clientY + "px");
});
The Code - CSS:
#mouseOverElement
{
width: 200px;
height: 100px;
background: rgb(0, 0, 0);
position: absolute;
color: white;
left: var(--mouse-x);
top: var(--mouse-y);
}
You have to account for the scroll y position. window.scrollY + e.clientY does the trick.
let root = document.documentElement;
root.addEventListener("mousemove", e => {
root.style.setProperty('--mouse-x', e.clientX + "px");
root.style.setProperty('--mouse-y', window.scrollY + e.clientY + "px");
});
#mouseOverElement {
width: 200px;
height: 100px;
background: rgb(0, 0, 0);
position: absolute;
color: white;
left: var(--mouse-x);
top: var(--mouse-y);
}
html, body{
height:200%;
}
<div id="mouseOverElement">
<h3 id="mouseOverText">
test text
</h3>
</div>
To update the position while scrolling we can also add an event listener for scroll:
let root = document.documentElement;
root.addEventListener("mousemove", e => {
root.style.setProperty('--mouse-x', e.clientX + "px");
root.style.setProperty('--mouse-y', window.scrollY + e.clientY + "px");
});
document.body.addEventListener("scroll", e => {
root.style.setProperty('--mouse-x', e.clientX + "px");
root.style.setProperty('--mouse-y', window.scrollY + e.clientY + "px");
});
#mouseOverElement {
width: 200px;
height: 100px;
background: rgb(0, 0, 0);
position: absolute;
color: white;
left: var(--mouse-x);
top: var(--mouse-y);
}
html, body{
height:200%;
}
<div id="mouseOverElement">
<h3 id="mouseOverText">
test text
</h3>
</div>

Move a div with mouse pointer

I'm trying to do exactly as it is in this link.
(The stripe on the banners with the read more link)
https://toyota.jp/vitz
What I tried so far doesn't work as expected. It moves the whole stripe apart from the range.
$(document).on("click mousemove", ".spec-slider-wrap", function(e) {
var x = e.clientX;
var y = e.clientY;
var newposX = x - 700;
var newposY = y - 350;
$(".stripe").css("transform", "translate3d(" + newposX + "px," + newposY + "px,0px)");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<span class="word">More</span>
<span class="arrow-wrap">
<span class="arrow-pulse-right"></span>
</span>
</div>
here the working code.
https://jsbin.com/geyudivuru/edit?html,css,js,output
<div class="parent" style="">
<div class="stripe">
<span class="word">More</span>
<span class="arrow-wrap">
<span class="arrow-pulse-right"></span>
</span>
<div>
</div>
.stripe {
width: 100%;
background: red;
position: absolute;
height: 40px;
display: none;
}
.parent {
position: relative;
height: 400px;
background: #ddd;
}
$ = jQuery;
$(document).on("mousemove", function(e) {
var x = e.clientX;
var y = e.clientY;
var newposX = x - 700;
var newposY = y;
$('.stripe').css({top: newposY, display: 'block'})
});
$('.parent').mouseleave(function(){
$('.stripe').css({top: 0, display: 'none'})
})
add styling to divs and you'll get what you need.

How can I drag a div and keep the cursor on the same spot as I clicked it at?

I'm trying to drag a div when I click on it but when I do it the div blinks and moves to the left, if I remove offset and put position instead it works but the cursor goes to the left top of the div.
var selected = 0,
x = 0,
y = 0;
$.fn.isDraggable = function() {
$(this).on('mousedown', function(e) {
selected = $(this);
$(selected).css({
position: 'absolute',
left: e.pageX - $(selected).position().left,
top: e.pageY - $(selected).position().top
});
});
$(document).on('mouseup', function() {
if (selected !== 0) {
selected = 0;
}
});
$(document).bind('mousemove', function(e) {
$(selected).css({
position: 'absolute',
left: e.pageX - $(selected).offset().left,
top: e.pageY - $(selected).offset().top
});
});
return true;
};
$('#card').isDraggable();
#card {
position: fixed;
width: 100px;
height: 150px;
top: calc(50% - 75px);
left: calc(50% - 50px);
border: 1px solid #D3D3D3;
}
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<title>freeMarketRocks</title>
</head>
<body>
<div>
<div id="card">
</div>
</div>
</body>
</html>
You have 2 problems here. First your event handler logic might result in a performance waste as you are asking your browser to constantly check for mouse movement, even if its not necessary.
Second, the calculation of the box coordiante is wrong, it must take the initial position in account. That's the purpose of my deltaX and deltaY variables in the fiddle
Here's a working fiddle https://jsfiddle.net/TCHdevlp/t2bapq5y/
Or Here:
var selected = 0,
x = 0,
y = 0,
boxX = 0,
boxY = 0;
$.fn.isDraggable = function() {
$(this).on('mousedown', function(e) {
selected = $(this);
//get initial positions
x = e.pageX;
y = e.pageY;
BoxX = $(selected).offset().left;
BoxY = $(selected).offset().top;
//bind mousemove
$(document).bind('mousemove', function(e) {
//compute new coordinate
deltaX = e.pageX - x;
deltaY = e.pageY - y;
$(selected).css({
position: 'absolute',
left: (BoxX + deltaX),
top: (BoxY + deltaY)
});
});
});
//unbind when finished
$(document).on('mouseup', function() {
if (selected !== 0) {
$(document).unbind("mousemove");
selected = 0;
}
});
return true;
};
$('#card').isDraggable();
#card {
position: fixed;
width: 100px;
height: 150px;
top: 10x;
left: 10px;
border: 1px solid #D3D3D3;
}
<div>
<div id="card">
</div>
</div>
var selected = 0,
x = 0,
y = 0;
$.fn.isDraggable = function() {
var moveFrame, comStartX, comStartY, startMousePosX, startMousePosY;
$(this).on('mousedown', function(e) {
selected = $(this);
moveFrame = true;
comStartX = $(this).position().left;
comStartY = $(this).position().top;
startMousePosX = e.pageX;
startMousePosY = e.pageY;
});
$(document).on('mouseup', function() {
moveFrame = false;
});
$(document).bind('mousemove', function(e) {
if (moveFrame){
currPosX = comStartX + (e.pageX - startMousePosX);
currPosY = comStartY + (e.pageY - startMousePosY);
$(selected).css({position: 'absolute', 'left': currPosX + 'px', 'top': currPosY + 'px'});
}
});
return true;
};
$('#card').isDraggable();
#card {
position: fixed;
width: 100px;
height: 150px;
top: calc(50% - 75px);
left: calc(50% - 50px);
border: 1px solid #D3D3D3;
}
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<title>freeMarketRocks</title>
</head>
<body>
<div>
<div id="card">
</div>
</div>
</body>
</html>

Animate clip-path using jQuery animate()?

I have 2 images overlapping each other. What I'm trying to achieve is to use mouse scroll / mouse wheel to make the clipping mask changes, to reveal the underneath layer.
CSS:
html {
overflow: hidden; /* prevent overscroll */
height: 100%;
}
body {
padding: 0;
margin: 0;
overflow: auto;
height: 100%;
}
#slideshow {
position: relative;
width: 100%;
top: 0;
display: table;
}
#slideshow img {
position: absolute;
top: 0;
left: 0;
width: 100%;
}
JS:
$(document).ready(function() {
var w = $('#slideshow').width();
var h = $('#slide1').height();
var lastScrollX = 0;
$('#slideshow').on('scroll', function() {
st = $(this).scrollTop();
if(st < lastScrollX) {
console.log('scroll up');
} else if(st < lastScrollX) {
console.log('scroll down');
}
lastScrollX = st;
});
var offsetX = 0;
$(document).on('DOMMouseScroll mousewheel', function (e) {
if (e.originalEvent.detail > 0 || e.originalEvent.wheelDelta < 0) {
dir = 'down';
} else {
dir = 'up';
}
d = -e.originalEvent.wheelDelta;
if(offsetX + d < w && offsetX + d >= 0) {
offsetX += d;
} else if(offsetX + d >= w) {
offsetX = w;
} else if(offsetX +d < 0) {
offsetX = 0;
}
if(offsetX > w / 2) {
// animate offsetX till w... but how?
} else {
$('#slide1').css('-webkit-clip-path', 'inset(0 ' + offsetX + 'px 0 0)');
$('#slide1').css('clip-path', 'inset(0 ' + offsetX + 'px 0 0)');
}
});
});
HTML:
<div id="slideshow">
<img id="slide5" src="img/banner5.jpg" alt="" />
<img id="slide4" src="img/banner4.jpg" alt="" />
<img id="slide3" src="img/banner3.jpg" alt="" />
<img id="slide2" src="img/banner2.jpg" alt="" />
<img id="slide1" src="img/banner1.jpg" alt="" />
</div>
somehow JSFiddle can't work on this case.
Question: how to animate the offsetX to full width w using jQuery?
I use clip-path instead of clip as latter property is deprecated.

Categories

Resources