The past few weeks I've been working on a website which is live now. It can be seen here: http://www.momkai.com/
This website works fine in all browsers I tested it in except one: Safari. When I open this website in Safari 10.1 and hover over the first paragraph, this is what I see:
This is correct. The first word of each line of text should be underlined. Hovering of the lines results in this styling:
So far everything is going well. Now I reload the page and I see this:
The underlines are way to wide! I've logged the offsetWidths and they are just completely wrong. This is the code which I use to retrieve the widths:
const parentParagraph = this.el.parentNode.parentNode;
let selfIndex;
let siblingUnderlineWidth;
this.underlineWidth = this.el.querySelector('.js-text-block-link-text-highlight').offsetWidth;
this.siblings = [].slice.call(parentParagraph.querySelectorAll('.js-text-block-link-text'));
this.siblingUnderlineWidths = [];
for (let sibling of this.siblings) {
if (sibling.isSameNode(this.underline)) {
selfIndex = this.siblings.indexOf(sibling);
} else {
siblingUnderlineWidth = sibling.querySelector('.js-text-block-link-text-highlight').offsetWidth;
console.log(siblingUnderlineWidth);
this.siblingUnderlineWidths.push(siblingUnderlineWidth);
}
}
this.siblings.splice(selfIndex, 1);
I've also added two screenshots of the console.log's to demonstrate how the values differ:
I'm experiencing this behaviour in Safari 10.1 on desktop and Safari for iOS. I've no idea what's going wrong so I hope someone can help me. Thanks in advance!
I'll be happy to provide more code if required.
I have found that when something CSS changes after I refresh, it is usually a loading order issue.
For example I was using
document.addEventListener('DOMContentLoaded', runsWhenReady);
But sometimes the offsetWidth would be wrong.
Figured out this we because the CSS file wasn't fully loaded, which changes how the offsetWidth is.
Chrome and Safari handle caching differently, which is why it would be different on refresh.
So I switched to:
window.addEventListener('load', runsWhenReady);
Which only fires after everything including CSS is loaded and it solved the issue.
English is not my first language, feel free to ask me any question to clarify this problem.
Im using admobpro plugin for my ionic/cordova apps.
This is the code i used for displaying the banner ads :
if(( /(ipad|iphone|ipod|android|windows phone)/i.test(navigator.userAgent) )) {
document.addEventListener('deviceready', initApp, false);
} else {
initApp();
}
function initApp() {
AdMob.createBanner( {
adId: admobid.banner,
isTesting: false,
overlap: false,
offsetTopBar: false,
position: AdMob.AD_POSITION.BOTTOM_CENTER//,
//bgColor: 'yellow'
} );
}
The problem is the entire page where the banner displayed will be reloaded/refreshed the first time the banner displayed. This will result in a blink to the page.
Is there any way to display the banner fluently? (without any blink)
Thanks a lot for your help
This is a bug in the AdMob cordova plugin.
I don't know if the plugin was updated recently to fix the problem.
Anyway, one proposed solution (may be not robust 100% but very helpful) is to keep the splash screen displayed until the banner had been fully displayed for a moment.
Pseudo code:
banner.create().then(()=>{
setTimeout(()=>{
splashScreen.hide();
}, 200);
});
I cant get my select box to work with i enable touchenabled in desktops. Viewing my fiddles you will see when you click on "ARTICLE" the select box will only work if i disable touchenabled for desktop users.
touchenabled:"on" http://jsfiddle.net/y82XD/ (ARTICLE select box will not work)
touchenabled:"off" http://jsfiddle.net/y82XD/3/ (ARTICLE select box works fine)
I am using a script to detect mobile devices and want to enable touchenabled: "on" , when device.mobile is detected. The mobile detection script has a JavaScript Method called device.mobile() that can be used . So using the below script for the slider , how would i go about incorporating the device.mobile() to set touchenabled:"on" for mobile , while setting touchenabled:"off" for everything else ?
var tpj=jQuery;
tpj.noConflict();
tpj(document).ready(function() {
if (tpj.fn.cssOriginal!=undefined)
tpj.fn.css = tpj.fn.cssOriginal;
tpj('#slidebox').services(
{
width:620,
height:460,
slideAmount:4,
slideSpacing:10,
touchenabled:"off",
NEED CODE HERE to enable touchenabled:"on" when device.mobile detected
mouseWheel:"off",
hoverAlpha:"on",
slideshow:3500,
hovereffect:"on",
callBack:function() { }
});
});
I was able to get the select box to function by changing the following two options in your slidebox services:
touchenabled:"off"
hoverAlpha:"off"
Those were previously on. When I turned them off, the parent slidebox div lost its mousedown and touchcancel event listeners.
I don't know enough about this package to understand what implications this might have. But it looked to be doing everything it was doing previously.
If you need to have these options on, then perhaps you could turn them off when this particular page is displayed? Or maybe you could unbind the two listeners that are causing the problems when the page is displayed.
UPDATE:
Ok, after reading your new comments, I'm not sure why this won't work, but it does seem a bit simple, so maybe I still don't understand it 100%.
var touchEnabledValue = (device.mobile) ? "on" : "off;
tpj('#slidebox').services(
{
width:620,
height:460,
slideAmount:4,
slideSpacing:10,
touchenabled: touchEnabledValue,
mouseWheel:"off",
hoverAlpha: touchEnabledValue,
slideshow:3500,
hovereffect:"on",
callBack:function() { }
}
In previous versions of iOS, <a> tags would open Mobile Safari, and you had to intercept those to instead stay inside the webapp (an HTML page that has been saved to the home screen by the user).
Starting in iOS 7, all links are staying inside the WebApp. I cannot figure out how to get it to open Safari, when I really want it to.
I've tried using window.open and a target="_blank" but neither works.
Here is a sample. https://s3.amazonaws.com/kaontest/testopen/index.html
If you save that to your home screen in iOS 6, the link opens Safari. But in iOS 7, it doesn't.
Note that this is the OPPOSITE question that everyone is usually asking ("how to NOT open Safari"). That behavior seems to be the new default, and I can't figure out how to get the old behavior back!
Update 10/23/13: Fixed in iOS 7.0.3. Add a target="xxx" attribute to your links to do this. Also works with mailto: and friends.
This is a bug in iOS 7.0, 7.0.1 and 7.0.2 and there's no known way to do this.
It's a regression from earlier versions of iOS, where links that open in Safari work just fine. It appears to be a part of a cluster of problems revolving around opening URLs, with no external URL schemes working (for example "mailto:" doesn't work either).
The usual suspects of working around a problem like this unfortunately don't work (for example using a form and submitting it with a target of "_new").
There's other grave issues, like alert and confirm modal dialogs not working at all.
It may help to submit these as bugs to Apple, http://bugreport.apple.com
Having an anchor tag with target _blankwill work in iOS 7.0.3 but using window.open will not work and will remain to open within the webview in 7.0.3:
window.open('http://www.google.com/', '_blank');
This is a known issue for the last couple months of betas. There are no work arounds, and from what I can tell Apple has been silent on any ETAs on fixes, or even recognizing it's a bug. Bug reports have been submitted, but not updated/responded to.
More: http://www.mobilexweb.com/blog/safari-ios7-html5-problems-apis-review
UPDATE
Just wanted to let any one following this know that iOS 7.0.3 seems to fix the issue. I've keep standalone webapps saved for testing and the update released today restored external link/app functionality. So I've updated my code to let customers know to update their phones instead of deleting and re saving the web app.
I was going to just add a comment but apparently this is too long.
Apple set the stage for a WebApp world when they allowed chromeless webapps to be saved to the homescreen of the device. This "bug" feels like a major step backwards. It doesn't seem very apple to leave such a gapping bug in a final release. At least not one that, once they become aware of it, they don't publicly state they are working on a fix for it like they did with the lockscreen bypasses. I can't help that this feels intentional though there doesn't seem to be a clear reason why.
For developers dealing with this issue the only solution I could find was to
1st) Set the meta tag apple-mobile-web-app-capable to "no" - this prevents future users from dealing with the problem
2nd) Updated the code in our webapp to look for "standalone" and iOS version 7+. When conditions are meet I offered a popup that stated the issue and added a link to that page and asked the users for their forgivness and requested they copy the link and paste in in safari.
I wrapped the link in edge to edge tag with line breaks above and bellow to help make the copy and pasting process of the url a bit easier.
iOS v7.0.3 released 10/22/13 fixes the problem.
I found two solutions for the time being to this problem, both of which obviously using preventDefault on the external links.
If you're linking to another website or something to download, the only option I see is to ironically alert the user to hold their finger on the link to get the touch callout prompt. Then again, depending if it's a website or a PDF, instruct them to either copy the link or in the case of a PDF, add it to their reading list. Since the alert and confirm modals are also broken you'll need to implement your own modal notifications. If you already have that it shouldn't be that much trouble.
Update [2013-10-25] Apparently it's been fixed in iOS 7.0.3 and links open in Safari...
Edit [2013-10-05] Here's pretty much what I use with a jQuery UI modal
// iOS 7 external link polyfill
$('a[rel=external], a[rel=blank], a[target=_blank], a[href$=".pdf"]').on('click', function(e) {
if (navigator.standalone && /iP(hone|od|ad) OS 7/.test(navigator.userAgent)) {
e.preventDefault(); e.stopPropagation();
var href = $(this).attr('href');
var $dialog = $('<div id="ios-copy"></div>')
.html('<p>iOS 7 prevents us from opening external links in Safari, you can continue to the address and risk losing all navigation or you can copy the address to your clipboard by <strong>holding your finger on the link</strong> for a few seconds.</p><p><a style="background-color: rgba(0,0,0,.75); color: #fff; font-size: 1.25em; padding: 1em;" href="' + href + '">' + href + '</a></p>')
.appendTo('body')
.dialog({
title: 'External link',
modal: true,
buttons: {
Ok: function() {
$( this ).dialog( "close" );
}
}
});
}
});
The other workaround is using ajax or an iframe to load the external content, but unless you have a good sub-browser or something in your app it will look sketchy. Here's something along those lines.
// iOS 7 external link polyfill
if (/iP(hone|od|ad) OS 7/.test(navigator.userAgent) && window.navigator.standalone) {
$('a[rel=external], a[href$=".pdf"]').on('click', function(e) {
e.preventDefault(); e.stopPropagation();
var link = this;
var href = $(link).attr('href');
var frameContainer = $('<div></div>').css({
position: 'absolute',
left: 10,
top: $(link).position().top,
opacity: 0,
overflow: 'scroll',
'-webkit-overflow-scrolling': 'touch',
height: 520,
transition: 'opacity .25s',
width: 300
});
var iosFrame = $('<iframe class="iosFrame" seamless="seamless" width="1024" height="5000"></iframe>')
.attr('src', href)
.css({
height: 5000,
'max-width': 1024,
width: 1024,
overflow: 'scroll !important',
'-webkit-overflow-scrolling': 'touch !important'
});
var iosFrameClose = $('<i class="icon-cancel icon-remove icon-3x"></i>').css({
position: 'absolute',
left: -10,
top: $(link).position().top - 20,
'text-shadow': '1px 1px 1px #000',
transition: 'opacity .25s',
opacity: 0,
'-webkit-transform': 'translate3d(0, 0, 0)',
width: '3em',
height: '3em'
}).on('click', function(e) {
e.preventDefault();
setTimeout( function() {
$(frameContainer).remove();
$(iosFrameClose).remove();
}, 250);
});
iosFrame.appendTo(frameContainer);
frameContainer.appendTo('body');
iosFrameClose.appendTo('body');
iosFrame.contents().css({
'-webkit-transform': 'translate3d(0, 0, 0)'
});
// Show this thing
setTimeout( function() {
$(frameContainer).css({ opacity: 1 });
$(iosFrameClose).css({ opacity: 1 });
}, 1);
});
}
window.open('http://www.google.com/'); // stays in web app view
<a href='http://www.google.com/' target='_blank'>Click Here</a> // opens in safari
If you want to open Safari, but using an anchor tag like this isn't possible for whatever reason, the JavaScript solution to this question will open in Safari as well.
It looks suspiciously like an intentional bug to limit the ability of web apps to deliver advertisements. Maybe you can try open the new page in an iframe.
EDIT: Sorry, I misread your original problem. This solution was for opening an external website at all. Basic A href tags used to work in opening links and stopped working in iOS7. This was the only way I could get it to open an external link at all.
Here's how I got it to sort of work with a webapp saved to desktop in iOS7.
function openpage()
{
window.open('http://www.yourlinkhere.com', '_blank');
}
...
<a ontouchstart="openpage();" onclick="openpage();">LINKED TEXT</a>
The issue though is that it seems to ignore the target option and it opens it in the same full screen desktop webapp and there is no way to navigate back that I can see.
window.open('http://www.google.com/', '_system');
this will open native Safari Application even on latest version of iOS...
Happy coding!!
Maybe you should remove the meta setting of "apple-mobile-web-app-capable" in the head of page2.html
https://developer.apple.com/library/ios/documentation/AppleApplications/Reference/SafariWebContent/ConfiguringWebApplications/ConfiguringWebApplications.html#//apple_ref/doc/uid/TP40002051-CH3-SW1
I'm working on a site that uses setTimeout() to do kind of a 'slideshow' with banners on my site. Everything works fine, I have the delay set to 10 seconds. The problem only occurs when I switch windows/tabs and do something else. When I come back, the function runs a ton of times I (assume) to catch up or something. Problem is, my screen starts flickering over and over to show all banners fading in and fading out.
Any ideas on a solution? I've noticed this in Google Chrome, I also know it happens in Firefox. Not sure about IE.
EDIT
Here is the snippet I'm dealing with. Sadly, it is part of a very large script and is connected to a very complicated HTML file.
I hope you can get an idea of what is going on here at least:
var lval=0;
var nval=1;
setHead = function(data) {
lval=nval;
var index=1;
$.each(data, function(name,value) {
if (Math.floor(Math.random()*index+2)==index+1) {
nval=index;
}
if (index==lval) {
$('.headmaster').find('img').fadeOut('fast');
//$('.headmaster').css('background-color',value.backgroundcolor);
$('.headmaster').find('a').attr('href',value.url);
$('.headmaster').animate({backgroundColor:value.backgroundcolor},'slow',function() {
$('.headmaster').find('img').attr('src',value.img);
$('.headmaster').find('img').fadeIn('slow');
});
}
index++;
});
setTimeout(function() { setHead(data); },10000);
}
arrayGet = function(arr,idx) {
$.each(arr, function(i,v) {
if (i==idx) {
return v
}
});
return null
}
$(document).ready(function() {
$.getJSON('json/intros.json', setHead);
});
I'm using jQuery for the animation and the color plugin for fading the colors.
It is happening probably because you are using an old version of jQuery. Namely the one where the dev team has started using requestAnimationFrame API. Fortunately, they fixed it in 1.6.3. Here is an extract from their blog:
No more animation “worm holes”: We had high hopes for the browser’s requestAnimationFrame API when we added support into version
1.6. However, one of the highest-volume complaints we’ve received since then relates to the way requestAnimationFrame acts when a tab is
not visible. All the animations initiated when the tab is invisible
“stack” and are not executed until the tab is brought back into focus.
Then they all animate at warp speed! We’ve removed support for this
API (which has no impact on the way you call jQuery’s animation
features) and plan to incorporate it into a future version of jQuery.
Simply update to 1.6.4.