AJAX 加载的图像无法在 Safari 中正确显示

Posted

技术标签:

【中文标题】AJAX 加载的图像无法在 Safari 中正确显示【英文标题】:AJAX loaded images not displaying properly in Safari 【发布时间】:2018-01-12 14:28:20 【问题描述】:

所以我使用 AJAX 从每个页面加载内容并将其注入当前页面。一切在 Chrome、Firefox、Internet Explorer 上运行良好(尽其所能,哈哈),并且内容在 Safari 上加载良好,除了两个奇怪的部分。

    通过 AJAX 加载的图像高度为 0 通过 AJAX 加载的图像正在失去其适合对象的属性。

问题1:图片高度0

我将使用此页面作为参考:http://insight.insightcreative.info/about

如果您在 Safari 中打开页面,一切都应该显示得很好,但现在如果您单击“关于”链接以使用 AJAX 加载重新加载页面,页面上的图像将会中断。

我发现,当 AJAX 加载图像高度时,图像高度被设置为 0。

这是一个页面上的图像在被 AJAX 加载后损坏的示例

<img data-aos-anchor-placement="bottom-bottom" data-aos-offset="100" src="/img/agency/clients/affinity-medical-group.jpg" 
srcset="
/img/agency/clients/affinity-medical-group-2400.jpg 2400w,
/img/agency/clients/affinity-medical-group-1800.jpg 1800w,
/img/agency/clients/affinity-medical-group-1200.jpg 1200w,
/img/agency/clients/affinity-medical-group-900.jpg 900w,
/img/agency/clients/affinity-medical-group-600.jpg 600w,
/img/agency/clients/affinity-medical-group-400.jpg 400w" />

如果页面是初始加载的页面(或硬刷新),为什么页面会正确呈现,但是当内容通过 AJAX 加载时,它没有正确应用高度?


问题 2:对象拟合不起作用

我将使用此页面作为参考:http://insight.insightcreative.info/work

如果您在 Safari 中打开页面,一切都应该显示得很好,但现在如果您单击工作链接以使用 AJAX 加载重新加载页面,页面上的图像将不会以对象匹配方式显示。

如果您检查页面,您会发现所有相同的 CSS 设置都应用于图像,包括 object-fit 属性,但由于某种原因,它们不再尊重它们的属性。相反,图像正在拉伸以填充容器。

如果页面是初始加载的页面(或硬刷新),为什么页面会正确呈现,但是当内容由 AJAX 加载时,它不再遵守 object-fit 属性?


这两个问题似乎只发生在 Safari 中,我猜这与 Safari 在通过 AJAX 加载时处理图像属性的方式有关。

在通过 AJAX 加载页面后,我是否可以尝试强制 Safari 正确重新应用这些设置?或者有没有编码大神知道如何用 Safari 处理这些问题?


编辑 1:

我编写了一个函数来在加载 AJAX 后更改我的页面的 CSS,以便它会重写我的图像的属性。我故意将object-fit 更改为fill,然后再改回cover,试图完全重置样式。

function checkImages() 
  var images = $('img');
  for (var i = 0; i <= images.length; i++)
    var result = $(images[i]).css("object-fit");
    if (result == 'cover')
      $(images[i]).css("object-fit","fill");
      $(images[i]).css("object-fit","cover");
      $(images[i]).css("display","block");
      $(images[i]).css("position","relative");
      $(images[i]).css("max-width","100%");
      $(images[i]).css("max-height","100%");
    
  

我通过有意更改其中一些设置来确认此代码有效,以便它们会在浏览器中显着反映。我发现即使在页面加载完所有内容后更改设置,我似乎仍然无法解决问题(关于样式)。

但是,这确实使我尝试了其他方法。 通过从我的图像中完全删除 srcset 属性,即使加载 AJAX,它也会正确呈现。所以本质上,出于某种原因,通过使用srcset,它只允许页面在硬加载时正确显示,但如果通过 AJAX 加载则无法正确显示。我不确定这是否与 Safari 也只会加载它在 srcset 中看到的第一个图像并忽略其余图像这一事实相关,但 我认为问题在于 Safari 如何处理 srcset

解决方案:Barba.js

在没有深入细节的情况下,我设法解决了这个问题。在我使用自己编写的脚本加载每个页面的内容之前。在测试Barba.js 后,我发现图像在 Safari 上没有任何问题。所以我加载了 Barba.js,然后重写了我所有的 JS,以便它可以与那个 PJAX 库一起正常运行。所以不知何故,我之前加载页面的方式导致了这个问题,但仅限于 Safari。

下面是我之前用来加载 AJAX 的代码的 sn-p

//Function that loads in the new content
var load = function(url) 

//Fadeout leaving page transition
$('#content').velocity("fadeOut", 
  visibility: 'visible',
  display: 'block',
  complete: function() 

    //Load new content
    $("#content").load(url + " #content");

  
);

;

