I have a javascript code, using which an iframe moves with mouse pointer.
and when I slide mouse over another iframe (e.x youtube embed video), the iframe doesn't move with mouse while mouse pointer is on youtube video.
what can be done? thanks
<script type="text/javascript">
var opacity = 1;
var time = 3500000;
if (document.cookie.indexOf('visited=true') == -1) {
(function openColorBox() {
if ((document.getElementById) && window.addEventListener || window.attachEvent) {
var hairCol = "#ff0000";
var d = document;
var my = -10;
var mx = -10;
var r;
var vert = "";
var idx = document.getElementsByTagName('div').length;
var thehairs = "<iframe id='theiframe' scrolling='no' frameBorder='0' allowTransparency='true' src='b.html' style='margin: px 0px 0px px; position:fixed;width:200px;height:200px;overflow:hidden;border:0;opacity:" + opacity + ";filter:alpha(opacity=" + opacity * 100 + ");'></iframe>";
document.write(thehairs);
var like = document.getElementById("theiframe");
document.getElementsByTagName('body')[0].appendChild(like);
var pix = "px";
var domWw = (typeof window.innerWidth == "number");
var domSy = (typeof window.pageYOffset == "number");
if (domWw) r = window;
else {
if (d.documentElement && typeof d.documentElement.clientWidth == "number" && d.documentElement.clientWidth != 0) r = d.documentElement;
else {
if (d.body && typeof d.body.clientWidth == "number") r = d.body
}
}
if (time != 0) {
setTimeout(function() {
document.getElementsByTagName('body')[0].removeChild(like);
if (window.addEventListener) {
document.removeEventListener("mousemove", mouse, false)
} else if (window.attachEvent) {
document.detachEvent("onmousemove", mouse)
}
}, time)
}
function scrl(yx) {
var y, x;
if (domSy) {
y = r.pageYOffset;
x = r.pageXOffset
} else {
y = r.scrollTop;
x = r.scrollLeft
}
return (yx == 0) ? y : x
}
function mouse(e) {
var msy = (domSy) ? window.pageYOffset : 0;
if (!e) e = window.event;
if (typeof e.pageY == 'number') {
my = e.pageY - 0 - msy;
mx = e.pageX - 0
} else {
my = e.clientY - 6 - msy;
mx = e.clientX - 6
}
vert.top = my + scrl(0) + pix;
vert.left = mx + pix
}
function ani() {
vert.top = my + scrl(0) + pix;
setTimeout(ani, 300)
}
function init() {
vert = document.getElementById("theiframe").style;
ani()
}
if (window.addEventListener) {
window.addEventListener("load", init, false);
document.addEventListener("mousemove", mouse, false)
} else if (window.attachEvent) {
window.attachEvent("onload", init);
document.attachEvent("onmousemove", mouse)
}
}
})();
var oneDay = 1000 * 60 * 30;
var expires = new Date((new Date()).valueOf() + oneDay);
document.cookie = "visited=true;expires=" + expires.toUTCString()
}
</script>
<iframe width="420" height="315" src="https://www.youtube.com/embed/sTesehdHbqs" style="display:block; position:static;"frameborder="0" allowfullscreen></iframe>
Without seeing your HTML, the best guess is: you're not going to be able to do this. The issue is that, once you move your mouse into an iframe that has an origin different from your page, mouse events will not fire out to your script, and therefore you won't be able to update the position of your iframe. DEMO: Note how the mouse coordinates stop updating once you move your mouse pointer inside the iframe.
function mouseMoveListener() {
var outputX = document.querySelector('#mouseX');
var outputY = document.querySelector('#mouseY');
return function(ev) {
outputX.innerText = ev.clientX;
outputY.innerText = ev.clientY;
};
}
function test(ev) {console.log('ev::', ev.clientX);}
document.addEventListener('mousemove', mouseMoveListener());
<div>Mouse position:
<span id="mouseX"></span>
,
<span id="mouseY"></span>
</div>
<iframe src="http://www.example.com" width="200" height="200"></iframe>
If you don't need to let your users interact with the content of the iframe, you can cheat this by overlaying a transparent div on top of the iframe. That prevents mouse events from "falling through" to the iframe beneath them, while still showing the content of the iframe. DEMO: But note that the iframe doesn't allow you to scroll, since mouse events (like clicks on the scroll bar or wheel events) are captured by the overlay div.
function mouseMoveListener() {
var outputX = document.querySelector('#mouseX');
var outputY = document.querySelector('#mouseY');
return function(ev) {
outputX.innerText = ev.clientX;
outputY.innerText = ev.clientY;
};
}
function test(ev) {console.log('ev::', ev.clientX);}
document.addEventListener('mousemove', mouseMoveListener());
#iframe-wrapper {
position: relative;
}
#iframe-wrapper iframe {
position: relative;
z-index: 0;
}
#iframe-wrapper .overlay {
position: absolute;
background: transparent;
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index: 2;
}
<div>Mouse position:
<span id="mouseX"></span>
,
<span id="mouseY"></span>
</div>
<div id="iframe-wrapper">
<iframe src="http://www.example.com" width="200" height="200"></iframe>
<div class="overlay"></div>
</div>
However, if you're displaying a YouTube video, it's unlikely this will satisfy your requirements, since user interaction is a key part of the viewing experience.
Related
Can you recommend a JS library that actually provides edge swipe functionality when working with bare-bones HTML & CSS?
I've searched all over and haven't found a source of truth for that problem.
I've seen lots and lots of libraries enabling swipe gestures but not edge swipe.
My last attempt was using Hammer.js which I've tried implementing as:
var swipe = new Hammer(document);
// detect swipe and call to a function
swipe.on('swiperight swipeleft', function (e) {
e.preventDefault();
var endPoint = e.pointers[0].pageX;
var distance = e.distance;
var origin = endPoint - distance;
//swipe right to open nav
if (origin <= 15 && e.type == 'swiperight') {
// open main menu
$('#navigation-menu').animate({
left: '0'
});
} else {
// close/hide menu(s)
$('#navigation-menu').animate({
left: '-100%'
});
}
});
Further, if not using any library, how can I implement a mobile edge swipe to show and hide content, (in my case it'd be a navigation menu) with vanilla JS?
At this point I'm open to either solution/direction.
Here is a solution, you can set thresholdStart, End, Milliseconds. You may want to tidy up the code, and port it for touch events (I used mouse events for testing in my browser more easily).
Use:
swipeEdgeFromLeft function and swipeEdgeFromRight function.
var div = document.body;
var mouse = {
isDown: false,
inLeft: false,
inRight: false,
downTimestamp: null
};
var width, thresholdStart, thresholdEnd, thresholdMilliseconds;
function resize(){
width = window.innerWidth;
thresholdStart = 0.1*width;//within 10% of screen width
thresholdEnd = 0.13*width;//beyond 13% of screen width
thresholdMilliseconds = 500;//must be done in 500 milliseconds
}
document.addEventListener("resize", resize, false);
resize();//initialize
div.addEventListener('mousedown'/*'touchstart'*/, function(e){
var x = e./*touches[0].*/pageX;
mouse.isDown = true;
mouse.downTimestamp = performance.now();
if(x < thresholdStart){
mouse.inLeft = true;
} else if(x > width-thresholdStart){
mouse.inRight = true;
}
});
div.addEventListener('mousemove'/*'touchmove'*/, function(e){
var x = e./*touches[0].*/pageX;
if(mouse.inLeft && x > thresholdEnd){
mouse.inLeft = false;
if(performance.now() - mouse.downTimestamp < thresholdMilliseconds){
swipeEdgeFromLeft();
}
} else if(mouse.inRight && x < width-thresholdEnd){
mouse.inRight = false;
if(performance.now() - mouse.downTimestamp < thresholdMilliseconds){
swipeEdgeFromRight();
}
}
});
div.addEventListener('mouseup'/*'touchend'*/, function(e){
//var x = e./*changedTouches[0].*/pageX;
mouse.isDown = false;
mouse.inLeft = false;
mouse.inRight = false;
mouse.downTimestamp = null;
});
function swipeEdgeFromLeft(){
console.log("edge swipe from left");
}
function swipeEdgeFromRight(){
console.log("edge swipe from right");
}
body {
max-width: 100vw;
height: 100vh;
}
.bar {
height: 100vh;
background-color: rgba(0,0,0,0.4);
position: fixed;
pointer-events: none;
}
#left-inner-threshold {
width: calc(0.1 * 100vw);
left: 0;
}
#right-inner-threshold {
width: calc(0.1 * 100vw);
right: 0;
}
#left-outer-threshold {
width: calc(0.13 * 100vw);
left: 0;
}
#right-outer-threshold {
width: calc(0.13 * 100vw);
right: 0;
}
<div id="left-inner-threshold" class="bar"></div>
<div id="left-outer-threshold" class="bar"></div>
<div id="right-inner-threshold" class="bar"></div>
<div id="right-outer-threshold" class="bar"></div>
Here's a solution to your existing code using Hammer.js v2.0.8
The explanation for how to achieve the edge swipe can be found here answered by #jovinbm.
$(document).ready(function () {
const swipe = new Hammer(document);
function getStartPosition(e) {
const delta_x = e.deltaX;
const delta_y = e.deltaY;
const final_x = e.srcEvent.pageX || e.srcEvent.screenX || 0;
const final_y = e.srcEvent.pageY || e.srcEvent.screenY || 0;
return {
x: final_x - delta_x,
y: final_y - delta_y
}
};
swipe.on('swiperight swipeleft', function (e) {
e.preventDefault();
const { x } = getStartPosition(e);
console.log(x);
//swipe right to open nav /* note the condition here */
if (e.type == 'swiperight' && x >= 0 && x <= 50) {
// open menu
$('#navigation').animate({
left: '0'
});
//swiping left should slide out nav and/or sub-nav
} else {
// close/hide menu
$('#navigation, #task-menu').animate({
left: '-100%'
});
}
});
});
Here's a pen showing it in action:
For swipes, only the final pointerup event is included as the srcEvent in the event object passed to your handler (see http://hammerjs.github.io/api/). The initial pointerdown event that carries the details of the initial position of where the swipe event started is not provided in the hammer event object. Fortunately, you can use the srcEvent in the event object to get the starting position of the event initial pointerdown event.
const getStartPosition = (e) => {
const delta_x = e.deltaX;
const delta_y = e.deltaY;
const final_x = e.srcEvent.pageX || e.srcEvent.screenX || 0;
const final_y = e.srcEvent.pageY || e.srcEvent.screenY || 0;
return {
x: final_x - delta_x,
y: final_y - delta_y
};
};
const handleSwipe = (e) => {
const {x} = getStartPosition(e);
if (x >= 0 && x <= 50) {
// handle swipe from left edge e.t.c
}
else {
// handle other case
}
};
The srcEvent is just a normal javascript event that inherits properties from UIEvent hence the pageX/pageY api above. This will probably not work in other browsers since some of them are not standardized
I was working on collision detection and thought I would start out simple by testing when the object reaches a certain x-position. It works when I set it to 100, the initial top value for 'character, which leads me to believe the problem is with top updating; however, I don't see why the circles would be moving if that were the case.If you could tell me how to keep 'top' updated or better yet, help me with collision detection that would be great!
(ps. I know it's not good to put css, javascript, and html in one page. I have this as part of a website but moved it to one file so I could test it separately without looking through the code of the entire website and I will add it in the appropriate files once I get this figured out.)
<html>
<head>
<style>
#character {
position: absolute;
width: 42px;
height: 42px;
background: black;
border-radius: 50%;
}
#character2 {
position: absolute;
width: 42px;
height: 42px;
background: pink;
border-radius: 50%;
} </style>
</head>
<body>
<div id = 'character'></div>
<div id = 'character2'></div>
<script>
var keys = {};
keys.UP = 38;
keys.LEFT = 37;
keys.RIGHT = 39;
keys.DOWN = 40;
keys.W = 87;
keys.A = 65;
keys.D = 68;
keys.S = 83;
/// store reference to character's position and element
var character = {
x: 1000,
y: 100,
speedMultiplier: 1,
element: document.getElementById("character")
};
var character2 = {
x: 100,
y: 100,
speedMultiplier: 3,
element: document.getElementById("character2")
};
/// key detection (better to use addEventListener, but this will do)
document.body.onkeyup =
document.body.onkeydown = function(e){
/// prevent default browser handling of keypresses
if (e.preventDefault) {
e.preventDefault();
}
else {
e.returnValue = false;
}
var kc = e.keyCode || e.which;
keys[kc] = e.type == 'keydown';
};
/// character movement update
var moveCharacter = function(dx, dy){
character.x += (dx||0) * character.speedMultiplier;
character.y += (dy||0) * character.speedMultiplier;
character.element.style.left = character.x + 'px';
character.element.style.top = character.y + 'px';
};
var moveCharacter2 = function(dx, dy){
character2.x += (dx||0) * character2.speedMultiplier;
character2.y += (dy||0) * character2.speedMultiplier;
character2.element.style.left = character2.x + 'px';
character2.element.style.top = character2.y + 'px';
};
/// character control
var detectCharacterMovement = function(){
if ( keys[keys.LEFT] ) {
moveCharacter(-1, 0);
}
if ( keys[keys.RIGHT] ) {
moveCharacter(1, 0);
}
if ( keys[keys.UP] ) {
moveCharacter(0, -1);
}
if ( keys[keys.DOWN] ) {
moveCharacter(0, 1);
}
if ( keys[keys.A] ) {
moveCharacter2(-1, 0);
}
if ( keys[keys.D] ) {
moveCharacter2(1, 0);
}
if ( keys[keys.W] ) {
moveCharacter2(0, -1);
}
if ( keys[keys.S] ) {
moveCharacter2(0, 1);
}
};
/// update current position on screen
moveCharacter();
moveCharacter2();
/// game loop
setInterval(function(){
detectCharacterMovement();
}, 1000/24);
function getPosition() {
var elem = document.getElementById("character");
var top = getComputedStyle(elem).getPropertyValue("top");
if (top == '200px') {
alert ("hi");
}
getPosition()
}
getPosition()
// var pos1 = document.getElementById('character').style.top
</script>
</body>
</html>
I figured it out! I just added Jquery's .position() to get the coordinates! For the collision detection I added this:
function collision1() {
$(document).ready(function(){
var x = $("#character").position();
var y = $("#character2").position();
var zid = '#' + id
var z = $(zid).position();
var topX = parseInt(x.top);
var topZ = parseInt(z.top);
var leftX = parseInt(x.left);
var leftZ = parseInt(z.left);
var topY = parseInt(y.top);
var leftY = parseInt(y.left);
if (topX > topZ && topX < (topZ + 50) && leftX > leftZ && leftX < (leftZ + 100)) {
alert('Player 1 Won! Click restart to play again.')
document.getElementById("button2").style.display = "block";
document.getElementById("def").style.display = "none";
document.getElementById("def2").style.display = "none";
document.getElementById("def3").style.display = "none";
document.getElementById("def4").style.display = "none";
document.getElementById("term").style.display = "none";
}
else {
collision1()}
});}
I know it is probably not the most effective way to program this but it works!
I was making my own flexible javascript DnD script when I encountered an error. The div moves perfectly fine the first time, but the remaining times, it messes up the offset. I know what everyone is probably going to say; "why don't you use a library?". The reason is because having my own personally designed script is easier to edit and understand. There is probably a more efficient way to do this, but here is the code:
document.onmousemove = mouseCoords;
var x = 0;
var y = 0;
var cl1= false;
var time1= true;
var divid;
var offs1;
var offs2;
function mouseCoords(e) {
x = e.x
y = e.y
if(cl1 === true){
document.getElementById(divid).style.top= y-offs1+"px";
document.getElementById(divid).style.left= x-offs2+"px";
}
}
var drag1 = function(i, cas) {
divid= i
if(time1=== true){
cl1= true
time1= false
}else{
cl1= false
time1= true
}
switch(cas){
case 0:
offs1 = 0;
offs2 = 0;
break;
case 1:
offs1 = y;
offs2 = x;
break;
}
}
<div id="1" onmousedown="drag1(1, 1);" onmouseup="drag1(1, 0);" style="background-color: yellow; width: 500px; height: 300px; position: fixed;"></div>
The first time there are no hiccups, but all proceeding times, the offset isn't close enough to the mouse to function almost seamlessly. How do I make the script work like it does the first time, every time? (It doesn't show up as much in the snippet.)
I added considering current div coordinates. It seems to work more stably:
document.onmousemove = mouseCoords;
var x = 0;
var y = 0;
var cl1= false;
var divid;
var offs1;
var offs2;
var _top;
var _left;
function mouseCoords(e) {
x = e.x
y = e.y
if(cl1 === true){
document.getElementById(divid).style.top = _top + (y-offs1) + 'px';
document.getElementById(divid).style.left = _left + (x-offs2) + 'px';
}
}
var drag1 = function(i, cas) {
divid= i
switch(cas){
case 0:
offs1 = 0;
offs2 = 0;
cl1= false;
break;
case 1:
var rect = document.getElementById(divid).getBoundingClientRect();
_left = rect.left;
_top = rect.top;
offs1 = y;
offs2 = x;
cl1= true;
break;
}
}
<div id="1" onmousedown="drag1(1, 1);" onmouseup="drag1(1, 0);" style="background-color: yellow; width: 500px; height: 300px; position: fixed;"></div>
I am developing an web application where I am trying simulate a popup window using tags , for style purpose. I done this with this javascript code:
<script>
function handleClick(url){
document.getElementById("results").style.display = 'block';
document.getElementById("about").innerHTML='<object type="text/html" data="'+url+'" ></object>';
}
function cleanDiv() {
document.getElementById("results").style.display = 'none';
document.getElementById("about").innerHTML=' ';
}
</script>
associated to this html code:
<section class="about" id="results">
<div align="right">Fechar</div>
<div id="about" algin="center"></div>
</section>
and the style is on my css file.
I have almost all what I want, but I wish this "popup window" don't stay fixed in a unique position on the page, and the user could move it around with the mouse.
Someone knows how to make this with javascript/html/css only?
You are looking for the HTML5 draggable attribute and events. Make the element draggable by setting draggable="true" and ondragstart="dragElem(event)". Then write your code in function dragElem(ev) { }. See W3Schools
After more search, I ended with this code, from site http://waseemblog.com/42/movable-div-using-javascript.html
html:
<section class="about" id="results" style="left: 183px; top: 111px;" onMouseDown="dragStart(event, 'results');">
<div align="right">X</div>
<div id="content" align="center"></div>
</section>
javascript:
function getID(id)
{
return document.getElementById(id);
}
// Global object to hold drag information.
var dragObj = new Object();
function dragStart(event, id) {
var x, y;
dragObj.elNode = getID(id);
// Get cursor position with respect to the page.
try {
x = window.event.clientX + document.documentElement.scrollLeft
+ document.body.scrollLeft;
y = window.event.clientY + document.documentElement.scrollTop
+ document.body.scrollTop;
}
catch (e) {
x = event.clientX + window.scrollX;
y = event.clientY + window.scrollY;
}
// Save starting positions of cursor and element.
dragObj.cursorStartX = x;
dragObj.cursorStartY = y;
dragObj.elStartLeft = parseInt(dragObj.elNode.style.left, 10);
dragObj.elStartTop = parseInt(dragObj.elNode.style.top, 10);
if (isNaN(dragObj.elStartLeft)) dragObj.elStartLeft = 0;
if (isNaN(dragObj.elStartTop)) dragObj.elStartTop = 0;
// Capture mousemove and mouseup events on the page.
try {
document.attachEvent("onmousemove", dragGo);
document.attachEvent("onmouseup", dragStop);
window.event.cancelBubble = true;
window.event.returnValue = false;
}
catch (e) {
document.addEventListener("mousemove", dragGo, true);
document.addEventListener("mouseup", dragStop, true);
event.preventDefault();
}
}
function dragGo(event) {
var x, y;
// Get cursor position with respect to the page.
try {
x = window.event.clientX + document.documentElement.scrollLeft
+ document.body.scrollLeft;
y = window.event.clientY + document.documentElement.scrollTop
+ document.body.scrollTop;
}
catch (e) {
x = event.clientX + window.scrollX;
y = event.clientY + window.scrollY;
}
// Move drag element by the same amount the cursor has moved.
var drLeft = (dragObj.elStartLeft + x - dragObj.cursorStartX);
var drTop = (dragObj.elStartTop + y - dragObj.cursorStartY);
if (drLeft > 0)
{
dragObj.elNode.style.left = drLeft + "px";
}
else
{
dragObj.elNode.style.left = "1px";
}
if (drTop > 0)
{
dragObj.elNode.style.top = drTop + "px";
}
else
{
dragObj.elNode.style.top = "1px";
}
try {
window.event.cancelBubble = true;
window.event.returnValue = false;
}
catch(e){
event.preventDefault();
}
}
function dragStop(event) {
// Stop capturing mousemove and mouseup events.
try {
document.detachEvent("onmousemove", dragGo);
document.detachEvent("onmouseup", dragStop);
}
catch (e) {
document.removeEventListener("mousemove", dragGo, true);
document.removeEventListener("mouseup", dragStop, true);
}
}
It can be bigger than your counterpart using jquery, but I guess it works fine in most browsers available today.
I want stop my function that run with setTimeout and do not show image followed mouse. I want do that with button click, how do that?
my code:
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title></title>
<script type="text/javascript">
var trailimage = ["test.gif", 100, 99];
var offsetfrommouse = [-25, -25];
var displayduration = 0;
function truebody() {
return (!window.opera && document.compatMode && document.compatMode != "BackCompat") ? document.documentElement : document.body;
}
function hidetrail() {
var x = document.getElementById("trailimageid").style;
x.visibility = "hidden";
document.onmousemove = "";
}
function followmouse(e) {
var xcoord = offsetfrommouse[0];
var ycoord = offsetfrommouse[1];
if (typeof e != "undefined") {
xcoord += e.pageX;
ycoord += e.pageY;
}
else if (typeof window.event != "undefined") {
xcoord += truebody().scrollLeft + event.clientX;
ycoord += truebody().scrollTop + event.clientY;
}
var x = document.getElementById("trailimageid").style;
x.left = xcoord + "px";
x.top = ycoord + "px";
}
alert("obj_selected = true");
document.onmousemove = followmouse;
if (displayduration > 0)
setTimeout("hidetrail()", displayduration * 1000);
</script>
</head>
<body>
<form id="form1" runat="server">
<img alt="" id="trailimageid" src="Pictures/sides/sides-not-clicked.gif" border="0" style="position: absolute; visibility: visible; left: 0px;
top: 0px; width: 50px; height: 50px"/>
</form>
</body>
</html>
var foobarTimeout = setTimeout(foobar, 1000);
...
clearTimeout(foobarTimeout);
See:
https://developer.mozilla.org/en/DOM/window.setTimeout
https://developer.mozilla.org/en/DOM/window.clearTimeout
Save the return value of setTimeout, which is a "handle" for the timer, and when you want to cancel it, call clearTimeout with that value.
So in your code, you'd declare a timerHandle variable somewhere appropriate, then set it here:
if (displayduration > 0)
timerHandle = setTimeout("hidetrail()", displayduration * 1000);
...and then create a button click handler:
function cancelTimeoutOnClick() {
if (timerHandle) {
clearTimeout(timerHandle);
timerHandle = 0;
}
}
Off-topic: It's almost never best practice to pass strings into setTimeout, that's an implicit eval. In your case, just pass the function reference:
if (displayduration > 0)
timerHandle = setTimeout(hidetrail, displayduration * 1000);
// ^--- Difference here (no quotes, no parentheses)
you use timeout like >
var myTimeout = setTimeout(yourfunction);
and then you can cancel it >
clearTimeout(myTimeout);