I have a problem with scroll to element on mobile Safari in iframe (it works on other browsers, including Safari on mac).
I use scrollIntoView. I want to scroll when all content has been rendered. Here is my code:
var readyStateCheckInterval = setInterval(function () {
if (document.readyState === "complete") {
clearInterval(readyStateCheckInterval);
$browser.notifyWhenNoOutstandingRequests(function () {
if (cinemaName != null && eventId == null) {
scrollToCinema();
} else {
scrollToEvent();
}
});
}
}, 10);
function scrollToEvent() {
var id = eventId;
var delay = 100;
if (cinemaName != null) {
id = cinemaName + "#" + eventId;
}
if ($rootScope.eventId != null) {
id = $rootScope.cinemaId + "#" + $rootScope.eventId;
}
$timeout(function () {
var el = document.getElementById(id);
if (el != null)
el.scrollIntoView(true);
$rootScope.eventId = null;
}, delay);
}
ScrollIntoView does not work (currently). But you can manually calculate the position of the element and scroll to it. Here is my solution
const element = document.getElementById('myId')
Pass the element to this function
/** Scrolls the element into view
* Manually created since Safari does not support the native one inside an iframe
*/
export const scrollElementIntoView = (element: HTMLElement, behavior?: 'smooth' | 'instant' | 'auto') => {
let scrollTop = window.pageYOffset || element.scrollTop
// Furthermore, if you have for example a header outside the iframe
// you need to factor in its dimensions when calculating the position to scroll to
const headerOutsideIframe = window.parent.document.getElementsByClassName('myHeader')[0].clientHeight
const finalOffset = element.getBoundingClientRect().top + scrollTop + headerOutsideIframe
window.parent.scrollTo({
top: finalOffset,
behavior: behavior || 'auto'
})
}
Pitfalls: Smooth scroll also does not work for ios mobile, but you can complement this code with this polyfill
In my experience scrollIntoView() fails sometimes on my iphone and my ipad and sometimes it works (on my own web sites). I'm not using iframes. This is true both with safari and firefox on the above devices.
The solution that works for me is to pop the element you need to scroll to inside a DIV eg. as the first element in that DIV. Hey presto it then works fine!
Seems like a dodgy implementation by Apple.
Your most likely having the exact same issue I just debugged. Safari automatically resizes the frame to fit it's contents. Therefore, the parent of the Iframe will have the scrollbars in Safari. So calling scrollintoview from within the Iframe itself 'fails'.
If Iframe is cross domain accessing the parent document via window.parent.document will be denied.
If you need a cross domain solution check my answer here.
Basically I use post message to tell the parent page to do the scrolling itself when inside Mobile Safari cross domain.
I'll try to explain my use case here. In my site I have a break point for desktop view, and break point for tablet view (which is more compact). I'm trying to add a function to allow seeing the tablet view when browsing from desktop, cause some members prefer the compact design in their desktop as well.
For doing that, I figured I would need to trick the '#media(max-width:X)' query. I'm looking for a JS code that can manipulate the screen width value, so when the browser calculates max-width, it would be against a value that I specified.
One thing to note, this is suppose to work on desktop browsers, so the meta viewport can't be used here.
One solution is to apply a specific class (e.g: .tablet) to the body.
<body class="tablet"></body>
In your CSS:
#media screen and (/* your query */) {
.tablet .my-class {
/* tablet specific stuff */
}
}
You could then remove the .tablet class and replace it with .desktop via JavaScript
var body = document.body;
var switchToDesktop = function() {
body.className = body.className.replace('tablet', 'desktop');
}
var switchToTablet = function() {
body.className = body.className.replace('desktop', 'tablet');
}
var toggleView = function() {
(body.className.indexOf("tablet") > -1) ?
switchToDesktop() :
switchToTablet();
}
If you are using SASS or LESS, you can nest the tablet-specific styles.
#media screen and (/* your query */) {
.tablet {
h1 {
/* tablet specific h1 */
}
.my-div {
color: red;
}
/* etc... */
}
}
My extension opens in a new FF tab. I would like all toolbars(exept for tabbar) be hidden when the tab is active.
What I want is exactly how the standard FF addons tab works(tools->addons).
Copy paste this code into scratchpad with browser environment and run it:
Cu.import('resource://gre/modules/Services.jsm');
var sss = Cc['#mozilla.org/content/style-sheet-service;1'].getService(Ci.nsIStyleSheetService);
try {
sss.unregisterSheet(cssUri, sss.USER_SHEET);
} catch (ex) {}
var css = '';
css += 'toolbar { display: none }';
var cssEnc = encodeURIComponent(css);
var newURIParam = {
aURL: 'data:text/css,' + cssEnc,
aOriginCharset: null,
aBaseURI: null
}
var cssUri = Services.io.newURI(newURIParam.aURL, newURIParam.aOriginCharset, newURIParam.aBaseURI);
sss.loadAndRegisterSheet(cssUri, sss.USER_SHEET);
to remove just run the sss.unregisterSheet(cssUri, sss.USER_SHEET);
You didn't write what kind of extension you're developing... SDK or XUL.
In a XUL extension, first get all toolbars, then set collapsed according to your wishes.
Here is some same code.
function toggleToolbars() {
// First get all toolbars (that are not the tab bar)
var tbs = Array.filter(document.querySelectorAll('toolbar'), function (x) {
return x.id != 'TabsToolbar';
});
// For each toolbar
for (var tb of tbs) {
// Either un-collapse if we collapsed it.
if (tb.getAttribute('my-addon-collapsed')) {
tb.removeAttribute('collapsed');
tb.removeAttribute('my-addon-collapsed');
}
// Or collapse other-wise, if not already collapsed
else if (!tb.getAttribute('collapsed')) {
tb.setAttribute('collapsed', 'true');
tb.setAttribute('my-addon-collapsed', 'true');
}
}
}
You may wish to fixup the code to handle corner cases, such as the user manually restoring a toolbar, other add-ons add-on entirely new toolbars later and so on.
In an SDK add-on your will need to get to the actual browser.xul windows first. I'm sure how to do this is already somewhere on SO.
I have some code running on my website which will detect if a div with the id, photo, is showing on the screen or is scrolled onto the screen. If the div is showing, a class is added to the div which will cause a background image to load inside the div. The intent is to lazyload the image so that the site loads faster.
It is working great in all browsers except for IE 6/7. Can someone tell me what is wrong with the below code that prevents it from working in these IE browsers?
function $(a){
return document.getElementById(a)
}
function scrll(){
function a(d){
var f=d.offsetTop,
e=d.offsetLeft,
c=d.offsetWidth,
b=d.offsetHeight;
while(d.offsetParent){
d=d.offsetParent;
f+=d.offsetTop;
e+=d.offsetLeft
}
return(f<(window.pageYOffset+window.innerHeight)
&&e<(window.pageXOffset+window.innerWidth)
&&(f+b)>window.pageYOffset&&(e+c)>window.pageXOffset)
}
if(a($("photo"))){
$("imgholder").className="pic11 pic21";
if(window.removeEventListener){
window.removeEventListener("scroll",scrll,false)
}else{
if(window.detachEvent){
window.detachEvent("onscroll",scrll)
}else{
window.onscroll=null
}
}
}
}
if(window.addEventListener){
window.addEventListener("scroll",scrll,false);
}else{
if(window.attachEvent){
window.attachEvent("onscroll",scrll);
}else{
window.onscroll=scrll;
}
}
setTimeout(scrll,1);
The code is active on my website: http://www.ericperrets.info/
IE doesn't have innerHeight. Use this function instead:
function getWindowHeight()
{
if (window.innerHeight) return window.innerHeight;
if (window.document.documentElement.clientHeight) return window.document.documentElement.clientHeight;
return window.document.body.clientHeight;
}
Also, a good article explaining differences between browsers is at http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
Is there any way of reliably detecting if a browser is running in full screen mode? I'm pretty sure there isn't any browser API I can query, but has anyone worked it out by inspecting and comparing certain height/width measurements exposed by the DOM? Even if it only works for certain browsers I'm interested in hearing about it.
Chrome 15, Firefox 10, and Safari 5.1 now provide APIs to programmatically trigger fullscreen mode. Fullscreen mode triggered this way provides events to detect fullscreen changes and CSS pseudo-classes for styling fullscreen elements.
See this hacks.mozilla.org blog post for details.
What about determining the distance between the viewport width and the resolution width and likewise for height. If it is a small amount of pixels (especially for height) it may be at fullscreen.
However, this will never be reliable.
Opera treats full screen as a different CSS media type. They call it Opera Show, and you can control it yourself easily:
#media projection {
/* these rules only apply in full screen mode */
}
Combined with Opera#USB, I've personally found it extremely handy.
You can check if document.fullscreenElement is not null to determine if fullscreen mode is on. You'll need to vendor prefix fullscreenElement accordingly. I would use something like this:
var fullscreenElement = document.fullscreenElement || document.mozFullScreenElement ||
document.webkitFullscreenElement || document.msFullscreenElement;
https://msdn.microsoft.com/en-us/library/dn312066(v=vs.85).aspx has a good example for this which I quote below:
document.addEventListener("fullscreenChange", function () {
if (fullscreenElement != null) {
console.info("Went full screen");
} else {
console.info("Exited full screen");
}
});
The Document read-only property returns the Element that is currently being presented in full-screen mode in this document, or null if full-screen mode is not currently in use.
if(document.fullscreenElement){
console.log("Fullscreen");
}else{
console.log("Not Fullscreen");
};
Supports in all major browsers.
Firefox 3+ provides a non-standard property on the window object that reports whether the browser is in full screen mode or not: window.fullScreen.
Just thought I'd add my thruppence to save anyone banging their heads. The first answer is excellent if you have complete control over the process, that is you initiate the fullscreen process in code. Useless should anyone do it thissen by hitting F11.
The glimmer of hope on the horizon come in the form of this W3C recommendation http://www.w3.org/TR/view-mode/ which will enable detection of windowed, floating (without chrome), maximized, minimized and fullscreen via media queries (which of course means window.matchMedia and associated).
I've seen signs that it's in the implementation process with -webkit and -moz prefixes but it doesn't appear to be in production yet.
So no, no solutions but hopefully I'll save someone doing a lot of running around before hitting the same wall.
PS *:-moz-full-screen does doo-dah as well, but nice to know about.
While searching high & low I have found only half-solutions.
So it's better to post here a modern, working approach to this issue:
var isAtMaxWidth = (screen.availWidth - window.innerWidth) === 0;
var isAtMaxHeight = (screen.availHeight - window.outerHeight <= 1);
if (!isAtMaxWidth || !isAtMaxHeight) {
alert("Browser NOT maximized!");
}
Tested and working properly in Chrome, Firefox, Edge and Opera* (*with Sidebar unpinned) as of 10.11.2019.
Testing environment (only desktop):
CHROME - Ver. 78.0.3904.97 (64-bit)
FIREFOX - Ver. 70.0.1 (64-bit)
EDGE - Ver. 44.18362.449.0 (64-bit)
OPERA - Ver. 64.0.3417.92 (64-bit)
OS - WIN10 build 18362.449 (64-bit)
Resources:
https://developer.mozilla.org/en-US/docs/Web/API/Screen/availWidth
https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth
https://developer.mozilla.org/en-US/docs/Web/API/Screen/availHeight
https://developer.mozilla.org/en-US/docs/Web/API/Window/outerHeight
In Chrome at least:
onkeydown can be used to detect the F11 key being pressed to enter fullscreen.
onkeyup can be used to detect the F11 key being pressed to exit fullscreen.
Use that in conjunction with checking for keyCode == 122
The tricky part would be to tell the keydown/keyup not to execute its code if the other one just did.
Right. Totally late on this one...
As of 25th Nov, 2014 (Time of writing), it is possible for elements to request fullscreen access, and subsequently control entering/exiting fullscreen mode.
MDN Explanation here: https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Using_full_screen_mode
Straightforward explanation by David Walsh: http://davidwalsh.name/fullscreen
For Safari on iOS can use:
if (window.navigator.standalone) {
alert("Full Screen");
}
More:
https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/ConfiguringWebApplications/ConfiguringWebApplications.html
This works for all new browsers :
if (!window.screenTop && !window.screenY) {
alert('Browser is in fullscreen');
}
There is my NOT cross-browser variant:
<!DOCTYPE html>
<html>
<head>
<title>Fullscreen</title>
</head>
<body>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script type="text/javascript">
var fullscreen = $(window).height() + 1 >= screen.height;
$(window).on('resize', function() {
if (!fullscreen) {
setTimeout(function(heightStamp) {
if (!fullscreen && $(window).height() === heightStamp && heightStamp + 1 >= screen.height) {
fullscreen = true;
$('body').prepend( "<div>" + $( window ).height() + " | " + screen.height + " | fullscreen ON</div>" );
}
}, 500, $(window).height());
} else {
setTimeout(function(heightStamp) {
if (fullscreen && $(window).height() === heightStamp && heightStamp + 1 < screen.height) {
fullscreen = false;
$('body').prepend( "<div>" + $( window ).height() + " | " + screen.height + " | fullscreen OFF</div>" );
}
}, 500, $(window).height());
}
});
</script>
</body>
</html>
Tested on:
Kubuntu 13.10:
Firefox 27 (<!DOCTYPE html> is required, script correctly works with dual-monitors), Chrome 33, Rekonq - pass
Win 7:
Firefox 27, Chrome 33, Opera 12, Opera 20, IE 10 - pass
IE < 10 - fail
My solution is:
var fullscreenCount = 0;
var changeHandler = function() {
fullscreenCount ++;
if(fullscreenCount % 2 === 0)
{
console.log('fullscreen exit');
}
else
{
console.log('fullscreened');
}
}
document.addEventListener("fullscreenchange", changeHandler, false);
document.addEventListener("webkitfullscreenchange", changeHandler, false);
document.addEventListener("mozfullscreenchange", changeHandler, false);
document.addEventListener("MSFullscreenChanges", changeHandler, false);
This is the solution that I've come to...
I wrote it as an es6 module but the code should be pretty straightforward.
/**
* Created by sam on 9/9/16.
*/
import $ from "jquery"
function isFullScreenWebkit(){
return $("*:-webkit-full-screen").length > 0;
}
function isFullScreenMozilla(){
return $("*:-moz-full-screen").length > 0;
}
function isFullScreenMicrosoft(){
return $("*:-ms-fullscreen").length > 0;
}
function isFullScreen(){
// Fastist way
var result =
document.fullscreenElement ||
document.mozFullScreenElement ||
document.webkitFullscreenElement ||
document.msFullscreenElement;
if(result) return true;
// A fallback
try{
return isFullScreenMicrosoft();
}catch(ex){}
try{
return isFullScreenMozilla();
}catch(ex){}
try{
return isFullScreenWebkit();
}catch(ex){}
console.log("This browser is not supported, sorry!");
return false;
}
window.isFullScreen = isFullScreen;
export default isFullScreen;
2021, the Fullscreen API is available. It's a Living Standard and is supported by all browsers (except the usual suspects - IE11 and iOS Safari).
// toggle fullscreen
if (!document.fullscreenElement) {
// enter fullscreen
if (docElm.requestFullscreen) {
console.log('entering fullscreen')
docElm.requestFullscreen()
}
} else {
// exit fullscreen
if (document.exitFullscreen) {
console.log('exiting fullscreen')
document.exitFullscreen()
}
}
User window.innerHeight and screen.availHeight. Also the widths.
window.onresize = function(event) {
if (window.outerWidth === screen.availWidth && window.outerHeight === screen.availHeight) {
console.log("This is your MOMENT of fullscreen: " + Date());
}
To detect whether browser is in fullscreen mode:
document.webkitIsFullScreen || document.mozFullScreen || document.msFullscreenElement
according to caniuse you should be fine for majority of browsers.
This property returns the Element that is currently in fullscreen mode.
document.fullscreenElement; // HTML Element or null
Also, you can subscribe to fullscreen change events with this method
addEventListener('fullscreenchange', (event) => { });
You can combine both to detect the nature of the change
addEventListener('fullscreenchange', () => {
if (document.fullscreenElement) {
// Your Logic if fullscreen
}
});
More on this here.
You can detect full screen using CSS like this:
#media all and (display-mode: fullscreen) {
// Regular CSS to be applied in full-screen mode
}