//Action to perform on link click
$(document).on('click', 'a', function(e) 

//Sets variables to be used for url and page name
var $this = $(this),
  url = $this.attr("href"),
  title = $this.text();
loading = true;

//Makes entries into browser history
if (url.indexOf(document.domain) > -1 || url.indexOf(':') === -1) 
  history.pushState(
    url: url + '/',
    title: title
  , title, url);
  $('#container').mixItUp('destroy');
  $('a').on('click.myDisable', function() 
    return false;
  );
  load(url);
  if (url === '/') 
    document.title = "Insight Creative, Inc.";
   else 
    document.title = title + " - Insight Creative, Inc.";
  

  return false;

);

【问题讨论】:

我有这个完全相同的问题,并且一直在通过设置高度来解决它,类似于 Tyler 的回答。老实说,我认为这是一个非常糟糕的错误,应该引起 Safari 的注意。 【参考方案1】:

我也遇到了问题 1 中概述的 Safari 错误,但我没有在 Barba.js 上重建我的应用程序,而是选择使用 imagesLoaded 脚本重写 safariResize 函数。这是我的功能,以防其他人发现它有用:

var safariResize = function() 
    // Targetting collapsed images in pjax loading box (safari bug)
    var imgLoad = imagesLoaded( $('.site-container > .site-inner img') );
    imgLoad.on( 'progress', function( instance, image ) 
        if(image.isLoaded && image.img.height == 0)
            var naturalH = image.img.naturalHeight,
            naturalW = image.img.naturalWidth;
            if( image.img.parentElement.clientWidth < naturalW )
                var ratio = naturalH / naturalW;
                naturalW = image.img.parentElement.clientWidth;
                naturalH = naturalW * ratio;
            
            image.img.setAttribute("style","width: "+naturalW+"px; height: "+naturalH+"px;");
        
    );
;

【讨论】:

【参考方案2】:

所以我设法解决了两个问题中较大的一个,即由于高度为 0,图像未显示。出于某种原因,当通过 AJAX Safari 加载带有srcset 的图像时,会删除自动高度并将其设置为 0px。

我编写了一个函数,等待所有图像都加载完毕(因为否则naturalHeight 返回 0),然后它将高度更改为保持原始图像纵横比相同的高度。我也这样做了,它只针对没有应用object-fit: cover 的图像,因为这些图像给我带来了问题,否则它会弄乱object-fit 图像。

function safariResize() 
  console.log("Running safariResize");

  // This variable starts at 1 because the logo (always on the page) is image 0
  var loaded = 1;
  $('img').on('load',function()
    loaded++;
    images = $('img');
    if (loaded == $('img').length)
      for (var i = 1; i < images.length; i++)
        if ($(images[i]).css("object-fit") != 'cover')
          var naturalH = images[i].naturalHeight;
          var naturalW = images[i].naturalWidth;
          var ratio = naturalH / naturalW;
          var newRatio = (images[i].width / naturalW);
          var newH = naturalH * newRatio;
          $(images[i]).css("height", newH + "px");
        
      
    

  );

然后我在 if 语句中加载 AJAX 后调用此函数,以确保它仅在 Safari 上触发

if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1)  
  safariResize();
 else if (navigator.userAgent.indexOf('iPad') != -1 && navigator.userAgent.indexOf('Chrome') == -1) 
  safariResize();

我不相信我能够解决对象匹配问题,该问题仅发生在桌面版 Safari 上(在 iPad 上运行良好)。如果您找到解决此问题的更简单方法,请告诉我,因为这对我来说是一个需要解决的过程。

【讨论】:

【参考方案3】:

检查您的图像 css 上的以下内容

显示:通常设置为阻止 位置:如果最初不加载,可能需要设置为固定 最大宽度:检查是否更改 最大高度:检查是否更改

您可能假设应用于组件的 css 规则保持初始加载时的状态,但如果您运行了一些 javascript 来管理这些规则,则您可能必须在 ajax 完成加载后重新应用其中的一些规则。一些浏览器可能能够应用它们。我需要在网上找到那个帖子,但现在如果你可以查看上面的内容并且它没有解决你的问题,那么请在这里告诉我。要隔离 img 问题,您可以使用单个图像创建测试页面并共享链接并从该页面中删除尽可能多的其他项目。也许只是基本的页眉和页脚来隔离其他问题。

【讨论】:

我在我的问题中添加了一个编辑 1,我在其中解释了我是如何尝试使用在 AJAX 加载后更新图像样式的方法来解决的。

以上是关于AJAX 加载的图像无法在 Safari 中正确显示的主要内容,如果未能解决你的问题,请参考以下文章

图像无法在 iOS 上的 Safari 上加载

将 createObjectURL 的结果分配给图像无法在移动 Safari 上加载资源

在AJAX调用后附加到Flexslider后,无法使用Fancybox打开图像

本地加载 XML 的 jQuery Ajax 问题 - Safari 版本 11.0 - 错误:XMLHttpRequest 无法加载 .xml。预检响应不成功

Safari 浏览器无法处理 Click 事件以显示加载图像

无法在 Safari 中加载跨域图像(来自 CloudFront)