How to get hold of div on mousemove? - javascript

JSFiddle code
I am trying to get hold of div with blue lines when I move the mouse pointer within a distance of 20px from the div. I am able to get hold of the div with blue lines only when the mouse pointer is on that div. Basically, selecting a div using the mouser pointer is difficult as the div width is only 1px which cannot be changed.
I am executing the below code but still not able to catch hold of the div which is 20px away from either right or left of the mouse pointer.
Note:The div mentioned above indicated the div with blue lines and not the gray box.
//Div positions and their id has been added to map
var hmap = new Map();
hmap.set("hguide1",96);
hmap.set("hguide2",284);
hmap.set("hguide3",520);
var vmap = new Map();
vmap.set("vguide1", 96);
vmap.set("vguide2",384);
vmap.set("vguide3",720);
$(document).mousemove(function(e){
var mx = e.pageX, my = e.pageY;
//Catch hold of vertical div's
for (var [key, value] of vmap) {
var dist = value - mx;
if(dist >= -20 && dist <= 20){
$('.'+key).css({width: '10px', left:});
} else {
$('.'+key).css({width: '1px'});
}
}
//Catch hold of horizontal div's
for (var [key, value] of hmap) {
var dist = value - my;
if(dist >= -20 && dist <= 20){
$('.'+key).css({height: '10px'});
} else {
$('.'+key).css({height: '1px'});
}
}
});
I looking for a way thru which I can catch hold of the div, which is 20px away from either the left or right side of the mouse pointer, and drag it.
Any suggestions much appreciated.

You can use CSS styling to get this result. We set the ::after size to 100% - 20px on either the left or top, depending if it's the horizontal or vertical line. We then set our width or height, depending on if we're adjusting the row or column, to either 100% or the buffer size(40px, because we want 20px on either side of the line).
I realize that sounds a little confusing, so I'll split them up. Here's the vertical:
.vguide1,.vguide2,.vguide3 {
border-left: 1px solid blue;
padding-bottom: 20px;
position: absolute;
width:1px;
height:650px;
}
.vguide1::after,.vguide2::after,.vguide3::after {
content: '';
position: absolute;
left: calc(50% - 20px);
width: 40px;
height: 100%;
cursor: col-resize;
}
Horizontal:
.hguide1,.hguide2,.hguide3 {
padding-right: 20px;
position: absolute;
width:850px;
height:1px;
border-top: 1px solid blue;
}
.hguide1::after,.hguide2::after,.hguide3::after {
content: '';
position: absolute;
top: calc(50% - 20px);
width: 100%;
height: 40px;
cursor: row-resize;
}
With shading to show the hit box: https://jsfiddle.net/Ljxpj5bt/27/
Without hit box: https://jsfiddle.net/Ljxpj5bt/28/

Related

How to move HTML image to click location with JavaScript

