【问题标题】:show alternate image if img src is not found - knockout如果找不到 img src,则显示替代图像 - 淘汰赛
【发布时间】:2016-02-17 01:37:13
【问题描述】:

我有这段代码。

<img data-bind="attr: {src: 'imagePath'}, style: { 'background-image': 'url('imagePath')' }" class="img-responsive">

问题是它显示了两个图像。一个是来自src 的图像,另一个来自background 图像。我的目标是在src 图像不可用时启用background 图像。

【问题讨论】:

  • 为什么不只使用src 属性,并将其连接到一个可观察的对象,以便在图像源可用时解析它?
  • 默认显示后备图像,并在找到其他图像时替换它。
  • 使用背景图像作为替代会产生一些问题,例如,它仍然会显示损坏的图像图标,您需要设置高度和宽度。这就是为什么只使用 src 似乎是一个更好的解决方案。
  • 只是想知道我的回答是否确实回答了您的问题?

标签: javascript html knockout.js


【解决方案1】:

您可以做的是创建一个自定义绑定,我们称之为safeSrc

在此绑定中,您会监听图像的 loaderror 事件 - 如果图像加载成功则渲染图像,如果加载失败则渲染回退。

实际上,它可能如下所示:

ko.bindingHandlers.safeSrc = {
  update: function(element, valueAccessor) {
    var options = valueAccessor();
    var src = ko.unwrap(options.src);
    $('<img />').attr('src', src).on('load', function() {
      $(element).attr('src', src);
    }).on('error', function() {
      $(element).attr('src', ko.unwrap(options.fallback));
    });
  }
};

然后,您可以像这样应用绑定:

<img alt="Foo" data-bind="safeSrc: {src: imageObservable, fallback: 'https://example.com/fallback.png'}" />

请注意,这假定您使用的是 jQuery - 但您可以轻松地重写事件侦听器。

最后,我还想说,您应该渲染一个不同的src,而不是背景图像 - 除非您有特定的理由需要它?

无论哪种方式,您都可以简单地将行 $(element).attr('src', ko.unwrap(options.fallback)); 更改为 $(element).css('background-image', 'url(' + ko.unwrap(options.fallback) + ')');

JS Fiddle 演示

在这里,您可以看到这一切:https://jsfiddle.net/13vkutkv/2/

(编辑:我用 Placehold.it 替换了指向 Knockout JS 徽标的厚颜无耻的热链接)

【讨论】:

  • 注意后备图像不会失败并触发 on 错误,它可能会陷入无限循环。
  • 非常好。但是我已经解释了这个问题:这个绑定创建了一个虚拟图像元素来检查它是否加载成功,而不是使用传递给绑定的原始 DOM 元素。除非我误解了你的意思。
  • 啊,是的,不错的解决方案!我没有对代码付出太多的关注,因为它看起来与我实现的东西非常相似。可能不得不捏造这个想法以备将来使用。
  • 不用担心。但是你是对的,这个解决方案不会处理丢失的后备图像 - 让我们让开发人员不要依赖 404。:)
【解决方案2】:

如果找不到 img src 则显示备用图像在您的服务器逻辑中创建备用图像链接并在您的前端仅使用 src: 'imagePath'

或者如果在前端做这件事很重要,你应该看看这篇文章: Display alternate image

【讨论】:

  • 不错的答案,但添加一些示例代码会有所帮助。
  • @Roberto ,谢谢,非常高兴,但我不知道他(她)的后端(
【解决方案3】:

我总是使用延迟对象检查我的图像,以确保它们能够加载。这是使用 jquery deferred 方法,但您可以使用任何延迟库。我是凭记忆编写的,所以可能会有一些错误。

<img data-bind="attr: {src: $root.imagePath()}, style: { 'background-image': 'url('imagePath')' }" class="img-responsive">

var myController = function()
{
    var self = this;
    this.imagePath = ko.observable('myPath.png'); // Make the image url an observable
    var getImagePath = function(path)
    { 
        var imagePath = this.imagePath();
        isLoaded(imagePath).done(function(result)
        {
            // The image will load fine, do nothing.
        }).fail(function(e)
        {
            self.imagePath('defaultImageOnFail.png'); // replace the image if it fails to load
        });
    };
    getImagePath();
};

var isLoaded = function(img)
{
    var deferred = new $.Deferred();
    var imgObj = $("<img src='"+img+"'/>");
    if(imgObj.height > 0 || imgObj.width > 0)
    {
        deferred.resolve(true);
    }
    else
    {
        imgObj.on("load", function(e)
        {
            deferred.resolve(true);
        });
        imgObj.on("error", function(e)
        {
            console.info("VoteScreenController.isLoaded URL error");
            deferred.reject();
        });
    }
    return deferred.promise();
};

【讨论】:

    猜你喜欢
    • 2013-09-28
    • 2023-02-05
    • 2016-07-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-07
    • 1970-01-01
    • 1970-01-01
    • 2014-05-17
    相关资源
    最近更新 更多