我动态构建的一些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
在地狱中,我正在添加“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有高度和宽度属性是问题......
}); //each
$('#BooksContent').append(htmlBuilder).
find("img").error(function(){
$(this).attr("src", "Content/NoImageAvailable.png");
});
}); //getJSON()
此:
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);
...效果不好(填充了正确的东西,但格式化了所有混乱(而不是纯黑色背景,每个部分都有黑色背景,但整体背景是银色)。
我只是想到可能导致我的问题的一些事情:我试图展示的图像都是jpgs,但是“Image Not Available”图像是png。这有什么区别吗?这可能是导致渲染引擎混淆的原因吗?如果是这样,我只会将后备img保存为jpg ......
不,这最后两次尝试也没有用。我尝试了约瑟夫迈尔斯的想法,然后是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,我处于“前沿”。
好的,这是所有相关代码(一些冗余和模拟代码将被重构,已被省略以符合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>
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=\"' +
这是它的样子(图像“块”或“对象”在那里,它只是它的黑色/空白):
BTW,Jamie McPheeters的游记无论如何都是一本很棒的书,但也许尤其是给你的孩子读书(任何年龄,但也许是青少年时期最佳)。
答案 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;
解释:在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/
由于图像错误事件不会起泡,因此无法使用全局错误跟踪功能解决方案,只留下两种处理此问题的一般方法:
src
之前,但至少在它成为实时HTML片段或JavaScript图像对象之前。此方法的优点是,每个图像都会立即进行错误处理,一旦检测到404 Not Found,就会用占位符图像替换损坏的图像图标。hmtlBuilder
字符串)加载到页面中的图像的优势,这需要完全重新编程以允许图像单独分配错误处理程序。解决这个问题(不存在)的理想方法是浏览器“泡沫”#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。它容易出错。您的img标记(例如)无效。
请尝试以下图片:
var $img = $('<img>', {
'src': dataPoint.imgsrc
});
您可以通过创建一个部分来开始循环:
var $output = $('<section>', {
'class': 'wrapper'
});
然后当你循环时,你可以追加它:
$output.append($img);
这减少了弄乱的表面积。如果您想进一步缩小表面积,可以使用像把手一样的模板语言。
...最后
您的网络流量对图像的调用返回了什么?它说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);
}
答案 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);
});
});