I am trying to move an HTML image (a black marker) to where I click on a map on the screen. The map has an onclick function which makes a marker visible and move to where the user clicks. However at the moment this only works for the size of screen I am using and whenever the window size is changed the image is several hundred pixels off on each axis.
At the moment I am storing the coordinates of a click in an array and using DOM style.left/top to change the position and using those coordinates plus a set amount of pixels that works for me, but not any other screen.
I would like a way to have it it move wherever the user clicks, regardless of the page dimensions.
This is the current way I am doing things, with coords being the array containing the relative coordinates:
document.getElementById('black-marker').style.visibility = 'visible';
document.getElementById('black-marker').style.left = coords[0]-20;
document.getElementById('black-marker').style.top = coords[1]+205;
Click in the red box and the black circle will move to the mouse point.
I got the position of the red box and the mouse position and used them to calculate the relative position for the black box.
const blackMarker = document.getElementById('black-marker');
const parent = blackMarker.parentElement;
parent.addEventListener('click', e => {
const {
x,
y,
width,
height
} = parent.getBoundingClientRect();
blackMarker.style.left = `${(e.clientX - x) / width * 100}%`;
blackMarker.style.top = `${(e.clientY - y) / height * 100}%`;
});
body {
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
div {
position: relative;
width: 150px;
height: 150px;
background-color: red;
}
span {
position: absolute;
transform: translate(-50%, -50%);
width: 25px;
border-radius: 50%;
height: 25px;
background-color: black;
}
<div>
<span id="black-marker"></span>
</div>

Resize an html element using mouse - jQuery

I have container and I want to resize it with mouse using JavaScript.
the implementation uses mousedown ,mouseup, and mousemove events but I have slight problem when page is already scrolled before the mousedown is fired.
the whole page seems to scroll to position zero. How can i fix it so whether page is already scrolled or not the resize will work fine.
JS:
//resize div vertically or horizontal or both
$.fn.resizeMe = function(options){
var grippie = $(this),
options = $.extend({resizeMe:"",resize:"vertical"},options),
resizeMe = $(options.resizeMe);
grippie.on('mousedown',function(e){initialiseGrippieResize(e)});
function initialiseGrippieResize(e) {
$(window).on('mousemove',function(e){
startResizing(e);
resizeMe.css({opacity:.25});
}).on('mouseup',function(e){
stopResizing(e);
resizeMe.css({opacity:1});
});
}
//css objects
function cssOBJ(e,key){
var css = {
vertical:{height:(e.clientY - resizeMe.offset().top)},
horizontal : {width:(e.clientX - resizeMe.offset().left)},
both: {
height:(e.clientY - resizeMe.offset().top),
width: (e.clientX - resizeMe.offset().left)
}
};
//return objects
return css[key];
}
//Start Resizing
function startResizing(e) {
resizeMe.css(cssOBJ(e,options.resize));
}
function stopResizing(e) {
$(window).off('mousemove mouseup');
}
}
$('.grippie').resizeMe({resizeMe:"#pane",resize:'vertical'});
HTML:
<div id='main-container'>
<div id='pane' arial-lable='content-wrapper'>contents will go here</div>
<div class='grippie'></div>
</div>
CSS:
#pane{
resize: n-resize;
overflow: hidden;
border: 1px solid #d6d9dc;
padding:15px 20px;
min-height:50px;
}
#pane *{border:0px !important; background: #fff !important;}
.grippie {
background-position: center;
border: 1px solid #d6d9dc;
border-width: 0 1px 1px;
cursor: s-resize;
height: 9px;
overflow: hidden;
background-color: #eff0f1;
/*background-image: url('images/icons.png');*/
background-repeat: no-repeat;
In JavaScript
pageX, pageY, screenX, screenY, clientX, and clientY returns a number which indicates the number of physical “CSS pixels” a point is from the reference point. The event point is where the user moved the mouse, the reference point is a point in the upper left. These properties return the horizontal and vertical distance from that reference point.
but pageX or pageY returns a number which indicates the amount of page scrolled top or left.
so changing the clientX to pageX and clientY to pageY
solved the problem and now I can resize any element. :) :)
//css objects
function cssOBJ(e,key){
var css = {
vertical:{height:(e.pageY - resizeMe.offset().top)},
horizontal : {width:(e.pageX - resizeMe.offset().left)},
both: {
height:(e.pageY - resizeMe.offset().top),
width: (e.pageX - resizeMe.offset().left)
}
};
//return objects
return css[key];
}

Highlight HTML element just like the Chrome Dev Tools in Javascript

WolfPack!
I want to highlight any element I hover over just like the Chrome Dev Tools does it.
Picture of Chrome Dev Tools
Notice how the entire element is drenched in a blue tint? This is not as simple as adding a background color or linear-gradient because the insides of input elements are still white.
I've tried using the different filter methods like hue rotate, contrast w/brightness, and even THIS MONSTER, but nothing seems to work.
The closest I've been is just a nice looking box-shadow around the elements for highlighting.
Javascript: element.classList.add('anotherClass')
CSS: box-shadow: 0 0 5px #3fd290, 0 0 10px #36A9F7, 0 0 15px #36A9F7, 0 0 20px #36A9F7 !important;
Help me make my dreams come true
If anyone cares what I did to solve it, here is my code (thanks to the help of Roope):
onMouseEnter:
highlightElement(event){
const hoverableElements = document.querySelectorAll('[data-attr]');
for(let elm of hoverableElements){
const styles = elm.getBoundingClientRect()
if(event.currentTarget.textContent === elm.dataset.dataAttr) {
let div = document.createElement('div');
div.className = 'anotherClass';
div.style.position = 'absolute';
div.style.content = '';
div.style.height = `${styles.height}px`;
div.style.width = `${styles.width}px`;
div.style.top = `${styles.top}px`;
div.style.right = `${styles.right}px`;
div.style.bottom = `${styles.bottom}px`;
div.style.left = `${styles.left}px`;
div.style.background = '#05f';
div.style.opacity = '0.25';
document.body.appendChild(div);
}
}
}
onMouseLeave:
onLeave(event){
const anotherClass = document.getElementsByClassName("anotherClass");
for (let elm of anotherClass) {
document.body.removeChild(elm)
}
}
After looping through the querySelectorAll (to get the desired elements), I used element.getBoundingClientRect() to get the exact height, width, top, right, bottom, left of the element.. That way, the new div created will take the exact size and location of the element.
CSS didn't quite cut it because other stylesheets would override/mess the styling up.
If all you want is the blue transparent highlight, just add a pseudo element over the hovered element. Positioning may of course be absolute of fixed for the element as well.
.element {
float: left;
position: relative;
width: 100px;
height: 100px;
margin: 10px;
border: 1px solid #000;
text-align: center;
line-height: 100px;
}
.element:hover::after {
position: absolute;
display: block;
content: '';
top: 0;
right: 0;
bottom: 0;
left: 0;
background: #05f;
opacity: 0.25;
}
.tall {
height: 200px;
}
<div class="element">Element</div>
<div class="element tall">Element</div>
<div class="element">Element</div>

