Почему моя функция ошибки img не работает?

Некоторые из элементов img, которые я динамически создаю, могут выйти из строя. Для этих случаев у меня есть код, который я получил отсюда: Есть ли способ программно определить, что ссылка на изображение неверна? а именно:

    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) {
    . . .

... но это не работает. Варум нихт?

ОБНОВИТЬ

С этим кодом внутри части .each вызова $.getJSON():

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

МанМохан Вьяс: Вы имеете в виду так:

}); //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').append(htmlBuilder);

...к этому:

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

... не сработало (нужное заполнилось, но форматирование испортилось (вместо сплошного черного фона каждый раздел имел черный фон, но общий фон был серебристым).

ОБНОВЛЕНИЕ 5

Я просто подумал о том, что может быть причиной моей проблемы: изображения, которые я пытаюсь показать, все в формате jpg, но изображение «Изображение недоступно» — это png. Это имеет значение? Возможно, это то, что вызывает путаницу в механизме рендеринга? Если да, то я просто сохраню запасной img как jpg...

ОБНОВЛЕНИЕ 6

Нет, последние две попытки тоже не сработали. Я попробовал идею Джозефа Майерса, затем Престола, когда я изменил это:

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, но нахожусь на переднем крае в отношении jQueryUI версии 1.10.3.

ОБНОВЛЕНИЕ 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() {

. . . } // получитьNatlBook()

    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

Вот как это выглядит (изображение "блок" или "объект" есть, просто оно черное/пустое):

введите здесь описание изображения

Кстати, «Путешествия Джейми Макфитерса» — потрясающая книга в любом случае, но, возможно, особенно для чтения вашим детям (любой возраст, но, возможно, до подросткового возраста является оптимальным).


person Community    schedule 18.07.2013    source источник
comment
Я удалил свой ответ и скажу всем, кто предложит делегирование событий (например, с .on): error events не всплывает в большинстве браузеров, хотя согласно спецификации. Об этом также говорится в .on документах: Во всех браузерах... error события (например, , на элементе <img>) не пузыриться. Такие события не поддерживаются для использования с делегированием...   -  person apsillers    schedule 22.07.2013
comment
Черт возьми! ‹-- Кип Динамит. Я возлагал большие надежды на эту методологию.   -  person B. Clay Shannon    schedule 22.07.2013
comment
@ClayShannon Попробуйте это решение, работая с JS Fiddle здесь: jsfiddle.net/cookies/xdfjU/15 Просто нужно вставить ‹script src=desandro.github.io /imagesloaded/› в свой документ, а также код скрипта, который находится по ссылке JS Fiddle.   -  person Joseph Myers    schedule 25.07.2013
comment
Зачем мне нужно добавлять этот src val? Это просто должно [in,pro] вызвать условие ошибки? Если это так, не беспокойтесь — я могу сделать это с несколькими моими изображениями без какой-либо посторонней помощи.   -  person B. Clay Shannon    schedule 25.07.2013
comment
Этот скрипт содержит все необходимое для выполнения другого варианта, который я описал в своем ответе ниже, т. е. для поиска всех поврежденных изображений сразу после загрузки страницы. Это сложно сделать (и простой способ сделать это, на который я изначально ссылался в своем ответе, у вас не сработал). Вы можете видеть в моем JS Fiddle, что после того, как этот скрипт был включен, можно легко найти все поврежденные изображения и изменить их src на изображение-заполнитель по вашему выбору. Я обновляю свой ответ, чтобы более четко объяснить, что делать, поскольку комментарий ставит многоточие в мои инструкции.   -  person Joseph Myers    schedule 25.07.2013
comment
@ClayShannon Я опубликовал несколько проверенных решений, каждое из которых работает на 100% и имеет общую ценность для сообщества. Это максимум, что я могу сделать, пока вы не опубликуете ссылку или не опубликуете весь свой код или автономный пример, содержащий весь ваш код, который может иметь какое-либо отношение к вашему вопросу. Я думаю, что сейчас проблема заключается в том, чтобы помочь вам установить решение на свою страницу, а не найти решение. Но установить решение — это то же самое, что установить новый аккумулятор в автомобиль. Автомобиль должен быть там для того, чтобы установка произошла. :) Будем рады помочь сделать эту работу для вас.   -  person Joseph Myers    schedule 25.07.2013
comment
Благодарю всех за помощь (и здесь, и на форуме jQuery), но пока ничего не получается. Думаю, я разместил соответствующий код выше. Я могу делать аналогичные вещи, которые работают, например, добавлять обработчик кликов для imgs, но по какой-то странной причине это не работает.   -  person B. Clay Shannon    schedule 25.07.2013
comment
Добро пожаловать, но поскольку ни один из кода, который вы разместили выше, ничего не делает сам по себе, это не весь соответствующий код. Если наши ответы не работают для вас, это означает, что нам нужно больше от вас. Вы обращаетесь со всеми людьми, отвечающими на ваш вопрос, как с идиотами, говоря, что наши ответы не работают, когда вы не дали нам шанс заставить их работать на вас. Как вы ожидаете, что кто-то еще захочет вам помочь?   -  person Joseph Myers    schedule 25.07.2013
comment
Кстати, у @roasted ниже тоже есть отличный ответ, за исключением того, что вам нужно будет переписать функцию getNatlBookCritics(), чтобы использовать объекты DOM вместо строк, прежде чем этот метод заработает. Если вы не хотите публиковать свой код, я предлагаю вам хотя бы попробовать переписать эту функцию, чтобы использовать метод жареного, и тогда, возможно, жареный поможет вам закончить.   -  person Joseph Myers    schedule 25.07.2013
comment
@JosephMyers: Если вы дадите мне свой адрес электронной почты (вы можете написать мне по адресу bclayshannon att dot net), я вышлю вам весь код. Мне очень любопытно, почему ни одно из решений не сработало.   -  person B. Clay Shannon    schedule 25.07.2013
comment
@ClayShannon Да, мне тоже любопытно. Когда вы отправляете его по электронной почте, обязательно поместите файл (файлы) в папку, а затем заархивируйте его, чтобы ни один из сценариев не был удален фильтрами спама электронной почты (если вы напрямую прикрепляете HTML-файл, обычно сценарии удаляются). Моя электронная почта переполнения стека: e_mayilme на hotmail.com   -  person Joseph Myers    schedule 25.07.2013
comment
Мне действительно кажется, что использование делегата - это логичный путь (но кто-то рекомендовал это ранее, и это также не сработало).   -  person B. Clay Shannon    schedule 25.07.2013
comment
@JosephMyers: Спасибо, я постараюсь выложить это сегодня вечером.   -  person B. Clay Shannon    schedule 25.07.2013


