Shubham Bhave Shubham Bhave - 6 months ago 60
Javascript Question

Window onload event does not fire in ipad ios 8.4

I am facing following strange issue:

Functionality:

When I open my website page which has many images and have javascript/jquery used for client side functionality. On clicking each image, all the other images changes their opacity and the selected image shows a

<div>
containing some information and a video for the image.


  1. I have used jquery unveil which loads all the images only after a scroll event is fired on the page. Untill that, it displays a "loading" image.

  2. I have added a javascipt on
    window.onload
    event to resize the
    <div>
    element when image is clicked. And some javascript that identifies the browser and set video tag source accordingly.

  3. All the images are rendered inside a datalist and is being bound from database.

  4. As unveil loads the image only after scroll event, I have added a code on page load to scroll a page by a pixel artificially.



Problem:

I open the same page in iPad(iOS 8.4) on chrome or safari. All my javascript under
window.onload
does not fire.

ASPX page:

<script type="text/javascript" src="/js/jquery.unveil.js"></script>
<asp:DataList ID="dlPersonList" runat="server" OnItemDataBound="dlPersonList_OnItemDataBound"
RepeatDirection="Horizontal" RepeatLayout="Flow">
<ItemTemplate>
<div class="itemImage">
<asp:HyperLink ID="hypPersonPicture" runat="server">
<asp:Image ID="imgPersonPicture" runat="server" CssClass="lazy" />
</asp:HyperLink>
</div>
<asp:Panel class="person-detail" ID="pnlpersonDetail" runat="server">
<div class="person-content detailView">
<%--Some text and other controls--%>
<asp:Panel ID="pnlVideo" runat="server">
<div class="video-content">
<video id="personVideo" controls="controls" preload="none">
<%--Video source elements--%>
</video>
</div>
</asp:Panel>
</div>
</asp:Panel>
</ItemTemplate>
</asp:DataList>


CS code:

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//Bind data list
dlPersonList.DataSource = SelectPersons();
dlPersonList.DataBind();
// Register the script for slide up effect
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "scriptPerson", @"$(document).ready(function () {
jWDScrollWindow();});",
true);
}
}
protected void dlPersonList_OnItemDataBound(Object sender, DataListItemEventArgs e)
{
/*Lazy loading functionality*/
//Set the image source as loader image
imgPersonPicture.Attributes.Add("src", "/img/loading.gif");
//set image resource as actual image
imgPersonPicture.Attributes.Add("data-src", imageObject.ImagePath.TrimStart('~'));
}


JS code:

window.onload = function () {
//Apply lazy loading functionality to images
$(".lazy").unveil();
//Javascript to set the width and height of the details div
.
.
//Javascript to blur all the other images when one image is clicked
}
function jWDScrollWindow() {
//scroll by 1px to load the images
$(window).scrollTop($(window).scrollTop() + 1);
}


Things I have tried yet:


  1. I thought jquery unveil might have making the page slow or something. so, I removed the call but the problem is the
    unveil();
    is called within
    window.onload
    . So, if window.onload is not being fired, it doesnt make any sence to remove the unveil.

  2. I added an alert() on
    window.onload()
    , but in this case, everything works perfect.



All the functionality works perfectly in all devices except ipad with ios 8.4 (it works great even in earlier os)

Help/Suggessions are much appreciated.

EDIT:

I found one jsconsole through which we can see the console logs in iPad on the desktop. Here is how we can use it.

I checked the logs and found that when I am getting error
JQMIGRATE: jQuery.browser is deprecated
, My
window.onload
event doesn't fire. Whereas, if I get log
JQMIGRATE: Logging is active
, everything works fine.
My
jqmigrate
reference is in master page as,

<script type="text/javascript" async src='/js/jquery-migrate-1.1.1.js'></script>

Answer

I too recently encountered this issue. Sounds like a similar situation to yours Shubham.

TL;DR:

Various versions of iOS8 seem to prevent window onload from firing if an <audio> or <video> tag contain the attribute preload="none" (and maybe other variations)

It makes no sense to me seeing as a preload of "none" should in fact NOT be trying to load media data so why it interferes with window onload??

Further explanation:

In a Wordpress/WooCommerce site that I'd helped build, the client had several employees ALL with iPhone iOS 8.4.1. Three with an iPhone 5 and one with iPhone 6. TWO of them with iPhone 5 had issues, the other iPhone 5 user and the iPhone 6 user had no such issue so originally I assumed the issue lay with the order/speed of which some jQuery plugins may have loaded.

The symptoms were that things like the mobile navigation that should expand/contract and the AJAX search functionality would fail for these users and not function at all but all other browsers/desktops/Android tested were fine.

The site sells audio products, many with audio previews. After some (lots!) of testing I realised that the users did not have this issue when on a page WITHOUT an audio tag.

So I searched on iOS8, window onload and audio bugs and I found these two little gems that contained comments related to audio issues on various versions of iOS:

http://themeforest.net/forums/thread/ios8-safari-breaks-windowload-info-for-authors/147825?page=1&message_id=1154236#1154236 (user "tommusrhodus")

if you have any or tags in your page, then it’s currently going to be broken in iOS8 safari which never fires the window.onload event if these tags are present in the DOM.

https://github.com/codevise/pageflow/issues/118 (user "lufes"):

The problem is related to the window.onload event, which will not be triggered if there's a video or audio with the preload="none" attribute set. window.onload will run once every asset is loaded, and iOS 8 keeps waiting for the video to load, which will never do.

So the solution for me - since I didn't want to hack the Wordpress core - was to simply remove the preload attribute altogether via jQuery in a ready callback which would fire before the window onload like:

$("audio").removeAttr("preload");
Comments