I spend hours to find a solution for click detection inside iframe and the result is, its not possible. We can only detect a shift in focus and all solutions that I could find anywhere do not work on either chrome or Firefox. or only register the first click because the focus can not be bring back programmatically in JavaScript.
I build a solution my self which works in Firefox and google chrome and detects every click. the only thing is it can differentiate between left/right click and I have no way of testing it on safari.
let mouseover = false,
tab = false;
function registerCLick(elem){
if(elem && elem.tagName == 'IFRAME' && !tab && mouseover){ // check if activeElement is iframe, not tab key action and mouseover iframe
console.log(elem.parentNode.getAttribute('data-id'));
};
tab = false;
};
document.addEventListener('mousemove', ()=>{ // this sets back the focus to document if the activeElement is iframe
var elem = document.activeElement;
if(elem && elem.tagName == 'IFRAME'){
window.focus();
};
});
document.addEventListener('keydown', (e)=>{ // ignore blur by Tab key
if(e.key == 'Tab'){
tab = true;
};
}, false);
window.addEventListener('blur', ()=>{
setTimeout(()=>{ // firefox take a bit longet to change the activeElement, we wait before checking if iframe is the active element
registerCLick(document.activeElement);
}, 500);
});
function frameListener(frame){ // eventlistener per iframe to know when hover
frame.addEventListener('mouseover', ()=>{
mouseover = true;
});
frame.addEventListener('mouseout', ()=>{
setTimeout(()=>{
mouseover = false;
}, 1000);
});
};
frameListener(iframe); // call function for each iframe with iframe element as parameter
I have not tested it on mobile browsers, if someone has time to check on mobile device and or safari. we might could build a solution that works good enough.
My question is, how can I make this better? make it differentiate between left/right click? and is there someone that could test it on safari?
I usually wrap the iframe on div and use event listeners on this div.
<div class='test'>
<iframe src="url" title="description"></iframe>
</div>
Related
For my project, I need to catch all the click outside the browser in Javascript. Is there a way to do that ? For example by asking the user the right access ?
I need a function like "onclick" that works even outside the browser.
There are various approaches for detecting when the focus moves out of the current page which would be a side effect of clicking outside the window if the window currently has focus.
Explicitly detecting clicks outside the page is not possible. It would be a security problem if a web page could monitor how the user interacts with other applications.
To detect click outside element with JavaScript, we can use the element’s contains method.
For instance, we write
const specifiedElement = document.getElementById("a");
document.addEventListener("click", (event) => {
const isClickInside = specifiedElement.contains(event.target);
if (!isClickInside) {
// ...
}
});
to select the element we want to check with getElemebntById.
Then we add a click listener for the whole page with document.addEventListener.
In the callback, we call specifiedElement.contains with event.target to check if we clicked inside the a element.
If it’s false, then we clicked outside of it.
javascript detect click outside of element
var ignoreClickOnMeElement = document.getElementById('someElementID');
document.addEventListener('click', function(event) {
var isClickInsideElement = ignoreClickOnMeElement.contains(event.target);
if (!isClickInsideElement) {
//Do something click is outside specified element
}
});
click outside javascript
// Vanilla js
var ignoreMe = document.getElementById("ignoreMe");
window.addEventListener('mouseup', function(event){
if (event.target != ignoreMe && event.target.parentNode != ignoreMe){
// Place your output
}
});
https://www.codegrepper.com/code-examples/javascript/javascript+detect+click+outside+of+element
I noticed that these function doesn't work good in Firefox, but does in Chrome.
I use these function in a game in Js to shoot bullet (left mouse click) and to create a fireball all around the player with the right click that burns everyone in a small radius.
document.onclick = function(event) {
if(!player){ //to avoid onclick to be used before calling Player();
return;
}
if(player.canAttack && player.distance >= 80) { //not for sword attack
performAttack(player);
player.canAttack = false;
}
if(player.distance < 80)
performAttack(player);
//event.preventDefault();
}
document.oncontextmenu = function(event) {
//hide default behaviour of right click -> no context menu popup
event.preventDefault();
if(player.obtainedGadjet > 0) {
player.pressingMouseRight = true;
performSpecialAttack(player);
}
}
In the performAttack function I set player.isStopped = true, so my updatePlayer() doesn't change player.x and player.y while he's attacking. The same for the fireball attack. I want my player stays there.
It works in chrome, my player stops, attacks,and then can moves again, but in Firefox if I right click it somethimes acts instead as I have left clicked, so shoot the magic ball, and maybe then the fireball too. Furthermore, my player ignore isStopped = true, it seems like in Firefox oncontextmenu has "lower priority" than other events.
Any idea?
Thanks
Please note that a click event contains information about which button was pressed. You can try yourself with something like:
document.addEventListener('click', function(ev){
console.log(ev.button);
});
And, yes, click events are fired when you right-click, even if you're doing something on related contextmenu events.
So your code should look a bit more like
document.addEventListener('click', function(ev){
if (ev.button === 0) {
// Perform primary action
} else if (ev.button === 2) {
// Perform secondary action
}
});
document.addEventListener('contextmenu', function(ev){
ev.preventDefault();
});
Using the same click event is advisable as said by Ivan. You may also want to read this other discussion here on SO about best practices and why it's not always good to disable default right click behaviour (i.e.: it's not always guaranteed to work).
This are the code that I currently have:
var interval;
function printPageState() {
console.log("active");
}
window.onfocus = function() {
console.log("focus");
clearInterval(interval);
interval = setInterval(printPageState, 2000);
};
window.onblur = function() {
console.log("blur");
clearInterval(interval);
};
window.onscroll = function() {
console.log("scroll");
if (!document.hasFocus())
document.getElementById("some-id").focus();
clearInterval(interval);
interval = setInterval(printPageState, 2000);
};
I'm attempting to create a user attention checker/page-pinging like functionality. the checker currently has an event handler for blur, focus, and scroll event.
And I'm having the problem that was stated above when the following stuff are met.
Your browser had some viewable part on the browser view port which make it possible to scroll even if the page was not in focus.
The page was out of focus and or blur event was already fired.
I want to stop the interval but the blur event was not firing anymore as the browser isn't focus so I tried to force the focus state on one of the element but no locky it wasn't working.
Do the following issue to replicate the issue:
Open the page in minimized browser > then focus out the page.
Scroll on the visible browser view port but do not click (which won't make focus state true).
Mobile browsers require user action to start play on Audio elements. The click event satisfies the requirement, but it appears that touchstart is not an acceptable initiating event in Chrome on Android or iOS. (See below)
Does anyone know where to find a precise definition of the event context required to start play.
(I was attempting to solve a UX problem using the ideas in How to prevent doubletap zoom in iOS and Android. Since posting my original question, I've found a solution that solves the UX problem without using touchstart, but I think the essential question about which events are considered to be user action is still valid.)
Addendum:
It has been suggested that I am mistaken about touchstart events, so for the record, I am providing a trivial test program. Since it requires a real music file and a mobile device, JSFiddle isn't a suitable platform (unless somebody knows how to simulate a touchstart event in a fiddle). To reproduce my observations, edit the javascript to load your own audio file.
<!DOCTYPE html>
<html>
<body>
<br>
<button type="button" id="but1">click</button>
<button type="button" id="but2">touch</button>
<br>
<br>
<span id="message"></span>
<script>
var e;
e = document.getElementById('but1');
e.onclick = click;
e = document.getElementById('but2');
e.ontouchstart = touchstart;
function click() {
alert('caught click');
play();
event.preventDefault();
}
function touchstart() {
alert('caught touchstart');
play();
event.preventDefault();
}
var p;
var t;
function play() {
p = new Audio();
p.src = '/k487.mp3'; // CHANGE THIS
p.preload = 'auto';
p.play();
t = setInterval(report,1000);
}
function report() {
var s = 'Player readyState='+p.readyState+', currentTime='+p.currentTime;
var e = document.getElementById('message');
e.innerHTML = s;
}
</script>
</body>
</html>
When I load this page in Chrome 58 on Android 6.0.1 the Click button works as expected, producing a popup, playing some music and updating the play time.
If I reload the page and touch the Touch button instead, I get the popup, but no music plays. The status display shows a readyState of 4 and a currentTime of 0. In other words, the touchstart event is permitted to load the audio but not to initiate play.
Since I can find no documentation on what events are meant to work, I don't know whether to consider this a Chrome bug, or intended behaviour.
When the play() method on a media element is invoked, the user agent must run the following steps https://html.spec.whatwg.org/multipage/media.html#dom-media-play
step1: if the media element is not allowed to play...
then I wonder the condition that allowed to play, it jump to here https://html.spec.whatwg.org/multipage/media.html#allowed-to-play
it says:
For example, a user agent could require that playback is triggered by user activation, but an exception could be made to allow playback while mute
then came to 'triggered-by-user-activation' here
I think that's the reason:
An algorithm is triggered by user activation if any of the following conditions is true:
The task in which the algorithm is running is currently processing an activation behavior whose click event's isTrusted attribute is true.
change
click
contextmenu
dblclick
mouseup
pointerup
reset
submit
touchend
'touchstart' is not mentioned there.
hope that helps you.
In this page you will found answer on this question .
Use some popup or any animation nice for eye to attract user for tap .
in my memory ... android and iOS have no same behavior it is about max number of audios that we can start buffer with this trick .
var EXE_JUST_ONE_TIME = false;
document.addEventListener("touchstart" , function(e) {
if (EXE_JUST_ONE_TIME == false){
EXE_JUST_ONE_TIME = true;
document.getElementById("LaserShot").play(); // need for play pause just for buffering start
document.getElementById("LaserShot").pause();
// now you can play programmability from js
document.getElementById("LaserShot_CLONE").play();
document.getElementById("LaserShot_CLONE").pause();
}
else if(EXE_JUST_ONE_TIME = true){
document.getElementById("MakeReadyotherAudio1").play();
document.getElementById("MakeReadyotherAudio1").pause();
EXE_JUST_ONE_TIME = 'NOMORE'
}
}
If you have problems i can make you code snippet with working example !
I put in 90% in mobile web dev in event function on begin :
document.getElementById("myAnchor").addEventListener("click", function(event){
event.preventDefault()
});
//Sometimes even if you dont use some event its good to override :
window.addEventListener('touchstart', function(e){
e.preventDefault()
}, false)
window.addEventListener('touchmove', function(e){
e.preventDefault()
}, false)
window.addEventListener('touchend', function(e){
e.preventDefault()
}, false)
window.addEventListener('touchleave', function(e){
e.preventDefault()
}, false)
window.addEventListener('touchcancel', function(e){
e.preventDefault()
}, false)
window.addEventListener('touchenter', function(e){
e.preventDefault()
}, false)
If you wanna you can use this library :
desktop/mobile event optimise for canvas
I have a defined a click which works as desired in all except two. I am binding the click event as follows :
$('#next_item').bind(myDown,function (e) {
config.scrolling = true;
config.scrollTimer = setInterval(function (e) {
if(!config.scrolling) return false;
if(myScroll.x >= myScroll.maxScrollX){
myScroll.scrollTo((config.itemWidth+config.itemBoxSpacing), 0, 400, true);
}else{
config.scrolling=false;
clearInterval(config.scrollTimer);
}
}, 100);
return false;
});
I am using iScroll 4. The #next_item is used to scroll the dynamically added div onclick. setInterval function() is used because on single click i want to scroll one div at a time and on mousedown i want the div to scroll till i do mouseup. Now the problem is on single click more then one div scroll at a time in blackberry playbook but works fine in ipad, android tablet and desktop browser including IE8. Also when i do mousedown in blacberry playbook the div keeps on scrolling till end and does not stop immediately on mouseup and for IE8 the div stops and scroll seems like setInterval is not working properly. What changes needs to be done to make this work in both IE8 and blackberry playbook
Update :
var isIOS = config.isIpad || config.isIphone || config.isAndroid;
var myDown = isIOS ? "touchstart" : "mousedown";
var myUp = isIOS ? "touchend" : "mouseup";
$('#next_item').bind(myUp,function (e) {
config.scrolling = false;
clearInterval(config.scrollTimer);
return false;
});
I have solved the blackberry problem. I had to just change one line of my code.
var isIOS = 'ontouchstart' in document.documentElement; /*This detects all touch devices*/
In my earlier code i was not detecting blackberry playbook and so it was receiving the mousedown event which caused the default touchstart event for touch devices to trigger along with the mousedown event and hence unexpected result.
I still could not solve the IE8 issue. Please anyone suggest what to do for IE8.