Ответы (8)


использовать загруженный плагин изображений

https://github.com/desandro/imagesloaded

Использует удивительные возможности отложенных объектов jQuery. Это даже поможет выяснить, загружено ли изображение для вас, поэтому вам не нужно использовать jQuery.error (TBH, это не совсем подходящее использование для этого).

person Community    schedule 29.07.2013
comment
TBH == Быть целостным? Правда быть без проблем? - person B. Clay Shannon; 30.07.2013
comment
На самом деле оба... Откуда ты знаешь!? :) - person 1nfiniti; 30.07.2013
comment
Я действительно не понимаю, как это могло бы мне помочь; у него есть событие сбоя, но я уже знаю, что иногда оно терпит неудачу. Кажется, это просто общий провал всей операции; Мне нужен один для каждого случая сбоя, чтобы заменить сломанную картинку на общую. Причина, по которой мне кажется, что это просто общее событие сбоя, заключается в том, что пример показывает: .fail( function() { console.log('все изображения загружены, по крайней мере одно не работает'); }) - person B. Clay Shannon; 30.07.2013
comment
Это не общий провал. Общий объект сбоя имеет список всех изображений, которые вы передали функции, хранящейся в массиве. Есть несколько способов использовать это. Самый простой способ - проверить каждое изображение на состояние isLoaded... Более точный способ - использовать настройку отложенного объекта jQuery... Вы почти добрались до цели, просто нужно немного прокрутить мою ссылку;) - person 1nfiniti; 30.07.2013
comment
Вместо этого попробуйте демоверсию: desandro.github.io/imagesloaded ‹- постоянно загружайте кучу изображений - в конце концов некоторые из них потерпят неудачу, и вы увидите замену сломанного образа в действии. - person 1nfiniti; 30.07.2013
comment
Я награждаю вас наградой, хотя еще не пробовал; Я задал новый вопрос: почему мой альтернативный текст не отображается (stackoverflow.com/questions/17956938/) - person B. Clay Shannon; 31.07.2013
comment
Поверьте мне, это гораздо более простое решение вашей проблемы. Как только вы начнете использовать его, вы не вернетесь назад. Загрузка изображений — это очень сложный и хорошо написанный плагин ... он был запущен Полом Айришем и дополнен парой очень умных разработчиков при большой поддержке сообщества. - person 1nfiniti; 31.07.2013

