为什么我的img错误函数失败了?

时间:2013-07-18 02:03:48

标签: javascript jquery html razor asp.net-webpages

我动态构建的一些img元素可能会(失败)失败。对于这些情况,我从这里得到了一些代码:Is there a way to programmatically determine that an image link is bad?即:

    function getNatlBookCritics() {
        var htmlBuilder = '';

        // Doesn't do diddly-squat - wrong spot for it?
        $('img').error(function () {
            $(this).attr("src", "Content/NoImageAvailable.png");
        });

        $.getJSON('Content/NBCCJr.json', function (data) {
            $.each(data, function (i, dataPoint) {
    . . .

......但它不起作用。 Warum nicht?

更新

将此代码放在$ .getJSON()调用的.each部分中:

var jObject = $('<img src=\"' + dataPoint.imghref + '\"/>');
$(jObject).error(function () {
    $(this).attr("src", "Content/NoImageAvailable.jpg");
});

... 所有图像都失败了。 dataPoint.imghref包含以下值:

http://www.amazon.com/exec/obidos/ASIN/B00655KLOY/garrphotgall-20

更新2

在地狱中,我正在添加“img src”,如下所示:

function getNatlBookCritics() {
    var htmlBuilder = '';
    $.getJSON('Content/nbcc.json', function (data) {
        $.each(data, function (i, dataPoint) {
            if (IsYear(dataPoint.category)) {
                htmlBuilder += '<div class=\"yearBanner\">' + dataPoint.category + '</div>';
            } else {
                htmlBuilder += '<section class=\"wrapper\" ><a id=\"mainImage\" class=\"floatLeft\" href=\"' +
                    dataPoint.imghref + '\"' + ' target=\"_blank\"><img height=\"160\" width=\"107\" src=\"' +
                    dataPoint.imgsrc + '\"' +
                    dataPoint.imgalt + '></img></a>' +
    . . .
                htmlBuilder += '</section>';
            }
    // this is where I had the img err code
        }); //each
        $('#BooksContent').append(htmlBuilder);
    });     //getNatlBookCritics

...所以你可以看到img被添加到DOM中;也许事实上,我的img有高度和宽度属性是问题......

更新3

ManMohan Vyas:你的意思是这样的:

}); //each
        $('#BooksContent').append(htmlBuilder).
    find("img").error(function(){ 
        $(this).attr("src", "Content/NoImageAvailable.png");
    });
    });     //getJSON()

更新4

此:

var jObject = $(htmlBuilder);
jObject.find("img").error(function () {
    $(this).attr("src", "Content/NoImageAvailable.png");
});
$('#BooksContent').append(jObject);

......没用。

和FWIW,改变这个:

$('#BooksContent').html('');

。 。 。     $( '#BooksContent')附加(htmlBuilder);

......对此:

$( '#BooksContent')replaceWith(htmlBuilder);

...效果不好(填充了正确的东西,但格式化了所有混乱(而不是纯黑色背景,每个部分都有黑色背景,但整体背景是银色)。

更新5

我只是想到可能导致我的问题的一些事情:我试图展示的图像都是jpgs,但是“Image Not Available”图像是png。这有什么区别吗?这可能是导致渲染引擎混淆的原因吗?如果是这样,我只会将后备img保存为jpg ......

更新6

不,这最后两次尝试也没有用。我尝试了约瑟夫迈尔斯的想法,然后是Prestauls,因为我改变了这个想法:

dataPoint.imghref + '\"' + ' onerror=\"imgError(this);\" target=\"_blank\"><img height=\"160\" width=\"107\" src=\"' +
dataPoint.imgsrc + '\"' +

..对此:

dataPoint.imgsrc + '\" onerror=\"imgError(this);\"' +
dataPoint.imgalt + '></img></a>' +

......没有区别。我在jQuery论坛上问过这个问题:我在这里抓住了吸管,但我想知道是否有不匹配的jQuery / jQueryUI版本可能是问题?为了支持旧的浏览器,我仍然使用jQuery 1.9.1,但对于版本为1.10.3的jQueryUI,我处于“前沿”。

更新7

好的,这是所有相关代码(一些冗余和模拟代码将被重构,已被省略以符合SO的长度限制)。 (静态)CSS应该不重要,对吗?唯一的其他“代码”是Web.config和那种性质的东西,所以这些都不应该影响为什么我无法显示后备图像。

很多失败的尝试让NoImageAvailable.png显示出来都被注释掉了。

@{
    Layout = "~/_SiteLayout.cshtml";
    Page.Title = "My Next Winner";
}
<div id="tabs" class="content-wrapper">
    <ul>
        <li><a href="#tab-Books">Books</a></li>
        <li><a href="#tab-Movies">Movies</a></li>
        <li><a href="#tab-Music">Music</a></li>
    </ul>
    <div id="tab-Books">
        <select id="bookDropDown">
            <option value="Pulitzer">Pulitzer</option>
            <option value="NBCC">National Book Critics Circle</option>
            <option value="NBA">National Book Awards</option>
            <option value="NOBA">National Outdoors Book Awards</option>
        </select>
        <div id="BooksContent" class="clearfix">Content in Books tab</div>
    </div>
    <div id="tab-Movies">

。 。 。          。 。 。     

<script>
    $.ajaxSetup({ cache: false });
    var currentBookSelection = ''; 
    var currentMovieSelection = '';
    var currentMusicSelection = '';

    function imgError(image) {
        image.onerror = "";
        image.src = "Content/NoImageAvailable.png"; 
        return true;
    }

    // BOOKS
// TODO: Refactor: just have one "getBooks()" function, passing in the name of the json file
    function getNatlBookCritics() {
        var htmlBuilder = '';

        $.getJSON('Content/nbcc.json', function (data) {
            $.each(data, function (i, dataPoint) {
                if (IsYear(dataPoint.category)) {
                    htmlBuilder += '<div class=\"yearBanner\">' + dataPoint.category + '</div>';
                } else { // see snippet at top of unit for dealing with landscape-oriented books (such as some children's books) to change height and width of img
                    htmlBuilder += '<section class=\"wrapper\" ><a id=\"mainImage\" class=\"floatLeft\" href=\"' +
                        dataPoint.imghref + '\"' + ' target=\"_blank\"><img height=\"160\" width=\"107\" src=\"' +
                        //dataPoint.imghref + '\"' + ' onerror=\"imgError(this);\" target=\"_blank\"><img height=\"160\" width=\"107\" src=\"' +
                        //dataPoint.imgsrc + '\" onerror=\"imgError(this);\"' +
                        dataPoint.imgsrc + '\"' +
                        dataPoint.imgalt + '></img></a>' +
                        '<div id=\"prizeCategory\" class=\"category\">' +
                        dataPoint.category +
                        '</div><br/><cite id=\"prizeTitle\" >' +
                        dataPoint.title +
                        '</cite><br/><div id=\"prizeArtist\" class=\"author\">' +
                        dataPoint.author +
                        '</div><br/>';
                    if (dataPoint.kindle.trim().length > 2) {
                        htmlBuilder += '<button><a href=\"' + Urlify(dataPoint.kindle) + '\"' +
                            ' target=\"_blank\">Kindle</a></button>';
                    }
                    if (dataPoint.paperback.trim().length > 2) {
                        htmlBuilder += '<button><a href=\"' + Urlify(dataPoint.paperback) + '\"' +
                            ' target=\"_blank\">Paperback</a></button>';
                    }
                    if (dataPoint.hardbound.trim().length > 2) {
                        htmlBuilder += '<button><a href=\"' + Urlify(dataPoint.hardbound) + '\"' +
                            ' target=\"_blank\">Hardcover</a></button>';
                    }
                    htmlBuilder += '</section>';

                    //// Doesn't work
                    //$('img').error(function () {
                    //    $(this).attr("src", "Content/NoImageAvailable.png");
                    //});
                    // When get answer, try this: <-- they all fail with this
                    //var jObject = $('<img src=\"' + dataPoint.imghref + '\"/>');
                    //var jObject = $('<img src=' + dataPoint.imghref + ' />');
                    //$(jObject).error(function () {
                    //    $(this).attr("src", "Content/NoImageAvailable.jpg");
                    //});
                }
            }); //each
            //var jObject = $(htmlBuilder).find('img').error(function () {
            //    $(this).attr("src", "Content/NoImageAvailable.png")
            //});

            //$("#BooksContent").html(jObject);
            //var jObject = $(htmlBuilder);
            //jObject.find("img").error(function () {
            //    $(this).attr("src", "Content/NoImageAvailable.png");
            //});
            //$('#BooksContent').append(jObject);

            // 7/23
            //imageError = function (it) {
            //    $(it).attr("src", "Content/NoImageAvailable.png");
            //};
            //htmlBuilder = htmlBuilder.replace(/<img/g, '<img onerror="imageError(this)"');
            //var jObject = $(htmlBuilder);

            //$("#BooksContent").html(jObject);
            // </ 7/23

            //$('#BooksContent').html('');
            //$('#BooksContent').append(htmlBuilder);

            ////try this 7/24/2013
            //var $jObject = $('<img>');
            //$jObject.error(function () { //$jObject is already a jquery object, don't wrap it again
            //    $(this).attr("src", "Content/NoImageAvailable.jpg");
            //}).attr('src', dataPoint.imghref);
            //</try this 7/24/2013

            //$('#BooksContent').html(htmlBuilder);
            $('#BooksContent').html(htmlBuilder).
                 find('img, button').click(function (evt) {
                     $(this).css('border', '1px solid red')
                     //evt.preventDefault();
                     //find('img').error(function() {
                     //    this.src = "/Content/NoImageAvailable.png"
                     //})
                 });

            //$('#BooksContent').replaceWith(htmlBuilder);
                //.find('img').error(function() {
                //    this.src = "Content/NoImageAvailable.png"
                //    //this.src = "http://www.gravatar.com/avatar/317f4b62da2b0186feac9b6209793505?s=80&d=http%3A%2F%2Fimg.zohostatic.com%2Fdiscussions%2Fv1%2Fimages%2FdefaultPhoto.png";
                //});
            $('#BooksContent').css('background-color', 'black');
            $('button').button();
        }); //getJSONnbcc
        $largest = 0;
        $(".wrapper").each(function () {
            if ($(this).height() > $largest) {
                $largest = $(this).height();
            }
        });
        $(".wrapper").css("height", $largest);
    }   // getNatlBookCritics()

    function getPulitzers() {
        // Since pulitzers will be the one that shows when site first opens, added rel="nofollow"
        // in each href; in this way only this method differs from the other "getX" book methods
        var htmlBuilder = '';

        $.getJSON('Content/pulitzers2.json', function (data) {
            $.each(data, function (i, dataPoint) {
                if (IsYear(dataPoint.category)) {
                    htmlBuilder += '<div class=\"yearBanner\">' + dataPoint.category + '</div>';
                } else { // see snippet at top of unit for dealing with landscape-oriented books (such as some children's books) to change height and width of img
                    htmlBuilder += '<section class=\"wrapper\" ><a id=\"mainImage\" class=\"floatLeft\" href=\"' +
                        dataPoint.imghref + '\"' + ' target=\"_blank\"><img height=\"160\" width=\"107\" src=\"' +
                        dataPoint.imgsrc + '\"' +
                        dataPoint.imgalt + '></img></a>' +
                        '<div id=\"prizeCategory\" class=\"category\">' +
                        dataPoint.category +
                        '</div><br/><cite id=\"prizeTitle\" >' +
                        dataPoint.title +
                        '</cite><br/><div id=\"prizeArtist\" class=\"author\">' +
                        dataPoint.author +
                        '</div><br/>';
                    if (dataPoint.kindle.trim().length > 2) {
                        htmlBuilder += '<button><a href=\"' + Urlify(dataPoint.kindle) + '\"' +
                            ' target=\"_blank\" rel=\"nofollow\" >Kindle</a></button>';
                    }
                    if (dataPoint.hardbound.trim().length > 2) {
                        htmlBuilder += '<button><a href=\"' + Urlify(dataPoint.hardbound) + '\"' +
                            ' target=\"_blank\" rel=\"nofollow\" >Hardcover</a></button>';
                    }
                    if (dataPoint.paperback.trim().length > 2) {
                        htmlBuilder += '<button><a href=\"' + Urlify(dataPoint.paperback) + '\"' +
                            ' target=\"_blank\" rel=\"nofollow\" >Paperback</a></button>';
                    }
                    htmlBuilder += '</section>';
                }
            }); //each
            $('#BooksContent').html(htmlBuilder).
     find('img, button').click(function (evt) {
         $(this).css('border', '1px solid red')
     });

            $('#BooksContent').css('background-color', 'black');
            $('button').button();
        }); //getPulitzers
        $largest = 0;
        $(".wrapper").each(function () {
            if ($(this).height() > $largest) {
                $largest = $(this).height();
            }
        });
        $(".wrapper").css("height", $largest);
        // This is not working; axed a question on the jQuery forum
        $('img, button').click(function (evt) {
            $(this).css('border', '5px solid green');
            evt.preventDefault();
        });
        // added this 7/24/2013 - does nothing
        //$(function () {
        //    $('a').click(function () {
        //        open(this.href, 'NewWin', 'toolbar=yes');
        //        self.focus();
        //        return false;
        //    });
        //});
    } // getPulitzers()

    function getNatlBook() {

。 。 。 } // getNatlBook()

    function getNOBA() {
        // load bookContents using getJSON
    }

    // MOVIES
    // Movies differ from books and music in that some of the awards do not always have a person as winner - just the movie
    // So we have to check for that and conditionally add that bit of html (what corresponds to author in books and
    // artist in music)
    function getMovies(pathToJsonFile) {
        var htmlBuilder = '';

        $.getJSON(pathToJsonFile, function (data) {
            // I tried renaming the above to nbcc.json, but it won't work with that name...?!? $.getJSON('Content/nbcc.json', function (data) {
            $.each(data, function (i, dataPoint) {
                if (IsYear(dataPoint.category)) {
                    htmlBuilder += '<div class=\"yearBanner\">' + dataPoint.category + '</div>';
                } else { // see snippet at top of unit for dealing with landscape-oriented books (such as some children's books) to change height and width of img
                    htmlBuilder += '<section class=\"wrapper\" ><a id=\"mainImage\" class=\"floatLeft\" href=\"' +
                        dataPoint.imghref + '\"' + ' target=\"_blank\"><img height=\"160\" width=\"107\" src=\"' +
                        dataPoint.imgsrc + '\"' +
                        dataPoint.imgalt + '></img></a>' +
                        '<div id=\"prizeCategory\" class=\"category\">' +
                        dataPoint.category +
                        '</div><br/><cite id=\"prizeTitle\" >' +
                        dataPoint.film +
                        '</cite><br/>';
                    if (dataPoint.person.trim().length > 2) {
                        htmlBuilder += '<div id=\"prizeArtist\" class=\"person\">' + dataPoint.person + '</div><br/>';
                    }
                    if (dataPoint.bluray.trim().length > 2) {
                        htmlBuilder += '<button><a href=\"' + Urlify(dataPoint.bluray) + '\"' +
                            ' target=\"_blank\" >BluRay</a></button>';
                    }
                    if (dataPoint.dvd.trim().length > 2) {
                        htmlBuilder += '<button><a href=\"' + Urlify(dataPoint.dvd) + '\"' +
                            ' target=\"_blank\" >DVD</a></button>';
                    }
                    htmlBuilder += '</section>';
                }
            }); //each
            $('#MoviesContent').html(htmlBuilder).
                 find('img, button').click(function (evt) {
                     $(this).css('border', '1px solid silver')
                 });
            $('#MoviesContent').css('background-color', 'black');
            $('button').button();
            //console.log(htmlBuilder); <-- may want this for response to click on tab when movie tab is selected
        }); //getOscars
        $largest = 0;
        $(".wrapper").each(function () {
            if ($(this).height() > $largest) {
                $largest = $(this).height();
            }
        });
        $(".wrapper").css("height", $largest);
    }

    // MUSIC 
    // "work" is used for "album or song or recording or performance"
//TODO: Make this a generic "Music" function a la Movies above
    function getGrammies() {
        var htmlBuilder = '';

        $.getJSON('Content/grammies.json', function (data) {
            $.each(data, function (i, dataPoint) {
                if (IsYear(dataPoint.category)) {
                    htmlBuilder += '<div class=\"yearBanner\">' + dataPoint.category + '</div>';
                } else { // see snippet at top of unit for dealing with landscape-oriented books (such as some children's books) to change height and width of img
                    htmlBuilder += '<section class=\"wrapper\" ><a id=\"mainImage\" class=\"floatLeft\" href=\"' +
                        dataPoint.imghref + '\"' + ' target=\"_blank\"><img height=\"160\" width=\"107\" src=\"' +
                        dataPoint.imgsrc + '\"' +
                        dataPoint.imgalt + '></img></a>' +
                        '<div id=\"prizeCategory\" class=\"category\">' +
                        dataPoint.category +
                        '</div><br/><cite id=\"prizeTitle\" >' +
                        dataPoint.work +
                        '</cite><br/><div id=\"prizeArtist\" class=\"work\">' +
                        dataPoint.artist +
                        '</div><br/>';
                    if (dataPoint.mp3.trim().length > 2) {
                        htmlBuilder += '<button><a href=\"' + Urlify(dataPoint.mp3) + '\"' +
                            ' target=\"_blank\">mp3</a></button>';
                    }
                    if (dataPoint.dvd.trim().length > 2) {
                        htmlBuilder += '<button><a href=\"' + Urlify(dataPoint.dvd) + '\"' +
                            ' target=\"_blank\">DVD</a></button>';
                    }
                    if (dataPoint.vinyl.trim().length > 2) {
                        htmlBuilder += '<button><a href=\"' + Urlify(dataPoint.vinyl) + '\"' +
                            ' target=\"_blank\">Vinyl</a></button>';
                    }
                    htmlBuilder += '</section>';

                    //// Doesn't work
                    //$('img').error(function () {
                    //    $(this).attr("src", "Content/NoImageAvailable.png");
                    //});
                }
            }); //each
            $('#MusicContent').html(htmlBuilder).
     find('img, button').click(function (evt) {
         $(this).css('border', '1px solid gold')
     });
            $('#MusicContent').css('background-color', 'black');
            $('button').button();
        }); //getJSONMusic
        $largest = 0;
        $(".wrapper").each(function () {
            if ($(this).height() > $largest) {
                $largest = $(this).height();
            }
        });
        $(".wrapper").css("height", $largest);
    }

    function configLoading() {
        $('#lblLoading').show();
// TODO: Not working for some reason - the configLoaded never sets them back to enabled...
        //$('bookDropDown').Attr('disabled', true);
        //$('moviesDropDown').Attr('disabled', true);
        //$('musicDropDown').Attr('disabled', true);
    }

    function configLoaded() {
        $('#lblLoading').hide();
        //$('bookDropDown').Attr('disabled', false);
        //$('moviesDropDown').Attr('disabled', false);
        //$('musicDropDown').Attr('disabled', false);
    }

        $(document).ready(function () {
            $('#tabs').tabs({
                beforeActivate: function (event, ui) {
                    // Pulitzers is loaded at first; any time the books tab is clicked, something will already be there
                    if (ui.newTab.index() == 1) {
                        moviesContent = $('#MoviesContent').html();
                        if (moviesContent == 'Content in Movies tab') {
                            // TODO: When it's ready, uncomment this: getOscars();
                        }
                    }
                    else if (ui.newTab.index() == 2) {
                        musicContent = $('#MusicContent').html();
                        if (musicContent == 'Content in Music tab') {
                            // TODO: When it's ready, uncomment this: getGrammies();
                        }
                    }
                }
            });

            $('body').on('error', 'img', function (e) {
                $(e.currentTarget).attr("src", "Content/NoImageAvailable.png");
            });

            // This makes the external hrefs / targets "pop up"; I don't think I want that...
            //$('body').on('click', 'a', function () {
            //    open(this.href, 'NewWin', 'toolbar=yes')
            //    self.focus();
            //    return false;
            //});

            // Books tab is default view; load the default list (Pulitzer); the other two default lists (oscars and grammies)
            // will load the first time the user selects the corresponding tab (see beforeActivate() above)
            getPulitzers();
            currentBookSelection = "Pulitzer";
            configLoaded();

            $('#bookDropDown').change(function () {
                // TODO: May want to keep track of when in loading mode, and if so, exit/return
                configLoading();
                $('#body').removeClass('bronzeBackground silverBackground goldBackground').addClass('bronzeBackground');
                var sel = this.value;
                if ((sel == "NBCC") && (currentBookSelection != "NBCC")) {
                    getNatlBookCritics();
                    currentBookSelection = "NBCC";
                }
                else if ((sel == "NBA") && (currentBookSelection != "NBA")) {
                    getNatlBook();
                    currentBookSelection = "NBA";
                }
                else if ((sel == "NOBA") && (currentBookSelection != "NOBA")) {
                    getNOBA();
                    currentBookSelection = "NOBA";
                }
                else if ((sel == "Pulitzer") && (currentBookSelection != "Pulitzer")) {
                    getPulitzers();
                    currentBookSelection = "Pulitzer";
                }
                configLoaded();
            }); //bookDropDown

            $('#moviesDropDown').change(function () {
                configLoading();
                $('#body').removeClass('bronzeBackground silverBackground goldBackground').addClass('silverBackground');
                var sel = this.value;
                if ((sel == "Oscars") && (currentMovieSelection != "Oscars")) {
                    currentMovieSelection = "Oscars";
                    getMovies('Content/oscars.json');
                }
                else if ((sel == "GoldenGlobe") && (currentMovieSelection != "GoldenGlobe")) {
                    currentMovieSelection = "GoldenGlobe";
                    getMovies('Content/goldenglobe.json');
                }
                else if ((sel == "Cannes") && (currentMovieSelection != "Cannes")) {
                    currentMovieSelection = "Cannes";
                    getMovies('Content/cannes.json');
                }
                else if ((sel == "Sundance") && (currentMovieSelection != "Sundance")) {
                    currentMovieSelection = "Sundance";
                    getMovies('Content/sundance.json');
                }
                configLoaded();
            }); //moviesDropDown

            $('#musicDropDown').change(function () {
                configLoading();
                $('#body').removeClass('bronzeBackground silverBackground goldBackground').addClass('goldBackground');
                var sel = this.value;
                if ((sel == "Grammies") && (currentMusicSelection != "Grammies")) {
                    currentMusicSelection = "Grammies";
                    getGrammies();
                }
                else if ((sel == "AMA") && (currentMusicSelection != "AMA")) {
                    currentMusicSelection = "AMA";
                    getAMA();
                }
                else if ((sel == "CMA") && (currentMusicSelection != "CMA")) {
                    currentMusicSelection = "CMA";
                    getCMA();
                }
                else if ((sel == "Indies") && (currentMusicSelection != "Indies")) {
                    currentMusicSelection = "Indies";
                    getIndies();
                }
                configLoaded();
            }); //musicDropDown

            // added 7/24/2013, changed nothing
            //$(function() {
            //    $('a').click(function() {
            //        open(this.href, 'NewWin', 'toolbar=yes');
            //        self.focus();
            //        return false;
            //    });
            //});

        }); //ready
</script>

更新8

巴瓦兹的回答对我来说也不起作用;也许我做错了?基于他的回答,这就是我补充的内容:

CSS

.noImg {
  background:url(~/Content/NoImageAvailable.png);    
}

的jQuery

0)在就绪处理程序中添加了这个:

replaceEmptyImage = function ($img) {
    $img.parent().addClass('noImg');
    $img.remove();
};

1)改变了这一行:

dataPoint.imghref + '\"' + ' target=\"_blank\"><img height=\"160\" width=\"107\" src=\"' +

......对此:

dataPoint.imghref + '\"' + ' target=\"_blank\"><img height=\"160\" width=\"107\" onerror=\"replaceEmptyImage($(this))\" src=\"' +

更新9

这是它的样子(图像“块”或“对象”在那里,它只是它的黑色/空白):

enter image description here

BTW,Jamie McPheeters的游记无论如何都是一本很棒的书,但也许尤其是给你的孩子读书(任何年龄,但也许是青少年时期最佳)。

8 个答案:

答案 0 :(得分:6)

虽然您的解释不是很清楚,但最可能的原因是,在调用函数<img>

时,您的$('img').error();标记不存在

尝试

1)创建一个带有一些id的动态图像 2)将img标记放入DOM后调用错误函数。

