I am trying to modularize the following javascript but I have a problem to pass the event target. The function open was inside the the $('.myImg').on('click', function (event) { ...}.
I can't get it working.
Any Input would be appreciated.
var Modal = function () {
var modal = document.getElementById('myModal'),
modalcontent = document.getElementById('modal-img-content'),
close_btn = document.getElementsByClassName("close")[0],
img = document.getElementsByClassName('.myImg'),
modalImg = document.getElementById("img01"),
visible = false;
function getScrollBarWidth () {
var $outer = $('<div>').css({visibility: 'hidden', width: 100, overflow: 'scroll'}).appendTo('body'),
widthWithScroll = $('<div>').css({width: '100%'}).appendTo($outer).outerWidth();
$outer.remove();
return 100 - widthWithScroll;
}
function open(event){
visible = true;
modal.style.display = "block";
document.getElementsByTagName("BODY")[0].style.overflow = "hidden";
modal.style.overflow = "auto";
var newSrc = this.src;
var caption = this.alt;
modalImg.setAttribute('src', newSrc);
}
return {
getScrollBarWidth : getScrollBarWidth,
open : open
}
}();
$('.myImg').on('click', function(event) {
event.stopPropagation();
Modal.open(event);
});
You pass event but not use it in your handler.
There is correct code:
function open(event){
visible = true;
modal.style.display = "block";
document.getElementsByTagName("BODY")[0].style.overflow = "hidden";
modal.style.overflow = "auto";
var newSrc = event.target.getAttribute('src');
var caption = event.target.getAttribute('alt');
modalImg.setAttribute('src', newSrc);
}
Since I already commented with the solution, I post a cleaned version.
You need to use the event you passed.
You want
var newSrc = event.target.src;
var caption = event.target.alt;
which is the only place you need DOM in your code
var Modal = function() {
var $modal = $('#myModal'),
$modalcontent = $('#modal-img-content'),
$close_btn = $(".close"),
$img = $('.myImg'),
$modalImg = $("#img01"),
visible = false;
function getScrollBarWidth() {
var $outer = $('<div>').css({
visibility: 'hidden',
width: 100,
overflow: 'scroll'
}).appendTo('body'),
widthWithScroll = $('<div>').css({
width: '100%'
}).appendTo($outer).outerWidth();
$outer.remove(); // WHY?
return 100 - widthWithScroll;
}
function open(event) {
visible = true;
$modal.show();
$("body").css({'overflow':'hidden'});
$modal..css({'overflow':'auto'});
var newSrc = event.target.src;
var caption = event.target.alt;
$modalImg.attr('src', newSrc);
}
return {
getScrollBarWidth: getScrollBarWidth,
open: open
}
}();
$('.myImg').on('click', function(event) {
event.stopPropagation();
Modal.open(event);
});
Related
I'm trying to make a tab controller on a div that has divs beneath it that are for content (each sibling is a tab).
Given this html:
<div id="myTabCtl">
<div id="tab1">
<img src="https://images.unsplash.com/photo-1546238232-20216dec9f72?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1000&q=80" style="width:240px;">
</div>
<div id="tab2">
Cute puppies.
<img src="https://www.telegraph.co.uk/content/dam/news/2016/05/06/rexfeatures_4950182a_trans_NvBQzQNjv4Bqeo_i_u9APj8RuoebjoAHt0k9u7HhRJvuo-ZLenGRumA.jpg?imwidth=240" style="width:240px;">
</div>
<div id="tab3">
No puppies here.
</div>
</div>
And this javascript:
Element.prototype.tabs = function () {
var tabs = [];
this.classList.add('xTabCtl');
var tab_bar = document.createElement('ul');
tab_bar.classList.add('xTabRow');
this.insertBefore(tab_bar, this.firstChild);
this.addTab = function (div,label,title,click) {
if (typeof div == 'string')
div = document.getElementById(div);
if (!div) return false;
div.style.display = 'none';
var tab_ctl = document.createElement('li');
tab_ctl.innerHTML = label;
if (title) tab_ctl.title = title;
var cnt = tabs.length;
if (click) {
tab_ctl.onclick = function () {
this.setTab(cnt);
click();
};
} else {
tab_ctl.onclick = function () {
this.setTab(cnt);
};
}
tab_ctl.style.cursor = 'pointer';
tab_ctl.style.userSelect = 'none';
tab_ctl.classList.add('xTabItem');
tab_bar.appendChild(tab_ctl);
var tab = {};
tab.elem = tab_ctl;
tab.div = div;
tab.loaded = false;
tabs[tabs.length] = tab;
return true;
}
this.setTab = function (tab_no) {
for (var i=0; i<tabs.length; i++) {
tabs[i].elem.classList.remove('xTabItemSel');
tabs[i].div.style.display = 'none';
tabs[i].loaded = false;
}
tabs[tab_no].div.style.display = 'block';
tabs[tab_no].div.classList.add('xTabItemSel');
tabs[tab_no].loaded = true;
return;
}
};
document.getElementById('myTabCtl').tabs();
document.getElementById('myTabCtl').addTab('tab1','Cute Puppies 1','Title 1');
document.getElementById('myTabCtl').addTab('tab2','Cute Puppies 2','Title 2');
document.getElementById('myTabCtl').addTab('tab3','No Puppies','Title 3',function(){alert('hello.');});
Obviously, this uses some classes that are defined in a theme css file, but that's not at issue.
addTab works, but I cannot call setTab from the onclick of each li that is added. Why not?
Perhaps bigger, there has to be a cleaner way of doing this. I like that it adds the tabs as an li so the dopes I work with only have to add the wrapper and that content. There could be multiple tab controls on a screen. I'm not using the libraries that are available because most go way too far and I want to confine it to addTab and setTab.
This problem is with clouser, when you invoke this.setTab inside event handle, the reference of this is local so it will not get actual setTab method.
Element.prototype.tabs = function () {
var tabs = [], _this = this;
this.classList.add('xTabCtl');
var tab_bar = document.createElement('ul');
tab_bar.classList.add('xTabRow');
this.insertBefore(tab_bar, this.firstChild);
this.addTab = function (div,label,title,click) {
if (typeof div == 'string')
div = document.getElementById(div);
if (!div) return false;
div.style.display = 'none';
var tab_ctl = document.createElement('li');
tab_ctl.innerHTML = label;
if (title) tab_ctl.title = title;
var cnt = tabs.length;
if (click) {
tab_ctl.onclick = function () {
_this.setTab(cnt);
click();
};
} else {
tab_ctl.onclick = function () {
_this.setTab(cnt);
};
}
tab_ctl.style.cursor = 'pointer';
tab_ctl.style.userSelect = 'none';
tab_ctl.classList.add('xTabItem');
tab_bar.appendChild(tab_ctl);
var tab = {};
tab.elem = tab_ctl;
tab.div = div;
tab.loaded = false;
tabs[tabs.length] = tab;
return true;
}
this.setTab = function (tab_no) {
for (var i=0; i<tabs.length; i++) {
tabs[i].elem.classList.remove('xTabItemSel');
tabs[i].div.style.display = 'none';
tabs[i].loaded = false;
}
tabs[tab_no].div.style.display = 'block';
tabs[tab_no].div.classList.add('xTabItemSel');
tabs[tab_no].loaded = true;
return;
}
};
document.getElementById('myTabCtl').tabs();
document.getElementById('myTabCtl').addTab('tab1','Cute Puppies 1','Title 1');
document.getElementById('myTabCtl').addTab('tab2','Cute Puppies 2','Title 2');
document.getElementById('myTabCtl').addTab('tab3','No Puppies','Title 3',function(){alert('hello.');});
I am trying to make a function which will close my tooltip by 'click' on the parent element which returns me this tooltip by first click on it. Need to get the closing function exclusively for tooltip parent element. Right now everything is working, but i can also close my tooltip by clicking anywhere on body element.
`(function () {
function Tooltip(options) {
if (!options) options = {};
var self = this;
this.tooltips;
this.offset = 5;
this.beforeTooltip = options.beforeTooltip;
this.afterTooltip = options.afterTooltip;
this.tooltipWrapper = document.createElement('div');
this.status = false;
this.tooltip = function (elem) {
if (!elem.classList.contains('active')){
if (this.status) this.remElemActive();
if (this.beforeTooltip) this.beforeTooltip(elem);
elem.classList.add('active');
var coords = this.getCoords(elem);
this.tooltipWrapper.textContent = elem.dataset.tooltip;
this.tooltipWrapper.classList.add('active');
this.tooltipWrapper.style.top = coords.top - (this.tooltipWrapper.offsetHeight + this.offset) + 'px';
this.tooltipWrapper.style.left = (coords.left + coords.width / 2) - (this.tooltipWrapper.offsetWidth / 2) + 'px';
this.status = true;
if (this.status){
setTimeout(function () {
document.addEventListener('click', self.closeTipsBody, false);
}, 100)
}
if (this.afterTooltip) this.afterTooltip(elem)
}else {
elem.classList.remove('active');
}
};
this.closeTipsBody = function (e) {
if (self.tooltipWrapper === e.target || e.target.classList.contains('active')){
return false
}
self.closeTips();
};
this.closeTips = function () {
this.tooltipWrapper.classList.remove('active');
this.remElemActive();
this.status = false;
document.removeEventListener('click', self.closeTipsBody, false)
};
this.remElemActive = function () {
document.querySelector('.tooltip-js').classList.remove('active')
};
this.getCoords = function (elem) {
elem = elem.getBoundingClientRect();
return{
top: elem.top + window.pageYOffset,
left: elem.left + window.pageXOffset,
width: elem.width
}
};
this.init = function () {
document.addEventListener('DOMContentLoaded', function () {
this.tooltips = document.querySelectorAll('.tooltip-js');
this.tooltipWrapper.classList.add('tooltip-box');
document.querySelector('body').appendChild(this.tooltipWrapper);
for (var i = 0; i < this.tooltips.length; i++ ){
this.tooltips[i].addEventListener('click', function (e) {
e.preventDefault();
self.tooltip(this);
})
}
}.bind(this))
};
this.init();
}
window.Tooltip = Tooltip;
})();`
if you need any additional info, about what do i want to get to, text me.
I have a open function that once triggered, simply plays video in a dedicated panel.
This function can be triggered in two ways - one with a click and another one with a page load (window load) with url that contains a valid anchor tag.
They all work fine but some codes of the window load handler are repetitive and I'm not too sure how I can keep this DRY.
Please take a look and point me in some directions on how I can write this better.
I commented in open function which is for which.
$.videoWatch.prototype = {
init: function() {
this.$openLinks = this.$element.find(".open");
this.$closeLinks = this.$element.find(".close");
this.open();
this.close();
},
_getContent: function(element) {
var $parent = element.parent(),
id = element.attr('href').substring(1),
title = $parent.data('title'),
desc = $parent.data('desc');
return {
title: title,
desc: desc,
id: id
}
},
open: function() {
var self = this;
//open theatre with window load with #hash id
window.onload = function() {
var hash = location.hash;
var $a = $('a[href="' + hash + '"]'),
content = self._getContent($a),
$li = $a.parents("li"),
$theatreVideo = $(".playing"),
$theatreTitle = $(".theatre-title"),
$theatreText = $(".theatre-text");
$(".theatre").attr('id', content.id);
$theatreTitle.text(content.title);
$theatreText.text(content.desc);
if ($theatreText.text().length >= 90) {
$(".theatre-text").css({
'overflow': 'hidden',
'max-height': '90px',
});
$moreButton.insertAfter($theatreText);
}
$a.parent().addClass("active");
$(".theatre").insertAfter($li);
$(".theatre").slideDown('fast', scrollToTheatre);
oldIndex = $li.index();
}
//open theatre with click event
self.$openLinks.on("click", function(e) {
// e.preventDefault();
if (curID == $(this).parent().attr("id")) {
$("figure").removeClass("active");
$("button.more").remove();
$(".theatre").slideUp('fast');
$('.playing').attr("src", "");
removeHash();
oldIndex = -1;
curID = "";
return false
} else {
curID = $(this).parent().attr("id");
}
var $a = $(this),
content = self._getContent($a),
$li = $a.parents("li"),
$theatreVideo = $(".playing"),
$theatreTitle = $(".theatre-title"),
$theatreText = $(".theatre-text");
$(".theatre").attr('id', content.id);
$theatreTitle.text(content.title);
$theatreText.text(content.desc);
if ($theatreText.text().length >= 90) {
$(".theatre-text").css({
'overflow': 'hidden',
'max-height': '90px',
});
$moreButton.insertAfter($theatreText);
}
if (!($li.index() == oldIndex)) {
$("figure").removeClass("active");
$(".theatre").hide(function(){
$a.parent().addClass("active");
$(".theatre").insertAfter($li);
$(".theatre").slideDown('fast', scrollToTheatre);
oldIndex = $li.index();
});
} else {
$(".theatre").insertAfter($li);
scrollToTheatre();
$("figure").removeClass("active");
$a.parent().addClass("active");
}
});
},
...
Simplified and refactored open method:
open: function() {
var self = this;
var serviceObj = {
theatreVideo : $(".playing"),
theatre: $(".theatre"),
theatreTitle : $(".theatre-title"),
theatreText : $(".theatre-text"),
setTheatreContent: function(content){
this.theatre.attr('id', content.id);
this.theatreTitle.text(content.title);
this.theatreText.text(content.desc);
if (this.theatreText.text().length >= 90) {
this.theatreText.css({
'overflow': 'hidden',
'max-height': '90px',
});
$moreButton.insertAfter(this.theatreText);
}
},
activateTeatre: function(a, li){
a.parent().addClass("active");
this.theatre.insertAfter(li);
this.theatre.slideDown('fast', scrollToTheatre);
oldIndex = li.index();
}
};
//open theatre with window load with #hash id
window.onload = function() {
var hash = location.hash;
var $a = $('a[href="' + hash + '"]'),
content = self._getContent($a),
$li = $a.parents("li");
serviceObj.setTheatreContent(content);
serviceObj.activateTeatre($a, $li);
}
//open theatre with click event
self.$openLinks.on("click", function(e) {
// e.preventDefault();
if (curID == $(this).parent().attr("id")) {
$("figure").removeClass("active");
$("button.more").remove();
$(".theatre").slideUp('fast');
$('.playing').attr("src", "");
removeHash();
oldIndex = -1;
curID = "";
return false
} else {
curID = $(this).parent().attr("id");
}
var $a = $(this),
content = self._getContent($a),
$li = $a.parents("li");
serviceObj.setTheatreContent(content);
if (!($li.index() == oldIndex)) {
$("figure").removeClass("active");
$(".theatre").hide(function(){
serviceObj.activateTeatre($a, $li);
});
} else {
$(".theatre").insertAfter($li);
scrollToTheatre();
$("figure").removeClass("active");
$a.parent().addClass("active");
}
});
},
1st of all there are variables that don't depend on the input, you could pull them to the class (I'll show just one example, as you asked for directions):
init: function() {
this.$theatreVideo = $(".playing");
All the variables that do depend on the input, like $li could be moved to a function:
var $a = $(this),
$dependsOnA = self.dependsOnA($a);
self.actionDependsOnA($dependsOnA); // see below
function dependsOnA($a) {
return {
a: $a,
li: $a.parents("li"),
content: self._getContent($a)
}
}
Also the code that "repeats" can be moved to a function:
function actionDependsOnA($dependsOnA)
$(".theatre").attr('id', $dependsOnA.content.id);
$theatreTitle.text($dependsOnA.content.title);
$theatreText.text($dependsOnA.content.desc);
}
i want control speed in this function , please help me!
<script>
function toggle(target)
{
var artz = document.getElementsByClassName('showhidemenu');
var targ = document.getElementById(target);
var isVis = targ.style.display=='block';
// hide all
for(var i=0;i<artz.length;i++)
{
artz[i].style.display = 'none';
}
// toggle current
targ.style.display = isVis?'none':'block';
return false;
}
</script>
If you just want a delay, try this:
function toggle(target, milliseconds)
{
setTimeout(function() {
var artz = document.getElementsByClassName('showhidemenu');
var targ = document.getElementById(target);
var isVis = targ.style.display=='block';
// hide all
for(var i=0;i<artz.length;i++)
{
artz[i].style.display = 'none';
}
// toggle current
targ.style.display = isVis?'none':'block';
return false;
}, milliseconds);
}
You'll lose the return value, though.
Call your toggle function with an timeout as per your requirement
Use
window.setTimeout(toggle(),2000);
This will call your toggle function after a delay of 2000 ms.
cant show this function with animation ??
function toggle(target, milliseconds)
{
setTimeout(function() {
var artz = document.getElementsByClassName('showhidemenu');
var targ = document.getElementById(target);
var isVis = targ.style.display=='block';
// hide all
for(var i=0;i<artz.length;i++)
{
artz[i].style.display = 'none';
}
// toggle current
targ.style.display = isVis?'none':'block';
return false;
}, milliseconds);
}
If this question is totally unsuitable, please forgive me. I don't know anything about programming. I should learn Javascript, I know, but it is a bit difficult for a total layman.
I have two bookmarklets and one userscript that, together, do what I need; but I need to click, wait, and click. Could they all be combined into a single bookmarklet? This is for Firefox 5, on Windows XP.
The first bookmarklet takes all links on a page that point to images and displays all these images in a single page in a new tab:
javascript:(function(){function%20I(u){var%20t=u.split('.'),e=t[t.length-1].toLowerCase();return%20{gif:1,jpg:1,jpeg:1,png:1,mng:1}[e]}function%20hE(s){return%20s.replace(/&/g,'&').replace(/>/g,'>').replace(/</g,'<').replace(/"/g,'"');}var%20q,h,i,z=open().document;z.write('<p>Images%20linked%20to%20by%20'+hE(location.href)+':</p><hr>');for(i=0;q=document.links[i];++i){h=q.href;if(h&&I(h))z.write('<p>'+q.innerHTML+'%20('+hE(h)+')<br><img%20src="'+hE(h)+'">');}z.close();})()
Then the userscript kicks in, which changes the title of the page to include [Page loaded]:
// ==UserScript==
// #name Add "loaded" to title if page is loaded
// #namespace my
// #description Indicate if a page is loaded
// #include *
// ==/UserScript==
window.addEventListener(
'load',
function (e) {
document.title += " - [Page loaded]";
},
false);
Lastly, I click the second bookmarklet, which removes all text and all images smaller than a certain size from the page, and gives it a black background. It'd like this part to kick in only after all images have been loaded (hence the "loaded" title from the userscript).
I have to put this in in-line code, because the other methods seemed to fail (neither the code button nor blockquote did anything). It would be awesome if someone could help me out! I couldn't write a single line of Javascript myself and have no idea what to do.
function wrap(image, href) {
var img = document.createElement('img');
var div = document.createElement('div');
img.src = image.src;
var node = image.parentNode;
if (!href) {
div.appendChild(img);
} else {
var a = document.createElement('a');
a.href = href;
a.appendChild(img);
div.appendChild(a);
}
return div;
}
function findNext(document) {
var res = document.evaluate('//a[#rel='
next ']', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
if (res.singleNodeValue) {
return res.singleNodeValue.href;
} else {
return null;
}
}
if ('scrollMaxY' in window) {
function getScrollMaxY() {
return window.scrollMaxY;
}
} else {
function getScrollMaxY() {
return document.body.scrollHeight - window.innerHeight;
}
}
function streamify() {
var contentDiv = document.createElement('div');
var imageDiv = document.createElement('div');
var moreButton = document.createElement('input');
var style = document.createElement('style');
var iframe = document.createElement('iframe');
var errorSpan = document.createElement('span');
var retryButton = document.createElement('input');
var currentPageDiv = document.createElement('div');
var currentPageLink = document.createElement('a');
var nextUrl = findNext(document);
var occured = {};
var images = [];
var loadTimer = null;
var scrolledToBottom = false;
function extract(elem, href, images) {
switch (elem.localName) {
case 'a':
href = elem.href;
break;
case 'img':
if (!(elem.src in occured) && elem.offsetWidth > 250 && elem.offsetHeight > 300) {
images.push(wrap(elem));
occured[elem.src] = true;
}
}
var child = elem.firstElementChild;
while (child) {
extract(child, href, images);
child = child.nextElementSibling;
}
}
function loadNext() {
if (loadTimer !== null) {
window.clearTimeout(loadTimer);
}
if (nextUrl) {
loadTimer = window.setTimeout(function () {
errorSpan.style.display = '';
loadTimer = null;
}, 30000);
iframe.src = nextUrl;
}
}
style.type = 'text/css';
style.appendChild(document.createTextNode('body {background-color: black;color: white;}a {color: white;font-weight: bold;text-decoration: none;}a:hover {text-decoration: underline;}#greasemonkey-image-stream-content {text-align: center;}#greasemonkey-image-stream-content > div > div {margin-top: 2em;margin-bottom: 2em;}#greasemonkey-image-stream-content input {padding: 0.5em;font-weight: bold;}'));
contentDiv.id = 'greasemonkey-image-stream-content';
currentPageLink.appendChild(document.createTextNode('current page'));
currentPageLink.href = window.location.href;
currentPageDiv.appendChild(currentPageLink);
moreButton.type = 'button';
moreButton.value = 'More';
moreButton.disabled = true;
function handleMore() {
currentPageLink.href = iframe.src;
scrolledToBottom = false;
errorSpan.style.display = 'none';
moreButton.disabled = true;
for (var i = 0; i < images.length; ++i) {
imageDiv.appendChild(images[i]);
}
images = [];
loadNext();
}
moreButton.addEventListener('click', handleMore, false);
retryButton.type = 'button';
retryButton.value = 'Retry';
retryButton.addEventListener('click', function (event) {
loadNext();
errorSpan.style.display = 'none';
}, false);
errorSpan.style.fontWeight = 'bold';
errorSpan.style.color = 'red';
errorSpan.style.display = 'none';
errorSpan.appendChild(document.createTextNode(' Load Error '));
errorSpan.appendChild(retryButton);
iframe.style.width = '0px';
iframe.style.height = '0px';
iframe.style.visibility = 'hidden';
iframe.addEventListener('load', function (event) {
if (loadTimer !== null) {
window.clearTimeout(loadTimer);
}
errorSpan.style.display = 'none';
nextUrl = findNext(iframe.contentDocument);
extract(iframe.contentDocument.body, null, images);
if (images.length == 0 && nextUrl) {
loadNext();
moreButton.disabled = true;
} else {
moreButton.disabled = !nextUrl && images.length == 0;
if (scrolledToBottom && (nextUrl || images.length > 0)) {
handleMore();
}
}
}, false);
extract(document.body, null, images);
for (var i = 0; i < images.length; ++i) {
imageDiv.appendChild(images[i]);
}
images = [];
contentDiv.appendChild(style);
contentDiv.appendChild(currentPageDiv);
contentDiv.appendChild(imageDiv);
contentDiv.appendChild(moreButton);
contentDiv.appendChild(errorSpan);
contentDiv.appendChild(iframe);
var elem = document.documentElement.firstElementChild;
while (elem) {
switch (elem.localName) {
case 'head':
var child = elem.firstElementChild;
while (child) {
var next = child.nextElementSibling;
if (child.localName != 'title') {
elem.removeChild(child);
}
child = next;
}
break;
case 'body':
while (elem.firstChild) {
elem.removeChild(elem.firstChild);
}
}
elem = elem.nextElementSibling;
}
window.addEventListener('scroll', function (event) {
if (window.scrollY >= getScrollMaxY()) {
scrolledToBottom = true;
moreButton.click();
}
}, false);
document.body.appendChild(contentDiv);
loadNext();
}
streamify();
void(0)
(function(){
var a=Array.filter(document.getElementsByTagName('a'),function(e){
var h=e.href.split('.').pop().toLowerCase();
return {gif:1,jpg:1,jpeg:1,png:1,mng:1}[h];
}),b=document.getElementsByTagName('body')[0],i=0,l=a.length;
b.innerHTML='';
b.style.background='#000';
b.style.color='#ddd'
for(i;i<l;i++){
var t=a[i].href,p=document.createElement('img'),s=document.createElement('div');
s.innerHTML=t;
p.src=t;
b.appendChild(p);
b.appendChild(s);
}
})()
Here it is compressed
javascript:(function(){var c=Array.filter(document.getElementsByTagName("a"),function(a){return{gif:1,jpg:1,jpeg:1,png:1,mng:1}[a.href.split(".").pop().toLowerCase()]}),a=document.getElementsByTagName("body")[0],b=0,g=c.length;a.innerHTML="";a.style.background="#000";a.style.color="#ddd";for(b;b<g;b++){var d=c[b].href,e=document.createElement("img"),f=document.createElement("div");f.innerHTML=d;e.src=d;a.appendChild(e);a.appendChild(f)}})();
One that waits for each image to load. Added error detection.
(function(){
var a=Array.filter(document.getElementsByTagName('a'),function(e){
return {gif:1,jpg:1,jpeg:1,png:1,mng:1}[e.href.split('.').pop().toLowerCase()];
}),b=document.getElementsByTagName('body')[0],i=0,l=a.length;
b.innerHTML='';
b.style.background='#000';
b.style.color='#ddd'
add(0);
function add(i){
var img=new Image(),t=a[i].href,p=document.createElement('img'),s=document.createElement('div');
img.src=t;
img.onload=function(){
s.innerHTML=t;
p.src=t;
b.appendChild(p);
b.appendChild(s);
++i<a.length?add(i):'';
};
img.onerror=function(){
++i<a.length?add(i):'';
};
}
})()
And the minified version.
javascript:(function(){function d(b){var e=new Image,c=f[b].href,g=document.createElement("img"),h=document.createElement("div");e.src=c;e.onerror=function(){++b<f.length&&d(b)};e.onload=function(){h.innerHTML=c;g.src=c;a.appendChild(g);a.appendChild(h);++b<f.length&&d(b)}}var f=Array.filter(document.getElementsByTagName("a"),function(a){return{gif:1,jpg:1,jpeg:1,png:1,mng:1}[a.href.split(".").pop().toLowerCase()]}),a=document.getElementsByTagName("body")[0];a.innerHTML="";a.style.background="#000";a.style.color="#ddd";d(0)})();
Here is some test HTML
<a href='http://mozcom-cdn.mozilla.net/img/covehead/about/logo/download/logo-only-preview.png'>Firefox</a>
<a href='http://ie.microsoft.com/testdrive/Graphics/IEBeatz/assets/ie-logo-small.png'>IE</a>
<a href='http://code.google.com/tv/images/chrome-logo.png'>Chrome</a>
I did not add limiter on size of images because I was not sure if it was necessary and I wasn't sure what size limit you wanted.