Хотя ваше объяснение не очень понятно, наиболее вероятная причина в том, что ваш тег <img> отсутствует во время вызова функции $('img').error();

пытаться

1) создать динамическое изображение с некоторым идентификатором.
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/

person ManMohan Vyas    schedule 18.07.2013
comment
Да, я согласен, это, видимо, не связано, но почему? И как это исправить? Я не хочу просто вызывать функцию ошибки, потому что я не знаю, когда она должна быть вызвана — я не хочу вызывать ее произвольно или как само собой разумеющееся. - person B. Clay Shannon; 18.07.2013
comment
@ClayShannon, пожалуйста, проверьте мой отредактированный пост ... включен рабочий пример. :) - person ManMohan Vyas; 22.07.2013
comment
Таким образом, в вызове $.getJSON(), где внутри раздела .each я создаю динамический HTML, включая ссылки на изображения, этот код должен находиться внутри части .each внизу, до следующей итерации .each, исправить ? - person B. Clay Shannon; 22.07.2013
comment
@ClayShannon, не могли бы вы создать скрипку на www.jsfiddle.net. Я не могу найти код, где вы на самом деле помещаете его в DOM. $(#myId).html(jObject); ЭТА ЛИНИЯ ВАЖНА. ПОСКОЛЬКУ К ЭТОМУ ЭЛЕМЕНТУ ИЗОБРАЖЕНИЯ ПРИСОЕДИНЕНО СОБЫТИЕ ПРИВЯЗКИ - person ManMohan Vyas; 22.07.2013
comment
Основной код (и ссылку на скрипку) можно увидеть здесь: stackoverflow.com/questions/17689644/. Я обновляю снова с более подробной информацией. - person B. Clay Shannon; 22.07.2013
comment
во-вторых... вернуть объект jQuery, например $(htmlBuilder).find(img).error(function(){ваша функция ошибки}); надеюсь, что это полностью решит вашу проблему... у скрипки нет никакого javascript, кроме кнопки - person ManMohan Vyas; 22.07.2013
comment
Снова обновлено (#3) с проверочным вопросом для вас. - person B. Clay Shannon; 22.07.2013
comment
Но как я понимаю сейчас, не будет ли слишком поздно? К этому моменту весь html уже добавлен... или он оглядывается назад на ошибки, которые произошли при попытке отобразить поддельные URL-адреса img? - person B. Clay Shannon; 22.07.2013
comment
давайте продолжим обсуждение в чате - person ManMohan Vyas; 23.07.2013
comment
Да, там это работает; не на моей машине, хотя - по какой-то причине. - person B. Clay Shannon; 23.07.2013
comment
проверьте версию плагина jquery, который вы используете - person ManMohan Vyas; 23.07.2013
comment
Если вы имеете в виду пользовательский интерфейс jQuery, я использую 1.10.3 — последнюю версию. - person B. Clay Shannon; 23.07.2013

Что касается вашего UPDATE 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);

Как правило, вы должны это делать. Тестируйте и смотрите.

person A. Wolff    schedule 24.07.2013

Обновление на основе частичного кода, отправленного мне по электронной почте

Это всего лишь предположение, потому что все ваши основные сценарии и данные 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% случаев, полностью протестированы, как и должны быть правильные ответы на переполнение стека. К сожалению, эти решения не были должным образом включены в ваш код, потому что мне не хватает вашего полного кода или отдельного примера.

Коротко о том, что вы дали, и 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 */
});