Float a div at the bottom right corner, but not inside footer

I'm trying to implement a "go to top" button that floats at the bottom right corner of a page. I can do this with the following code, but I don't want this button to enter the footer of my page. How can I stop it from entering the footer and stay at the top of it when user scrolls the page down to the bottom of the page?
CSS
#to-top {
position: fixed;
bottom: 10px;
right: 10px;
width: 100px;
padding: 5px;
border: 1px solid #ccc;
background: #f7f7f7;
color: #333;
text-align: center;
cursor: pointer;
display: none;
}
JavaScript
$(window).scroll(function() {
if($(this).scrollTop() != 0) {
$('#to-top').fadeIn();
} else {
$('#to-top').fadeOut();
}
});
$('#to-top').click(function() {
$('body,html').animate({scrollTop:0},"fast");
});
HTML
<div id="to-top">Back to Top</div>
EDIT
Here is a drawing of how it should look like. The black vertical rectangle is a scroll bar. The "back to top" button should never enter the footer region.
Here is a jsfiddle.
The solution turned out to be more complicated than I thought. Here is my solution.
It uses this function to check if footer is visible on the screen. If it is, it positions the button with position: absolute within a div. Otherwise, it uses position: fixed.
function isVisible(elment) {
var vpH = $(window).height(), // Viewport Height
st = $(window).scrollTop(), // Scroll Top
y = $(elment).offset().top;
return y <= (vpH + st);
}
$(window).scroll(function() {
if($(this).scrollTop() == 0) {
$('#to-top').fadeOut();
} else if (isVisible($('footer'))) {
$('#to-top').css('position','absolute');
} else {
$('#to-top').css('position','fixed');
$('#to-top').fadeIn();
}
});
jsfiddle
Increase the value of bottom: 10px; than the height of footer.
I saw your screenshot now,just add some padding-bottom to it.
Solution
$(document).ready(function(){
$(window).scroll(function(){
btnBottom = $(".btt").offset().top + $(".btt").outerHeight();
ftrTop = $(".footer").offset().top;
if (btnBottom > ftrTop)
$(".btt").css("bottom", btnBottom - ftrTop + $(".btt").outerHeight());
});
});
Fiddle: http://jsfiddle.net/praveenscience/BhvMg/
You forgot to give the z-index, that prevents it from being on top!
z-index: 999;
Or if it is overlapping with the footer of your page, you can increase the co-ordinates.
bottom: 50px;
Your question is still not clear, "stop it from entering the footer". Does it overlap?

Positioning absolute div inside relative parent - webkit browsers

My HTML basically looks like this:
<div id="#container">
<div id="left_col">
left stuff
</div>
<div id="middle_col">
middle stuff
</div>
<div id="right_col">
<div id="anchor"></div>
<div id="floater>
The problem div
</div>
</div>
</div>
The container div is pushed 82px to the left, because I don't want the rightmost column to be used as part of the centering (there is a header navigation bar above that is the size of left_col and middle_col):
#container {
width: 1124px;
margin-left: auto;
margin-right: auto;
text-align: left;
color: #656f79;
position: relative;
left: 82px;
}
#left_col {
float:left;
width: 410px;
background-color: #fff;
padding-bottom: 10px;
}
#middle_col {
width: 545px;
float: left;
}
#right_col {
float: left;
width: 154px;
margin-left: 5px;
position:relative;
}
#floater {
width: 154px;
}
I'm using the following javascript to keep the #floater div in position as you scroll down the page:
var a = function() {
var b = $(window).scrollTop();
var d = $("#anchor").offset().top;
var c = $("#floater");
if (b > d) {
c.css({position:"fixed",top:"10px"});
} else {
c.css({position:"absolute",top:""});
}
};
$(window).scroll(a);
a();
The problem I'm having is that in WebKit based browsers, once jQuery makes the floater div's positioning fixed so it will stay 10px from the top, that "left: 82px" from #container goes out the window, causing #floater to jump 82px to the left. This doesn't happen in FF or IE. Does anybody know a solution to this?
Update: Solved
I've solved this problem by not using fixed positioning, but instead using absolute positioning. I changed the javascript to set the top CSS property of div#floater to be based on the value $(window).scrollTop() if div#anchor's top offset is greater than $(window).scrollTop(). Pretty simple.
So the a() function now looks like this:
var a = function() {
var b = $(window).scrollTop();
var d = $("#anchor").offset().top;
var c = $("#floater");
if (b > d) {
var t = b-200; //200px is the height of the header, I subtract to make it float near the top
c.css({top:t+"px"});
} else {
c.css({top:""});
}
};

Categories