-->

Window onload event does not fire in ipad ios 8.4

2019-02-20 02:01发布

问题:

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>

回答1:

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");


回答2:

There is also a workaround:

var iOS8 = navigator.userAgent.match(/(iPad|iPhone|iPod).*OS 8_\d/i);
if( iOS8 ){
    setTimeout(function(){
        $(window).trigger('load');
    }, 3500);
}

This will trigger the load, and 'trick' Safari on iOS8 to think that the $(window) object was loaded, so the code inside the

$(window).on('load', function());

will work.

Hope this helps to anyone who is searching for this :)



回答3:

I counldn't find the reason why the control does not fire window.onload event. But for those who will get into the same issue, I am posting here the other way round to solve this issue. (and obviously I dont want to get a tumbleweed badge..)

  1. I have added most of the javascript in code behind (cs file) which was inside window.onload
  2. As I am calling a javascript function jWDScrollWindow() on page load to scroll the page, I added the $(".lazy").unveil(); inside jWDScrollWindow() function itself.

This solves my issue in iPad, but the changes are not device specific.

function jWDScrollWindow() {
    //Apply lazy loading functionality to images
    $(".lazy").unveil();
    //scroll by 1px to load the images
    $(window).scrollTop($(window).scrollTop() + 1);
}

This is not a full-fledged solution to the issue but a work aournd. If someone has a reason or solution on this issue, please do post as an answer.