Общие наблюдения

«Во всех браузерах события загрузки, прокрутки и ошибки (например, для элемента ‹img>) не всплывают. В Internet Explorer 8 и более ранних версиях события вставки и сброса не всплывают. Такие события не поддерживаются для использования. с делегированием, но их можно использовать, когда обработчик события напрямую привязан к элементу, генерирующему событие».

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

Интерпретация. Вы не можете надежно отловить ошибки загрузки изображения с помощью селектора jQuery в документе, где содержимое HTML создается асинхронно с помощью команды jQuery.

Следовательно, при регистрации обработчика ошибок для изображения (например, при замене его изображением «нет доступного изображения») важно зарегистрировать обработчик ошибок для изображения до того, как элемент изображения будет вставлен в DOM или станет активным. фрагмент документа. Если ваше изображение src существует в чистой строке JavaScript, вам необходимо убедиться, что указан обработчик onerror, прежде чем эта строка будет преобразована в фрагмент живого документа. Если ваше изображение src существует в объекте изображения JavaScript, то уже слишком поздно указывать обработчик ошибок — в этом случае вы должны указать обработчик перед src.

В противном случае возникает состояние гонки после вставки элемента изображения в DOM и до регистрации обработчика события. Изображение может вернуть ошибку 404 Not Found очень быстро, так как данные изображения не нужно загружать. Если обработчик события не был полностью подключен до того, как была обнаружена ошибка 404, обработчик события не будет вызываться.

Наличие изображения ошибки в формате PNG, а не в формате JPEG не имеет значения.

Ваш код создан таким образом, что он формирует строку HTML, затем преобразует ее в активный объект HTML, используя ее в качестве аргумента конструктора jQuery, и только затем устанавливает ошибку обработчик для img элементов, которые он содержит. Это вызывает ту же проблему, что и исходный HTML-код, не содержащий атрибута onerror, а затем попытка установить обработчик ошибок с помощью скрипта. Поведение, которое вы упомянули

Это работает для меня, просто изменив последние несколько строк в вашем 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, что потребует полного перепрограммирования, чтобы изображения могли иметь ошибки по отдельности. назначены обработчики.

Идеальным способом решения этой проблемы (которого не существует) было бы для браузеров «всплыть» событие изображения error в событие ошибки общего документа, которое можно было бы отслеживать с помощью одного обработчика событий, проверяя, не является ли источник событием ошибки был элемент img, и если да, то проверка вида ошибки и замена не найденного изображения на нужный заполнитель.

Еще раз, я был бы рад помочь вам заставить работать один из этих двух правильных методов решения, если вы пришлете мне ссылку на всю вашу страницу. Специфика работы любого JavaScript с вашим кодом требует, чтобы вы видели весь ваш код, поскольку могут быть другие скрытые переменные.

