如果找不到img src则显示替代图像 - 淘汰赛

时间:2016-02-15 20:22:15

标签: javascript html knockout.js

我有这段代码。

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

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

3 个答案:

答案 0 :(得分:8)

您可以做的是创建自定义绑定,让我们称之为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小提琴演示

在这里,您可以看到所有内容:https://jsfiddle.net/13vkutkv/2/

(编辑:我用Placehold.it将厚脸皮的热链接替换为Knockout JS徽标)

PS:根据您希望以后与元素交互的方式(与绑定交互/更新绑定),您可能希望使用applyBindingsToNode(即Knockout-way),而不是操纵{{ 1}}直接在DOM元素上进行属性。

答案 1 :(得分:0)

要显示替代图像,如果找不到img src,请在服务器逻辑中创建备用图像链接,并仅使用src:&#39; imagePath&#39;在你的前端

或者如果在前端执行它很重要,你应该看一下这篇文章: Display alternate image

答案 2 :(得分:0)

我总是用延迟对象检查我的图像,以确保它们会加载。这是使用jquery延迟方法,但您可以使用任何延迟库。我是从内存中编码的,所以可能会有一些错误。

<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();
};