How would I be able to create a new element and have it placed right where the mouse/cursor is located?
I have some example code below:
<div id = "adivthing></div>
<script>
var newthing = document.createElement("input");
document.getElementById("adivthing").appendChild(newthing);
</script>
If you use either the position: fixed or position: absolute style properties on the newthing element, you can then use the left and top properties to move the element around the box.
If you get the mouse coordinates from your triggering event (e.g. click), you can add the appropriate left and top to your element.
Example below:
function createInput(event){
var newthing = document.createElement("input");
document.getElementById("adivthing").appendChild(newthing); // Your existing code
// get the coordinates of the mouse
var x = event.clientX; // get the horizontal coordinate
var y = event.clientY; // get the vertical coordinate
// position newthing using the coordinates
newthing.style.position = "fixed"; // fixes el relative to page. Could use absolute.
newthing.style.left = x + "px";
newthing.style.top = y + "px";
}
/* Optional - Making new things more obvious in the pen */
input{
height: 10px;
width: 50px;
background: red;
}
#adivthing{
height: 600px;
width: 600px;
background: blue;
}
<!-- Onclick event added to your existing markup -->
<div id="adivthing" onclick="createInput(event)"></div>
Related
I have a resize observer re-positioning a div to overlay another element, and at first I tried to use the left and top properties of the ResizeObserver entry to position the div, but after some debugging I found that those properties were set to 0.
Unfortunately, I was not able to exactly replicate the problem within a stackoverflow snippet, and now all of the properties seem to be off, but getBoudingClientRect did work correctly when tried in the snippet, and in my original program, the right and bottom properties were correct.
const observer = new ResizeObserver(entries => {
const boundingRect = entries[0].contentRect;
console.log(boundingRect.x, boundingRect.y, boundingRect.top, boundingRect.left);
div.style.left = boundingRect.left + "px";
div.style.top = boundingRect.top + "px";
div.style.width = boundingRect.width + "px";
div.style.height = boundingRect.height + "px";
});
observer.observe(button);
#button {
position: absolute;
left: 50%;
top: 50%;
width: 50%;
height: 50%;
}
#div {
position: absolute;
background-color: #00000055;
}
<button id="button">some text</button>
<div id="div"></div>
From my understanding the contentRect object is supposed to be the same as using getBoundingClientRect, but as you can see from the snippet, it is far from correct. (no rhyme intended)
I have found a partial answer to my problem on the ResizeObserver spec page:
If target is not an SVG element do these steps:
Set this.contentRect.top to target.padding top.
Set this.contentRect.left to target.padding left.
If target is an SVG element do these steps:
Set this.contentRect.top and this.contentRect.left to 0.
Although this explains the "incorrect" coordinates, my original element was a normal div, not an SVG element, and the purpose for setting the left and right properties to 0 for SVGs is a mystery to me.
I am trying to make a right click lead to a div pop up. However, the click will be inside a cesium window, which only lets a div show if it has absolute position. Is it possible to edit the pop up position of a div with absolute position?
Right now, my code looks like this:
var editHandler = newCesium.ScreenSpaceEventHandler(scene.canvas);
editHandlersetInputAction(function(e){
var shapeEditMenu = document.getElementById("shapeEditMenu");
shapeEditMenu.style.display = "block";
shapeEditMenu.style.left = e.clientX;
shapeEditMenu.style.top = e.clientY;
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
#shapeEditMenu {
position: absolute;
display: none:
top: 80px;
height: 50px;
width: 80px;
}
<div id="shapeEditMenu">
Line thickness:
<input type="number"> pt
</div>
It doesn't work here because there isn't cesium, but what happens in my actual code is that the div pops up on right click, but always is at the same position, not at the place where you right click.
As mentioned in the comments, there is some API confusion going on here. clientX is part of browser-native API, not Cesium's API. Since you're using Cesium's event handling system, you get events from that API. In this case, you would use e.position.x and follow that up with a + 'px' to indicate CSS-pixel units for the stylesheet.
Also you have a few typos here:
newCesium. should be new Cesium.
editHandlersetInputAction should be editHandler.setInputAction
display: none: should be display: none;
Here's a live Sandcastle demo that shows a right-click "Testing" menu show up at the mouse location.
var viewer = new Cesium.Viewer('cesiumContainer');
var editHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
editHandler.setInputAction(function(e) {
var shapeEditMenu = document.getElementById("toolbar");
shapeEditMenu.textContent = 'Testing';
shapeEditMenu.style.display = "block";
shapeEditMenu.style.left = e.position.x + 'px';
shapeEditMenu.style.top = e.position.y + 'px';
shapeEditMenu.style.background = 'rgba(42, 42, 42, 0.8)';
shapeEditMenu.style.border = '1px solid #888';
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
editHandler.setInputAction(function(e) {
var shapeEditMenu = document.getElementById("toolbar");
shapeEditMenu.style.display = "none";
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);
I want to have an div under my mouse at all times, this div I want to use to display tool-tips.
This is the code i'm trying to use. But this code gives an error:
" Cannot read property 'pageX' of undefined"
My question is why is pageX undefined, and how do I fix this problem?
$( document ).ready(function() {
AppentMouse(); //Setup div that is used for mouse icon
window.setInterval(function(){
SetMouse(); //Set div that is used for mouse icon at mouse location
}, 5);
});
function AppentMouse(){
$( 'Body' ).append( "<div id='Mouse'>Mouse</div>");
}
function SetMouse(){
var e = window.event || e;
var left = e.pageX + "px";
var top = e.clientY + "px";
var div = document.getElementById('Mouse');
div.style.left = left;
div.style.top = top;
}
Considering this is your html code:
<body>
<div>Your content</div>
</body>
And you have these styles for the div:
div {
position: absolute;
border: solid 1px #fc0;
}
Using jQuery, attach mousemove event listener to the document and make the div to have top and left styles changed on every move:
$(document).on('mousemove', function(e){
$('div').css('top', e.pageY);
$('div').css('left', e.pageX);
});
See this JSFiddle
EDIT:
Considering your code, variable e is undefined. And the error says that an undefined value does not have a pageX property.
That is because you need an mouse event (for your case) to have object event defined. And that object is received by the event listener that we add in the code that I provided.
As for your code, you will have to bind the event to the div.
An easy way to do this would be to not dynamically generate the div, just show and hide it. (As in my example). This is faster as well.
Alternatively, each time you generate the div, define and trigger the set mouse event from within the function that generates it.
Providing an alternate way of doing this:
Firstly, the HTML. Add the following anywhere inside the body.
<div id="tooltip"></div>
Now the CSS (add more to make it look pretty):
#tooltip {
position: absolute;
display: inline-block;
opacity: 0;
}
Make a class called tips and have all elements that you wish to provide tool tips for, belong to that class.
And then the jQuery:
//For every element in ".tips" have an attribute "tooltiptext"
$('.tips').mouseenter(function(e) {
$("#tooltip").css("left", e.pageX + 10);
$("#tooltip").css("top", e.pageY+ 10);
$("#tooltip").html($(this).attr("tooltiptext"));
$("#tooltop").show();
});
$('.tips').mouseout(function() {
$("#tooltip").hide();
});
Do tell me if this works.
Let say I got this: http://puu.sh/6rqZc.jpg
How can I know the x/y or left/top properties of my canvas assuming that it is centered via this:
#canvas-container {
width: 100px;
height:100px;
margin: 0px auto;
}
Note: $('#myCanvas')[0].style.top returns ""
You can try to use offset() which will return the coordinates of the element relative to the document:
var eTop = $('#myCanvas').offset().top,
eLeft = $('#myCanvas').offset().left;
I think you need .offset() or .position():
if you need absolute left/top values:
var offLeft = $('#myCanvas').offset().left;
var offTop = $('#myCanvas').offset().top;
if you need relatively positioned elem's left/top values:
var posLeft = $('#myCanvas').position().left;
var posTop = $('#myCanvas').position().top;
Using JQuery
$('#myCanvas').eq(0).offset();
// or
$('#myCanvas:first').offset();
I have two columns in my HTML page.
<div id="content">
<div id="left"></div>
<div id="right"></div>
</div>
Each of them occupies half of the page
#content {
height: 100%;
}
#left, #right {
float: left;
width: 50%;
height: 100%;
overflow: auto;
}
I'd like the boundary between left and right halves to be adjustable by the user. That is, the user can move the boundary to the left or to the right as he/she browses the page. Is it possible to do that somehow?
Yes, but it requires JavaScript. To apply it, you could of course just set the width of each of the sides:
var leftPercent = 50;
function updateDivision() {
document.getElementById('left').style.width = leftPercent + '%';
document.getElementById('right').style.width = (100 - leftPercent) + '%';
}
Now you can adjust the division with, say leftPercent = 50; updateDivision(), but the user isn't going to do that. There are multiple different ways you could present this to the user. Probably the best-suited way would be a little line in the middle they could drag. For this, you could use a little CSS for the positioning:
#content {
position: relative;
}
#divider {
position: absolute;
/* left to be set by JavaScript */
width: 1px;
top: 0;
bottom: 0;
background: black;
cursor: col-resize;
/* feel free to customize this, of course */
}
And then make sure you've got a div with an id of divider in content and update updateDivision to also update the left of divider:
document.getElementById('left').style.left = leftPercent + '%';
Then you just need a little logic to handle the dragging. (Here, I've put all of the elements into appropriately-named variables):
divider.addEventListener('mousedown', function(e) {
e.preventDefault();
var lastX = e.pageX;
document.documentElement.addEventListener('mousemove', moveHandler, true);
document.documentElement.addEventListener('mouseup', upHandler, true);
function moveHandler(e) {
e.preventDefault();
e.stopPropagation();
var deltaX = e.pageX - lastX;
lastX = e.pageX;
leftPercent += deltaX / parseFloat(document.defaultView.getComputedStyle(content).width) * 100;
updateDivision();
}
function upHandler(e) {
e.preventDefault();
e.stopPropagation();
document.documentElement.removeEventListener('mousemove', moveHandler, true);
document.documentElement.removeEventListener('mouseup', upHandler, true);
}
}, false);
You should be able to read it to see how it works, but in short: It listens for when someone presses on the divider. When they do, it'll attach listeners to the page for when they move their mouse. When they do, it updates the variable and calls updateDivision to update the styles. When eventually it gets a mouseup, it stops listening on the page.
As a further improvement, you could make every element have an appropriate cursor style while dragging so your cursor doesn't flash while dragging it.
Try it out.
There's nothing in the divisions so nothing will happen. It's like writing:
<h1></h1>
And changing the CSS for h1 and expecting something to be there