person Joseph Myers    schedule 24.07.2013
comment
Нет, это тоже не работает. Единственное отличие в моем коде — это имя замещающего изображения: htmlBuilder = htmlBuilder.replace(/‹img/g, '‹img onerror=imageError(this)'); ...и идентификатор элемента div, который получает html: $(#BooksContent).html(jObject); - person B. Clay Shannon; 24.07.2013
comment
@ClayShannon Можете ли вы предоставить ссылку на файл на вашем сайте, где я могу просто обновить его несколько раз, пока не увижу некоторые изображения, которые не загружаются, но не отображают изображение ошибки должным образом? Тогда я мог бы отлаживать оттуда. Я не знаю, могу ли я видеть то, что вы видите на JS Fiddle, но я, вероятно, мог бы видеть это, если бы у вас была обычная страница, которую я мог бы просто обновить, пока не увижу проблему. - person Joseph Myers; 24.07.2013
comment
@ClayShannon Я вижу твою скрипку здесь, jsfiddle.net/clayshannon/cMYEH/1, но я не не вижу части JavaScript. Это правильная ссылка, на которую я должен смотреть? Я проверю завтра, если у вас нет возможности вернуться ко мне со ссылкой, прежде чем я немного посплю ночью. - person Joseph Myers; 24.07.2013

Вы редактируете, кажется, проблема. Резервный вариант должен решить вашу проблему

person Jnatalzia    schedule 23.07.2013
comment
Что ж, я использовал функцию err, которую предоставили другие, но она не сработала. Вы говорите, что несоответствие типа файла изображения является проблемой? (Я не смогу проверить это, пока не вернусь домой с работы, но пытливые умы хотят знать!). - person B. Clay Shannon; 24.07.2013
comment
Исходя из этого: jsfiddle.net/tJpaR/1, это, вероятно, не проблема, так как jpg ищется, а затем png (успешно) резервный img. - person B. Clay Shannon; 24.07.2013

Несколько проблем здесь потенциально...

Создание события/бублинг

Вам не нужно привязывать .error к каждому изображению. Вместо этого попробуйте это один раз, прежде чем войти в свой цикл:

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

Из-за всплытия событий каждый родительский элемент img также запускает событие error. Так что нет необходимости связываться с использованием .error в цикле.

Следующий...

Использование шаблонов/отказ от HTML в JS

Вам не нужно использовать что-то вроде руля или языка шаблонов подчеркивания; однако вы должны попытаться, по крайней мере, избегать любого html в своем JS. Он подвержен ошибкам. Ваша разметка img (например) недействительна.

Попробуйте следующее для ваших изображений:

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

Вы можете начать свой цикл, создав раздел:

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

Затем, когда вы выполняете цикл, вы можете добавить к нему:

$output.append($img);

Это уменьшает площадь поверхности для беспорядка. Если вы хотите еще больше уменьшить площадь поверхности, вы можете использовать язык шаблонов, такой как руль.

Наконец...

Типы пантомимы изображения? Сетевой трафик?

Что, по словам вашего сетевого трафика, возвращается вызовами изображений? Там написано 200 успехов? Там написано 400? Откройте инструменты разработчика Chrome -> щелкните вкладку «Сеть». Наблюдайте за трафиком и попытайтесь понять, что он говорит о ваших изображениях.

Какой код сервера? Это 200? Если это 200, какой тип пантомимы? Вы правильно настроили S3? URL-адрес изображения каким-то образом изменяется из JSON?

person Parris    schedule 25.07.2013
comment
Я изучу все это, когда у меня будет возможность (вероятно, не раньше вечера пятницы), но скажу, что более 95% изображений загружаются нормально, все выглядит хорошо и работает хорошо. Изображения, которых просто не существует (это очень малоизвестные книги, для которых было изображение, это была бы та ценность, которую я предоставляю, но ее нет) — но я заранее не знаю, какие именно. - person B. Clay Shannon; 25.07.2013
comment
Так что код, с которого вы начинаете, может быть включен в обработчик готовности, верно? Что такое S3? - person B. Clay Shannon; 25.07.2013
comment
CDT показывает, что почти все они имеют статус 304 Not Modified; Я видел один 200 OK, и несколько типов изображений предположительно являются изображениями/gif, хотя все они имеют расширение .jpg. - person B. Clay Shannon; 25.07.2013
comment
О, и несколько (ожидаемых) 404-х тоже. - person B. Clay Shannon; 25.07.2013
comment
@ClayShannon Да, код, с которого я начал, может войти в обработчик готовности. Коды 304 и 200 подходят. 304 означает, что изображение кэшировано и его не нужно повторно загружать, 200 загружается и все в порядке. Кроме того, что касается несовпадения типов gif и jpg, это может привести к ошибке. Не совсем уверен, что там происходит, но это может привести к неправильному отображению изображения. Вероятно, что-то в процессе загрузки сломалось. - person Parris; 27.07.2013

У меня такая же проблема. .error или другие методы делегирования (прикрепленные к узлу окна/документа/DOM) не работали для меня на <img>, созданном динамически после ответа ajax. Мое решение использует атрибут onerror внутри тега <img> (стандарт w3c), который вызывает функцию javascript, удаляет изображение и добавляет класс 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/.

person Community    schedule 27.07.2013
comment
Какая у вас ошибка? ваш $img.parent() является <a>. возможно, вам нужно подняться на другой уровень или указать тегу <a> ширину, высоту и свойства стиля display:block - person barvaz; 27.07.2013
comment
На самом деле, теперь отображается объект изображения, просто он пустой. Я опубликую снимок крика, чтобы показать вам, как это выглядит (это будет Обновление 9). - person B. Clay Shannon; 27.07.2013
comment
<a> — это встроенный элемент с шириной и высотой внутреннего узла. когда вы удаляете внутренний html, вы получаете элемент 0X0. вы можете удалить <a>, как здесь: jsfiddle.net/tJpaR/7, или придать стиль <a> как здесь: jsfiddle.net/tJpaR/6 - person barvaz; 27.07.2013
comment
Единственная ошибка (хотя пустых образов больше десятка) в консоли CDT — Failed to load resource: сервер ответил со статусом 404 (Not Found) - person B. Clay Shannon; 27.07.2013
comment
Что вы подразумеваете под отображением объекта изображения сейчас? Применяется ли класс noImg? Если вы хотите сохранить ссылку вокруг ненайденного изображения, посмотрите jsfiddle.net/tJpaR/6 - person barvaz; 27.07.2013
comment
То, что есть в кадре крика: вы можете сказать, что там что-то есть — раньше это было просто bla[c,n]k. Возможно, потому что я добавил к нему тень. - person B. Clay Shannon; 27.07.2013
comment
Хорошо, похоже, что JS работает просто отлично. Это означает, что проблема теперь в таблице стилей. 1) Является ли ~/Content/NoImageAvailable.png видимым для веб-приложения? установка background:url(~/Content/NoImageAvailable.png); делает его относительным к веб-странице. попробуйте абсолютный URL. 2) Есть ли какая-либо инструкция css, переопределяющая новую фоновую? Что говорит инспектор DOM? - person barvaz; 27.07.2013
comment
На самом деле, тень вокруг изображения была там последние неделю или две. До этого единственный способ ожидать, что изображение принадлежит этому месту, — это точно так же, как можно ожидать, что определенный элемент находится в определенном месте в периодической таблице элементов Менделева (без каламбура) — это была просто пустая область. Теперь золотая тень показывает, что здесь что-то должно быть. IOW, я не думаю, что ваш js сделал что-то большее, чем любая другая попытка (все они работают в теории, но не на самом деле). Вероятно, это что-то странное с моей стороны, что-то очевидное, что я не могу сделать или предотвратить. - person B. Clay Shannon; 27.07.2013
comment
Я согласен, что в вашем конце есть что-то очевидное, что это не работает. Пустая область имеет границу или определение фона, которые могут нарушить URL-адрес фона. или проблема с z-индексом или путем. Если у вас есть способ опубликовать незавершенный сайт, я могу помочь вам найти что-то - person barvaz; 28.07.2013
comment
Спасибо, но через пару месяцев он не будет в открытом доступе. - person B. Clay Shannon; 28.07.2013

.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);
            });
        });
person Community    schedule 03.11.2015