i'm creating a loading Screen for a FiveM server, the thing is I want to display a cursor and FiveM doesn't allow that in the loading screen (we can move the mouse, but the cursor is not showing). So in JS i've created a little script to display a cursor*(image)* depending on the mousemove event:
window.onload = function()
{
document.body.addEventListener("mousemove", function(event)
{
var cursor = document.getElementById("cursor");
var x = event.clientX - cursor.width + 23;
var y = event.clientY - 6;
// console.log("x="+x+" - y="+y);
$("#cursor").css({
"left": x+"px",
"top" : y+"px"
});
});
}
My script works well, but not on iframe, the cause is that when the cursor is on the iframe, the JS script doesn't works anymore (it doesn't apply the left/top position so the cursor stays outside of the iframe).
I tried modifying my css but in vain (here it is, i think it will help):
#cursor
{
position: absolute;
z-index: 99999!important;
pointer-events: none;
width: 40px;
}
iframe {
z-index: 1;
}
My question is, is it possible to mouve an image hover the iframe (and still being able to use the iframe) ?
Thanks for your help.
Related
I'm trying to solve an issue with css "position:fixed" property on mobile browsers. I have a fixed div:
<div id="logo">
...other content here...
</div>
with css:
#logo{
position: fixed;
-webkit-backface-visibility: hidden;
bottom: 100px;
right: 0px;
width: 32px;
height: 32px;
}
So, usually the behaviour is exactly the desired one, with the div position always on the bottom right of the window, indipendently of the scroll position.
My issue is that on mobile browsers, when the users zoom the page, after a certain zoom level the div position is wrong (sometimes the div disappear out of the window).
I know that fixed position is not well supported on mobile browsers, but I wonder if there is some workaround. I tried with this js code onScroll event:
window.addEventListener('scroll', function(e){
drag.style['-webkit-transform'] = 'scale(' +window.innerWidth/document.documentElement.clientWidth + ')';\\I want to avoid zoom on this element
var r = logo.getBoundingClientRect();
var w = window.innerWidth;
var h = window.innerHeight;
if(r.right != w){
rOff = r.right - w;
logo.style.right = rOff;
}
if(r.top+132 != h){\
tOff = r.top + 132 - h;
logo.style.bottom = tOff;
}
});
Unfortunately, the code seems to return the wrong position.
Does anyone have any tip?
Ok, that's how I solved the issue...I hope that could help anyone to simulate fixed position on iOS devices.
I switched the position from fixed to absolute;
Attach to window a listener to get the new position when the page is scrolled or zoomed,
setting window.onscroll and window.onresize events with the following function:
function position() {
drag.style.left = window.innerWidth + window.pageXOffset - 32 + 'px';
drag.style.top = window.innerHeight + window.pageYOffset - 132 + 'px';
}
Do you want to catch if zoom is active?
There's no window.onZoom listener, but you can read this thread:
Catch browser's "zoom" event in JavaScript
and this answer: https://stackoverflow.com/a/995967/3616853
There's no way to actively detect if there's a zoom. I found a good entry here on how you can attempt to implement it.
I’ve found two ways of detecting the zoom level. One way to detect zoom level changes relies on the fact that percentage values are not zoomed. A percentage value is relative to the viewport width, and thus unaffected by page zoom. If you insert two elements, one with a position in percentages, and one with the same position in pixels, they’ll move apart when the page is zoomed. Find the ratio between the positions of both elements and you’ve got the zoom level. See test case. http://web.archive.org/web/20080723161031/http://novemberborn.net/javascript/page-zoom-ff3
You could also do it using the tools of the above post. The problem is you're more or less making educated guesses on whether or not the page has zoomed. This will work better in some browsers than other.
There's no way to tell if the page is zoomed if they load your page while zoomed.
Just a theory, but you may want to try setting the bottom/right positions in % rather than px.
I think what you're seeing when using pixel measurements is just the zoom effecting the pixels. Or to put it better, when you zoom-in the pixels appear larger and that throws off the position of the element, even pushing it out of the view-port on smaller screens.
Example using pixel positioning
Notice that even on a desktop as you zoom-in and out the element appears to move up and down?
Example using percent positioning
In this example the element appears to stay in the bottom right corner, because it is always positioned at 10% from the bottom of the view-port.
#logo{
position: fixed;
-webkit-backface-visibility: hidden;
bottom:10%;
right: 0;
width: 32px;
height: 32px;
}
Having two different z-index for the logo and the rest of the page could help. Allowing zooming only to the rest of the page and not to the z-index layer where logo is included. So, this might not affect the stretching on the logo.
We can
Implement a ZOOM listener
Attach it to browser
Make the zoom listener change the zoom level of the element (modify the elements position) using z-index as a factor.
take a look at the first panel (in red) on the homepage.
http://www.boomtown.co.za/
I'd like to do something like this with an invisible image and only reveal parts of it as the mouse tracks over. Is this possible without using Flash?
This can be done quite easily using some css and background positioning with javascript. Here's 2 examples : http://jsbin.com/ococal/3
The source code is quite easy to understand and you can start working out with this.
You could do it by using a transparent png image that was a radial fade from transparent in the centre to semi-transparent at the edges and making it follow the mouse.
document.onmousemove=mousefollower
function mousefollower(e){
x = (!document.all)? e.pageX : event.x+document.body.scrollLeft;
y = (!document.all)? e.pageY : event.y+document.body.scrollTop;
document.getElementById('myImage').style.left = x + 'px';
document.getElementById('myImage').style.top = y + 'px';
}
Obviously you can use jQuery for this too, and set the mousemove function to occur only over a specific div. Also make sure the image you use is large enough (at least twice the size) so that the edges don't show up when you move to the far sides of the div (this means that for large areas you will need a huge image so it may get a big laggy). Put the image in the div and set overflow to none to clip anything that falls outside of the area.
It is possible yes, but only in modern browsers (chrome, safari, firefox, opera).
You would need to have two <div>'s
like so..
<div class="container">
<div class="revealer"></div>
</div>
and CSS like so
.container {
position: relative;
background: url("images/your-background.jpg");
}
.revealer {
position: absolute;
//set the mask size to be the size of the container
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index: 1;
background: url("images/your-background-over-state.jpg");
//css3 image masks, this is not cross browser, see the demo for
// cross browser syntax
mask: url("images/mask-shape.png") no-repeat;
//make sure the mask is off screen at first, by setting the mask position
//to minus the width and height of your mask image
mask-position: -300px -300px
}
And the JS
window.addEventListener('load',function(){
var background = document.querySelector('.container'),
revealer = document.querySelector('.revealer');
background.addEventListener('mousemove', function(e){
//the minus represents the half the width/height of your mask image
// to make the reveal centred to the mouse.
var x = e.offsetX - 150,
y = e.offsetY - 150;
// move the position of the mask to match the mouse offsets
revealer.style.maskPosition = x+'px '+y+'px';
return false;
});
});
Because of the way this works you need to ensure that any other content in the .container has a higher z-index than the mask to ensure the content is not masked. To do this add relative positioning to the elements in the container
like so
.container *:not(.revealer) {
position: relative;
z-index: 2;
}
Images used in masks are images where the solid colours create the visible or fill area, and the transparent areas are the mask or cut out.
Demo with cross browser code
I've been having trouble coming up with a way of making a drag and drop area on a web page. I have multiple resizable <div>s, and I want to be able to drag these anywhere. Think of it like dragging desktop icons around the desktop and placing them anywhere. It would be nice if I could add buttons to these <div>s to change their z-indexes and have them overlap. Would this require use of <canvas>? I am currently using <section> for the drag area.
Thanks!
If you want to do the drag-n-drop yourself, you may want to have one div enclosing the draggable div, so you can use the top of the larger div as the draggable area.
So, you have
<div id='draggablediv' style='backgroundcolor: blue;'>
<div class='draggable' style='position: relative; top: 5em; left: 0em;'>...
</div></div>
This code is purely for example, won't work, btw.
So, on the draggablediv you would put an onclick event handler, and this would start an onmousemove handler and onmouseup handler. The last one is to drop, but you may also want to have onblur in case the mouse moves outside of the browser.
Then, as the mouse moves, just reposition the div, so these divs would need to be absolute positioned, or relative positioned (absolute would be easier).
It is important to remove the event handlers by setting them to null when the mouse button is released.
If not in a droppable area then make certain to put the div back where it started, so you will want a closure so you can remember the original top/left coordinates of the div.
You will want to get familiar with this functionality:
(function g(someval) {
var a = someval;
return h() {
}
})(origval);
For an example search for getImgInPositionedDivHtml in http://jibbering.com/faq/notes/closures/
In order to change the z-index you may want to have a +/- in the div and when that is clicked on the z-index is changed.
Here is a page that talks about changing the z-index.
http://msdn.microsoft.com/en-us/library/ms533005(v=vs.85).aspx
I don't think you can do that with HTML-Only, however this is some example of how you could do it with javascript:
<html>
<head>
<style>
.draggable {
position: absolute;
cursor: default;
background-color: purple;
top: 0px;
left: 0px;
}
</style>
</body>
<body onmouseup="stopMovement()">
<div id="draggable" class="draggable" onmousedown="startMovement(event)">
Drag me around :D
</div>
<script>
var drg = document.getElementById("draggable");
var xDisplacement = 0;
var yDisplacement = 0;
function startMovement(e) {
xDisplacement = e.pageX - getComputedStyle(drg).left.substring(0, getComputedStyle(drg).left.length - 2);
yDisplacement = e.pageY - getComputedStyle(drg).top.substring(0, getComputedStyle(drg).top.length - 2);
document.body.onmousemove = moveDraggable;
}
function stopMovement() {
document.body.onmousemove = null;
}
function moveDraggable(e) {
drg.style.top = e.pageY - yDisplacement;
drg.style.left = e.pageX - xDisplacement;
}
</script>
</body>
</html>
The site I'm working on has a collection of navigation elements across the top ("Products", "Company", etc.). When you mouse over the Products link, an overlay appears that shows a list of products with links to each. There's a small link at the top of the container that, when clicked, closes the container. All of this works as advertised.
The client has asked that, once a user's mouse pointer is a sufficient distance from the overlay element, the overlay element would close (without them having to click the 'close' link). This element appears on multiple pages that have disparate content, so I'm afraid it won't be as simple as adding a mouseover listener to another single element within the page and have it work everywhere. My question, I suppose, is this: is there a relatively easy way to know when the mouse cursor is x pixels away from this container and trigger an event when this occurs?
My other thought is that I could just find several elements on the page that fit this criteria and add mouseover listeners to each, but I'm assuming there's a more elegant way of handling this.
Thanks in advance - and please let me know if more detail is needed.
Here's one example.
http://jsfiddle.net/CsgFk/
Calculate the bounds you want around the overlay, and set up a mousemove hanlder on the document, which tests to see if the mouse is outside the bounds.
EDIT: It may be worthwhile to unbind the mousemove from the document when the overlay is hidden, and rebind it when revealed so that the mousemove isn't constantly firing for no reason. Or at the very least, have the mousemove handler check to see if the overlay is already hidden before hiding it.
HTML
<div id='overlay'></div>
CSS
#overlay {
width: 200px;
height: 200px;
background: orange;
position: relative;
top: 123px;
left:23px;
}
jQuery
var $ovl = $('#overlay');
var offset = $ovl.offset();
var height = $ovl.height();
var width = $ovl.width();
var bounds = {top: offset.top - 100,
bottom: offset.top + height + 100,
left: offset.left - 100,
right: offset.left + width + 100
}
$ovl.mouseenter(function() {
$ovl.stop().animate({opacity:1});
});
$(document).mousemove(function(e) {
if(e.pageX < bounds.left ||
e.pageX > bounds.right ||
e.pageY < bounds.top ||
e.pageY > bounds.bottom) {
$ovl.stop().animate({opacity:.3});
}
});
EDIT:
Here's another idea (although it is heavily dependent on your layout). Place the overlay inside a container that has a large padding and remove the overlay when the pointer performs a mouseleave on the container. Again, this may not be feasible in your layout.
EDIT:
One other idea would be to set a delay on the code used to remove the overlay. Its not as precise, but may yield a sufficiently desirable effect.
Why not use a mouseout event with a timer?
var zGbl_OverlayCloseTimer = '';
OverlayElement.addEventListener ("mouseout", CloseOverlayWithDelay, false);
function CloseOverlayWithDelay (zEvent)
{
if (typeof zGbl_OverlayCloseTimer == "number")
{
clearTimeout (zGbl_OverlayCloseTimer);
zGbl_OverlayCloseTimer = '';
}
zGbl_OverlayCloseTimer = setTimeout (function() { CloseOverlay (); }, 333);
}
function CloseOverlay ()
{
...
}
Here's what is happening:
After the page loads, JavaScript reads an XML from the underlying code
The XML contains a bunch of field-ids, and corresponding content to display in popups when the mouse hovers over a field id listed
My code generates a bunch of popups as div-elements with the styles:
.render{
background-color: #fffc80;
border: .1em solid rgb(200, 128, 0);
padding-left: 2px;
padding-right: 2px;
z-index: 1000;
}
.hide{
display:none;
}
All created popups are attached to the root element.
EDITED: Added script snippets
The event handlers are attached as below
// instantiate a div element
var myDiv = document.createElement('div');
// generate an ID
myDiv.id = generatePopupId(getFieldId());
// attach the content from the XML into the new div element
myDiv.innerHTML = getPopupContent();
// apply mouseover/out handlers to the main element
document.getElementById(getFieldId()).onmouseover = function(){
showPopup(generatePopupId(getFieldId()));
};
document.getElementById(getFieldId()).onmouseout = function(){
hidePopup(generatePopupId(getFieldId()));
};
// read the X coordinate of the present position of the mouse
function getX(){
var e = window.event;
posX = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
return posX;
}
// read the Y coordinate of the present position of the mouse
function getY(){
var e = window.event;
posY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
return posY;
}
// Show the popup element at the current mouse location
function showPopup(popupId){
var posX = getX();
var posY = getY();
var poppyElement = document.getElementById(popupId);
poppyElement.className = 'render';
poppyElement.style.left = posX;
poppyElement.style.top = poxY;
poppyElement.style.position = 'absolute';
poppyElement.style.display = '';
}
// hide the popup element
function hidePopup(popupId){
var poppyElement = document.getElementById(popupId);
poppyElement.className = 'hide';
}
My question is - Why does the element flash, and disappear immediately instead of hanging around for the mouse-out event?
Changing the elements in the JavaScript may be modifying the element being hovered over, which may trigger the mouse out event by changing, rather than actually moving the mouse out of the co-ordinates.
Firstly, you need to be more careful with case sensitivity. It should be clientWidth (capital W) and top (small t). Secondly, when you set CSS left and top you must add a +'px' suffix to the value; an integer on its own is not valid.
Also if you want to know the height of the viewport, document.body is the wrong place to look. This will only work in IE Quirks Mode, which you generally want to avoid like the plague. Add a Standards Mode <!DOCTYPE declaration and you can use document.documentElement across browsers. (Or branch on window.innerHeight for non-IE browsers.)
In any case unless there is more CSS you aren't showing us, setting the left and top styles will have no effect at all because the .render divs are not position: absolute. You're not showing how exactly they are attached to the document, but since they are apparently not absolutely positioned, they're part of the document flow and may cause the page to shift/reflow when they're unhidden. If that causes the element being moused over to move, it will no longer be under the pointer and you'll get a mouseout event immediately.
(This would also happen with absolute positioning if the hovered item was underneath the place the pop-up appeared.)
(Also, the hiding/unhiding is a bit redundant. Leave style.display alone and just set className to either 'render' or 'render hide'.)