<img>标记未与错误函数绑定,这是我可以看到不使用代码的唯一原因。 现在是工作样本:

<强> HTML:

<div id="myId">
    h
</div>

jQuery脚本:

var jObject = $("<img src='helo.png' />");

$(jObject).error(function(){
    $(this).attr("src", "http://rack.2.mshcdn.com/media/ZgkyMDEyLzEyLzAzL2U0L3NlZWhvd3lvdXJnLjlyMS5qcGcKcAl0aHVtYgk5NTB4NTM0IwplCWpwZw/8fec6ce4/e71/see-how-your-google-results-measure-up-with-google-grader-video--6b8bbb4b41.jpg");

});

$("#myId").html(jObject);

你可以在这里查看工作小提琴[http://jsfiddle.net/jyXqw/] [1]

编辑 *

var jObject = $(htmlBuilder);
 jObject.find("img").error(function(){
      $(this).attr("src", "Content/NoImageAvailable.png");
    });
 $('#BooksContent').append(jObject);

EDIT-2 * 检查小提琴,你的代码似乎正常工作:http://jsfiddle.net/jYbQx/

答案 1 :(得分:3)

基于通过电子邮件发送给我的部分代码进行更新

这只是猜测,因为缺少所有主要脚本和JSON数据,所以我无法对其进行测试。但是,这些更改有望使它适合您。请测试一下!

在你的代码说明之前

<div id="tabs" class="content-wrapper">

您应该完全按照写入页面的方式添加此代码(我注意到您尚未在页面中包含此代码):

<script src="//desandro.github.io/imagesloaded/imagesloaded.pkgd.min.js">
</script>

然后,在函数configLoaded内部,您需要添加第二个代码块(代码的新更改标记为NEW):

function configLoaded() {
    $('#lblLoading').hide();
    var imgLoad = imagesLoaded('body');                    /* NEW */
    imgLoad.on( 'progress', function( instance, image ) {  /* NEW */
        var result = image.isLoaded ? 'loaded' : 'broken'; /* NEW */
        image.img.src = 'Your-Placeholder-Image.png';      /* NEW */
    });                                                    /* NEW */
    //$('bookDropDown').Attr('disabled', false);
    //$('moviesDropDown').Attr('disabled', false);
    //$('musicDropDown').Attr('disabled', false);
}

这样,当您的菜单加载新图像时,将再次附加进度/错误处理程序(如果生成新图像后需要)。当然,最重要的是你要包含imagesloaded.pkgd.min.js脚本代码,因为如果没有它,代码的第二部分就无能为力。

注意问题的作者

我的所有建议都可以100%的时间用于我,完全测试就像正确的Stack Overflow应答一样。不幸的是,这些解决方案没有机会将正确地合并到您的代码中,因为我缺少您的完整代码或自包含的示例。

你给出的简单介绍,以及你在另一个问题中提供的JS Fiddle(只有一行JavaScript),以及来自你和其他人的各种评论的JS Fiddles都给了我一个明确的图片你的问题是什么。然而,如果没有足够的实际代码(理想情况下所有代码),我无法向您展示如何正确地合并解决方案 - 这就像汽车修理工试图在汽车不在时修理汽车,或者数学老师试图用手动而不是写东西来教某人数学问题。

我可以让我的任何解决方案都适合您,但我需要的只是指向包含问题的完整代码的链接,或者如果由于某种原因它是保密的,那么至少是一个自包含的示例。请参阅:http://sscce.org

您是否介意提供完整代码或自包含示例的链接?我很乐意修改它,以便它适合你。即,如果这些解决方案对您不起作用,那么您的代码中还有其他内容需要修复,在此之前,我正在为社区的利益提供此答案。

使用推荐的解决方案进行更新

将此脚本添加到您的页面:

<script src="//desandro.github.io/imagesloaded/imagesloaded.pkgd.min.js">
</script>

该脚本提供了正确检测页面上所有损坏图像的功能。在此处阅读相关内容,包括一个演示,其中显示了您希望为自己的网站实现的功能:http://desandro.github.io/imagesloaded/

然后将以下代码选项之一添加到现有JavaScript中。 (您可能还需要删除从代码中检测图像加载错误的所有其他尝试,以确保没有冲突。)

var imgLoad = imagesLoaded('body');
imgLoad.on( 'always', function() {
  console.log( imgLoad.images.length + ' images loaded' );
  // detect which image is broken
  for ( var i = 0, len = imgLoad.images.length; i < len; i++ ) {
    var image = imgLoad.images[i];
    var result = image.isLoaded ? 'loaded' : 'broken';
    console.log( 'image is ' + result + ' for ' + image.img.src );
    if (result == 'broken')
        image.img.src = 'Your-Placeholder-Image.png'; /* CHANGE THIS */
  }
});

此代码应该可以正常或更好地运行,甚至更短。

var imgLoad = imagesLoaded('body');
imgLoad.on( 'progress', function( instance, image ) {
  var result = image.isLoaded ? 'loaded' : 'broken';
  console.log( 'image is ' + result + ' for ' + image.img.src );
  image.img.src = 'Your-Placeholder-Image.png'; /* CHANGE THIS */
});

一般观察

  

&#34;在所有浏览器中,加载,滚动和错误事件(例如,在   &LT; IMG&GT;元素)不要泡。在Internet Explorer 8及更低版本中   粘贴和重置事件不会冒泡。不支持此类事件   与委托一起使用,但它们可以在事件处理程序中使用   直接附加到生成事件的元素。&#34;

     

http://api.jquery.com/on/

解释:在jQuery命令异步生成HTML内容的文档中,您无法使用jQuery选择器可靠地捕获图像加载错误。

因此,在为图像注册错误处理程序时(例如将其替换为&#34;没有图像可用&#34;图像),在图像元素被注册之前在图像上注册错误处理程序是很重要的。插入DOM或成为实时文档片段。如果您的图像src存在于纯JavaScript字符串中,则需要确保在将该字符串转换为实时文档片段之前指定了onerror处理程序。如果您的图片src存在于JavaScript图片对象中,那么指定错误处理程序已经太晚了 - 在这种情况下,您必须在src之前指定处理程序。

否则,在将图像元素插入DOM之后,以及在注册事件处理程序之前,存在竞争条件。由于不需要加载图像数据,因此图像可以非常快速地返回404 Not Found。如果在检测到404之前未完全附加事件处理程序,则不会调用事件处理程序。

将错误图像设为PNG而不是JPEG并不重要。

构建代码的方式,它形成一个HTML字符串,然后将其转换为实时HTML对象,将其用作jQuery构造函数的参数,只有然后设置错误它包含的img元素的处理程序。这会导致与不包含onerror属性的HTML源相同的问题,然后尝试使用脚本设置错误处理程序。你提到的行为

这对我有用,只需更改JS Fiddle中的最后几行,并在将任何内容转换为实际实时元素之前在HTML字符串中设置属性:

imageError = function(it) {
    $(it).attr("src","placeholder.jpg");
};

htmlBuilder = htmlBuilder.replace(/<img/g, '<img onerror="imageError(this)"');
var jObject = $(htmlBuilder);

 $("#container").html(jObject);

您表示这不起作用,但它应该(在将placeholder.jpg#container更改为您自己的值之后),并且正确的诊断要求我查看您网页中的所有内容,因为其他任何内容你这样做可能会影响为什么这不适合你。

您拥有的其他选项(已更新)

正确实施使用错误处理程序的解决方案要求您在指定图像的onerror之前注册error / src事件处理程序实时文档片段。

然而,还有其他选择。例如,在加载整个文档之后,您可以创建一个循环遍历所有页面图像元素的函数,找到那些未加载的图像元素,并更改其src属性。

此处概述了该解决方案:

https://stackoverflow.com/a/93017/2188862

我无法保证它能够正常运作,因为正如我所提到的,你所做的任何其他事情都可能会影响为什么某些东西不适合你。

这种解决问题的方法还有一个插件,可以使用您的代码。 https://github.com/desandro/imagesloaded

首次将插件http://desandro.github.io/imagesloaded/imagesloaded.pkgd.min.js的脚本标记插入文档后,您可以像这样使用它:

var imgLoad = imagesLoaded('body');
imgLoad.on( 'always', function() {
  console.log( imgLoad.images.length + ' images loaded' );
  // detect which image is broken
  for ( var i = 0, len = imgLoad.images.length; i < len; i++ ) {
    var image = imgLoad.images[i];
    var result = image.isLoaded ? 'loaded' : 'broken';
    console.log( 'image is ' + result + ' for ' + image.img.src );
    if (result == 'broken')
        image.img.src = 'Content/NoImageAvailable.png'; /* DOUBLE CHECK THE SRC */
  }
});

同样,你可能正在做的其他事情会与这个插件冲突,但绝对值得一试!它在我的例子中完美地运作:

http://jsfiddle.net/cookies/xdfjU/15/

摘要

由于图像错误事件不会起泡,因此无法使用全局错误跟踪功能解决方案,只留下两种处理此问题的一般方法:

  1. 为每个图像单独注册错误处理程序的本地方式,最好在指定src之前,但至少在它成为实时HTML片段或JavaScript图像对象之前。此方法的优点是,每个图像都会立即进行错误处理,一旦检测到404 Not Found,就会用占位符图像替换损坏的图像图标。
  2. 在整个页面中定位损坏图像的全局方式。这种方法的缺点是不能立即修复损坏的图像(在最终破坏的图像被修复之前可能花费大量时间来加载其他大图像),并且不能用于在初始加载事件之后可能添加到页面的图像。发生(例如,稍后从Ajax数据加载的图像),但它具有处理通过各种机制(如hmtlBuilder字符串)加载到页面中的图像的优势,这需要完全重新编程以允许图像单独分配错误处理程序。
  3. 解决这个问题(不存在)的理想方法是浏览器“泡沫”#34;将图像error事件转换为一般文档错误事件,可由单个事件处理程序监视,检查错误事件的来源是否为img元素,如果是,则检查错误的类型和替换未找到所需占位符的图像。

    如果您向我发送指向整个页面的链接,我将很高兴帮助您使这两种正确的解决方法中的一种正常工作。使任何JavaScript与您的代码一起工作的细节要求您看到所有代码,因为可能存在其他潜伏变量。

答案 2 :(得分:3)

关于更新5 ,不,没有理由。

您应该在设置属性src之前设置错误处理程序:

var $jObject = $('<img>');
$jObject.error(function () { //$jObject is already a jquery object, don't wrap it again
    $(this).attr("src", "Content/NoImageAvailable.jpg");
}).attr('src',dataPoint.imghref);

这通常是您应该如何做到的。测试一下。

答案 3 :(得分:3)

使用图片加载的插件

https://github.com/desandro/imagesloaded

利用jQuery延迟对象非常棒。这甚至可以确定是否为您加载图像,因此您不必使用jQuery.error(TBH,这不是真正合适的用途)。

答案 4 :(得分:2)

您编辑似乎是个问题。有后备应该解决您的问题

答案 5 :(得分:2)

这里有多个问题...

事件创建/冒泡

您不需要在每个img上绑定.error。而是在进入循环之前尝试一次:

$('body').on('error', 'img', function (e) {
    $(e.currentTarget).attr("src", "Content/NoImageAvailable.png");
});

由于事件冒泡,img的每个父元素也会触发error事件。所以不需要在循环中使用.error进行绑定。

下一步...

在JS中使用模板/避免HTML

你不需要使用像把手或下划线的模板语言;但是你应该尝试至少避免JS中的任何html。它容易出错。您的img标记(例如)无效。

请尝试以下图片:

var $img = $('<img>', {
    'src': dataPoint.imgsrc
});

您可以通过创建一个部分来开始循环:

var $output = $('<section>', {
    'class': 'wrapper'
});

然后当你循环时,你可以追加它:

$output.append($img);

这减少了弄乱的表面积。如果您想进一步缩小表面积,可以使用像把手一样的模板语言。

...最后

图像mime类型?网络流量?

您的网络流量对图像的调用返回了什么?它说200成功吗?它说400吗?打开chrome的开发者工具 - &gt;单击“网络”选项卡。观察流量并尝试查看有关图像的内容。

什么是服务器代码?是200吗?如果它是200什么是哑剧类型?你有没有正确配置S3?是否以某种方式从JSON修改了图像URL?

答案 6 :(得分:2)

我遇到了同样的问题。 .error或其他委派方法(附加到窗口/文档/ DOM节点)对于我在ajax响应之后动态创建的<img>不起作用。 我的解决方案是使用调用javascript函数的onerror标记(w3c标准)中的<img>属性删除图像并将noImg类添加到父节点。

<img>标记内:

onerror='replaceEmptyImage($(this))'

replaceEmptyImage函数:

replaceEmptyImage = function($img) {
  $img.parent().addClass('noImg');
  $img.remove();
};

在css中:

.noImg {
  background:url(path/to/placeholder/image);    
}

请参阅http://jsfiddle.net/tJpaR/5/

答案 7 :(得分:1)

.on('error' handler);以来

jQuery 1.7可用 图像加载错误不要冒泡,代表不能正常工作绑定一个简单的函数并且很干净

        function noImage(event){
            $(event.target).attr('src', 'media/noImg.jpg');
        }
        $(function (){
            $('img').on('error', noImage);
            $("#neues_bild_button").on('click', function(ev){
                var newImg = $("<img src='andersBild.jpg'/>");
                newImg.on('error', noImage);
                $('#i2').after(newImg);
            });
        });