PDA

View Full Version : Keep a border on an image when clicked on it



Null
03-21-2006, 05:14 PM
Hi,

I have this code. When I click on the image, it will show the img url. Now I want when I click on the image, it will also show a border around the image. This way I can see which (seleted) image belongs to the code underneeth it. I tried some stuff with css but had no luck.

In short: click image, show border around it. Click other image, show border on the image (the other border dissappears again).

Hope someone can help me out!

The code:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">

.border img{
border: 2px solid white;
}

.border:hover img{
border: 2px solid lightgrey;
}

.border:active img{
border: 2px solid red;
}

</style>
<script language="JavaScript">

var isReady = false;

function showAddress(What){
if (isReady){
document.Which.Where.value = What;
}else{
alert("Not so fast...\nPlease wait for the page to finish loading.");
}
}

function clearAddress(){
if (isReady){
document.Which.Where.value = '';
}else{
alert("Not so fast...\nPlease wait for the page to finish loading.");
}
}

</script>
</head>

<body onload="isReady=true">

<a class="border"><img src="dir/a.png"
width="60"
height="60"
border="0"
onMouseDown="showAddress(this.src)"></a>

<a class="border"><img src="dir/b.png"
width="60"
height="60"
border="0"
onMouseDown="showAddress(this.src)"></a>

<form name="Which">
<input type="text" size="360" name="Where">
</form>

</body>
</html>

Twey
03-21-2006, 05:38 PM
<script type="text/javascript">
Array.prototype.indexOf = function(o) {
for(var i=0;i<this.length;i++) if(this[i] == o) return i;
return -1;
}

document.borderedImages = new Array();
function borderImage(img) {
if(document.borderedImages.indexOf(img) == -1) document.borderedImages.push(img);
for(var i=0;i<document.borderedImages.length;i++) document.borderedImages[i].style.borderStyle = "none";
img.style.border = "solid 1px red";
}

<img src="imageone.png" onclick="borderImage(this);">
<img src="imagetwo.png" onclick="borderImage(this);">Should work, but untested.

Null
03-21-2006, 05:52 PM
Must the scipt part be in the header or in the body?

Thx

Twey
03-21-2006, 05:55 PM
Head would be best, but body will work too so long as it's above the images.

Null
03-21-2006, 07:06 PM
Okay tested it, got some things not working:

1)mouse hover doesn't work any more
2)the images "move" a bit when clicking them
3)the other script stopped working, the image url isn't shown anymore...

The script you gave does work, but cancels a lot of other things.

My code now:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">

.border img{
border: 2px solid white;
}

.border:hover img{
border: 2px solid lightgrey;
}

.border:active img{
border: 2px solid red;
}

</style>

<script type="text/javascript">
Array.prototype.indexOf = function(o) {
for(var i=0;i<this.length;i++) if(this[i] == o) return i;
return -1;
}

document.borderedImages = new Array();
function borderImage(img) {
if(document.borderedImages.indexOf(img) == -1) document.borderedImages.push(img);
for(var i=0;i<document.borderedImages.length;i++) document.borderedImages[i].style.borderStyle = "none";
img.style.border = "solid 2px red";
}
</script

<script language="JavaScript">
var isReady = false;

function showAddress(What){
if (isReady){
document.Which.Where.value = What;
}else{
alert("Not so fast...\nPlease wait for the page to finish loading.");
}
}

function clearAddress(){
if (isReady){
document.Which.Where.value = '';
}else{
alert("Not so fast...\nPlease wait for the page to finish loading.");
}
}

</script>
</head>

<body onload="isReady=true">

<a class="border"><img src="dir/a.png"
width="60"
height="60"
border="0"
onclick="borderImage(this);"
onMouseDown="showAddress(this.src)"></a>

<a class="border"><img src="dir/b.png"
width="60"
height="60"
border="0"
onclick="borderImage(this);"
onMouseDown="showAddress(this.src)"></a>

<form name="Which">
<input type="text" size="360" name="Where">
</form>

</body>
</html>
Greetz

edit: ow and this code is displayed:

var isReady = false; function showAddress(What){ if (isReady){ document.Which.Where.value = What; }else{ alert("Not so fast...\nPlease wait for the page to finish loading."); } } function clearAddress(){ if (isReady){ document.Which.Where.value = ''; }else{ alert("Not so fast...\nPlease wait for the page to finish loading."); } }

Twey
03-21-2006, 07:18 PM
You missed the ending > off of the </script> tag. In fact, I missed the </script> tag completely. So I suppose I can't complain. :p But you can remove all this:
</script

<script language="JavaScript">It's unnecessary, and the language attribute is deprecated in favour of type.

Null
03-21-2006, 07:23 PM
Ahh ok that fixed the errors.

Still 2 problems:
1) when loading the page, the mouse hover works (onmouse over lightgrey border, see style). But after clicking an image this function doesn't work anymore
2) the images still "move" a little when cliking them.. how to fix this?

Thx for the quick replies!

Null

Twey
03-21-2006, 07:29 PM
1) when loading the page, the mouse hover works (onmouse over lightgrey border, see style). But after clicking an image this function doesn't work anymoreBecause it's overridden. Try using a class instead:
.border:active img, img.bordered {
border: 2px solid red;
}

</style>

<script type="text/javascript">
Array.prototype.indexOf = function(o) {
for(var i=0;i<this.length;i++) if(this[i] == o) return i;
return -1;
}

document.borderedImages = new Array();
function borderImage(img) {
if(document.borderedImages.indexOf(img) == -1) document.borderedImages.push(img);
for(var i=0;i<document.borderedImages.length;i++) document.borderedImages[i].className = "";
img.className = "bordered";
}The second is less easily fixed. Try setting a 1px border the same colour as the background.

Null
03-21-2006, 07:40 PM
Perfect, that code also fixed the moving images.

Got 1 little request left. At the moment the selected image has a red border, but the hover overides this one too. Is it possible to keep the mouse over on all the other images EXCEPT the one selected (with the red border)? So this one stays with the red border even when the mouse goes over it?

Thx again

Twey
03-21-2006, 07:59 PM
<script type="text/javascript">
Array.prototype.indexOf = function(o) {
for(var i=0;i<this.length;i++) if(this[i] == o) return i;
return -1;
}

document.borderedImages = new Array();
var oldmo = null;
function borderImage(img) {
if(document.borderedImages.indexOf(img) == -1) {
document.borderedImages.push(img);
if(oldmo == null) oldmo = img.onmouseover;
}
for(var i=0;i<document.borderedImages.length;i++) {
document.borderedImages[i].className = "";
document.borderedImages[i].onmouseover = oldmo;
}
img.className = "bordered";
img.onmouseover = function(){return true;};
}

Null
03-21-2006, 08:15 PM
<script type="text/javascript">
Array.prototype.indexOf = function(o) {
for(var i=0;i<this.length;i++) if(this[i] == o) return i;
return -1;
}

document.borderedImages = new Array();
var oldmo = null;
function borderImage(img) {
if(document.borderedImages.indexOf(img) == -1) {
document.borderedImages.push(img);
if(oldmo == null) oldmo = img.onmouseover;
}
for(var i=0;i<document.borderedImages.length;i++) {
document.borderedImages[i].className = "";
document.borderedImages[i].onmouseover = oldmo;
}
img.className = "bordered";
img.onmouseover = function(){return true;};
}
Sorry, this has no effect, the behavoiur stays the same. The red border is still overwritten on the mouse over....

Thx for the fast replies

Twey
03-21-2006, 08:52 PM
Oh - because you use CSS for this. Sorry, forgot about that.
.border:hover img.bordered {
border-style: solid 2px red;
}

Null
03-21-2006, 09:38 PM
Sorry still no effect, perhaps I did something wrong so here is the code I have now:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">

.border img{
border: 2px solid white;
}

.border:hover img{
border: 2px solid lightgrey;
}

.border:hover img.bordered {
border-style: solid 2px red;
}

.border:active img, img.bordered {
border: 2px solid red;
}

</style>

<script type="text/javascript">
Array.prototype.indexOf = function(o) {
for(var i=0;i<this.length;i++) if(this[i] == o) return i;
return -1;
}

document.borderedImages = new Array();
var oldmo = null;
function borderImage(img) {
if(document.borderedImages.indexOf(img) == -1) {
document.borderedImages.push(img);
if(oldmo == null) oldmo = img.onmouseover;
}
for(var i=0;i<document.borderedImages.length;i++) {
document.borderedImages[i].className = "";
document.borderedImages[i].onmouseover = oldmo;
}
img.className = "bordered";
img.onmouseover = function(){return true;};
}

var isReady = false;

function showAddress(What){
if (isReady){
document.Which.Where.value = What;
}else{
alert("Not so fast...\nPlease wait for the page to finish loading.");
}
}

function clearAddress(){
if (isReady){
document.Which.Where.value = '';
}else{
alert("Not so fast...\nPlease wait for the page to finish loading.");
}
}

</script>
</head>

<body onload="isReady=true">

<a class="border"><img src="dir/a.png"
width="60"
height="60"
border="0"
onclick="borderImage(this);"
onMouseDown="showAddress(this.src)"></a>

<a class="border"><img src="dir/b.png"
width="60"
height="60"
border="0"
onclick="borderImage(this);"
onMouseDown="showAddress(this.src)"></a>

<form name="Which">
<input type="text" size="360" name="Where">
</form>

</body>
</html>
Sorry if you have made a mistake :rolleyes:

Twey
03-21-2006, 09:45 PM
Sorry if you have made a mistake :rolleyes:Yes, it's my error again. :) Remove -style from the declaration.

mwinter
03-21-2006, 10:18 PM
Array.prototype.indexOf = function(o) {
for(var i=0;i<this.length;i++) if(this[i] == o) return i;
return -1;
}Totally unrelated to the task at hand, but that could be better written as:



if (typeof Array.prototype.indexOf == 'function')
Array.prototype.indexOf = function(v, s) {
var n = this.length >>> 0,
i = s >>> 0;

for (; i < n; ++i)
if (this[i] === v)
return i;
return -1;
};
Recent Gecko browsers (should) implement an indexOf method. By testing for that method, rather than unconditionally adding a user-defined version, there's the potential from benefiting from a faster, native implementation.

A strict comparison is also more appropriate than a type-converting one.

Mike

Null
03-21-2006, 10:43 PM
Yes, it's my error again. :) Remove -style from the declaration.
Could you be more accurate? Don't understand quite what to remove... :confused: (Bad in english :))

to mr winter; so why is that part better?

Twey
03-21-2006, 10:51 PM
Could you be more accurate?
.border:hover img.bordered {
border: solid 2px red;
}
to mr winter; so why is that part better?He explained it: it's twopart. Firstly, he actually checked whether Array.indexOf() already existed; secondly, he (I think) used bitwise operations for something or other, which are faster. Mine was just hacked up for the task at hand; actual thought seems to have gone into his. :)
Although, Mike, I'm not sure what v is used for?

Null
03-21-2006, 11:09 PM
Euuhh I am sorry, but the hover still overides the red border :(

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">

.border img{
border: 2px solid white;
}

.border:hover img{
border: 2px solid lightgrey;
}

.border:active img, img.bordered {
border: 2px solid red;
}

</style>

<script type="text/javascript">
Array.prototype.indexOf = function(o) {
for(var i=0;i<this.length;i++) if(this[i] == o) return i;
return -1;
}

document.borderedImages = new Array();
var oldmo = null;
function borderImage(img) {
if(document.borderedImages.indexOf(img) == -1) {
document.borderedImages.push(img);
if(oldmo == null) oldmo = img.onmouseover;
}
for(var i=0;i<document.borderedImages.length;i++) {
document.borderedImages[i].className = "";
document.borderedImages[i].onmouseover = oldmo;
}
img.className = "bordered";
img.onmouseover = function(){return true;};
}

var isReady = false;

function showAddress(What){
if (isReady){
document.Which.Where.value = What;
}else{
alert("Not so fast...\nPlease wait for the page to finish loading.");
}
}

function clearAddress(){
if (isReady){
document.Which.Where.value = '';
}else{
alert("Not so fast...\nPlease wait for the page to finish loading.");
}
}

</script>
</head>

<body onload="isReady=true">

<a class="border"><img src="dir/a.png"
width="60"
height="60"
border="0"
onclick="borderImage(this);"
onMouseDown="showAddress(this.src)"></a>

<a class="border"><img src="dir/b.png"
width="60"
height="60"
border="0"
onclick="borderImage(this);"
onMouseDown="showAddress(this.src)"></a>

<form name="Which">
<input type="text" size="360" name="Where">
</form>

</body>
</html>Am I missing something? Sorry to border you again with this....

About the winter adaption; indeed the v is what I don't understand either. If the script works, I will add his script part to see if it works :D

Thx for the help guys

Null

mwinter
03-21-2006, 11:14 PM
[...] he (I think) used bitwise operations for something or otherSome simple initialisation, that's all.

Bitwise operators generally convert their operands to signed 32-bit integers, with the side-effect that if the operand type-converts to NaN or Infinity, that value is substituted for zero (+0). The unsigned right shift operator, on the other hand, converts its left-hand operand to an unsigned 32-bit integer (with the same side-effects), which just happens to also be the range of array indicies.


Although, Mike, I'm not sure what v is used for?That's what happens when you look at someone else's code whilst writing your own. :) The post has been edited.

Mike

Twey
03-21-2006, 11:16 PM
Argh, I'm tired; the code is starting to beg me to let it sleep :p I'll come back to this one in the morning.
/EDIT: Aha, now it all makes a strange sort of "aargh-my-eyes-are-falling-out" sense. :p

Null
03-21-2006, 11:35 PM
Till tomorrow then :D

Null
03-22-2006, 10:17 AM
Found some incossistentie(?) in the code:

<a class="border"><img src="dir/a.png"
width="60"
height="60"
border="0"
onclick="borderImage(this)"
onMouseDown="showAddress(this.src);"></a>
Must the onclick and the onMouseDown have a ; at the end or not and why?

So like this:

<a class="border"><img src="dir/a.png"
width="60"
height="60"
border="0"
onclick="borderImage(this);"
onMouseDown="showAddress(this.src);"></a> or can I keep the ; away like:

<a class="border"><img src="dir/a.png"
width="60"
height="60"
border="0"
onclick="borderImage(this)"
onMouseDown="showAddress(this.src)"></a>
Both seem to work, so I am confused :)

Null

Twey
03-22-2006, 11:48 AM
In Javascript, the end of a statement is represented by either a semicolon or a new line. The end of an event attribute is considered to have a newline sequence after it.

Null
03-22-2006, 12:36 PM
So I need to use ; at the end of these 2 lines?

Any luck on fixing the hover thingy?

Greetz

mwinter
03-22-2006, 12:48 PM
As I saw the problem, I thought I may as well weigh into this thread, properly...



In short: click image, show border around it. Click other image, show border on the image (the other border dissappears again).A fully-working example (http://mwinter.webhop.info/dd/null/show-source.html). Most of the code is in-line for simplicity, but both the style sheet and script should be external. Code that already is in external files performs remedial tasks, like patching up missing methods in earlier IE versions (arrays.js (http://mwinter.webhop.info/dd/null/arrays.js)), providing data structures (set-minimized.js (http://mwinter.webhop.info/dd/null/set-minimized.js)), and event management (event-dispatcher.js (http://mwinter.webhop.info/dd/null/event-dispatcher.js)).



[To fix image movement] Try setting a 1px border the same colour as the background.It's a shame, really, that IE doesn't support the transparent value for border colours. It's a much nicer solution than setting the same colour as the background.



Is it possible to keep the mouse over on all the other images EXCEPT the one selected (with the red border)? So this one stays with the red border even when the mouse goes over it?This requirement seems to have been the stumbling block for much of the thread, and I note the reason (and the solution) in the comments in my example style sheet.

The :hover rule uses the selector, '.border:hover img'. The highlighting rule uses the selector, 'img.bordered'. The former is more specific (one element, two [pseudo-]classes) than the latter (one element, one class) so its declarations will take precedence.



In Javascript, the end of a statement is represented by either a semicolon or a new line.It's not quite as simple as that. ECMAScript defines a mechanism named 'Automatic Semicolon Insertion' (7.9, ECMA-262 3rd Ed.). The general gist is that a line terminator will implicitly create a semicolon to terminate the statement, but there are exceptions and the implications for certain productions result in very different behaviour.

For an example of the latter, consider:



return
-1
A line terminator may not appear between a return statement and its expression. As such, the code above is effectively the same as:



return;
-1;
That aside, personally, I think it's just good form to always include it.

Hope that helps,
Mike

Null
03-22-2006, 01:04 PM
Aah thx going to try that.

I have another noob question. The script shows the following line:
http://www.mlwinter.pwp.blueyonder.co.uk/dd/null/underwater-dome.jpeg

Can it be changed to only show (so whitout the http://www.site.com):
null/underwater-dome.jpeg

My real question is, what loads faster (loads the pic faster)

http://www.mlwinter.pwp.blueyonder.co.uk/dd/null/underwater-dome.jpeg

or

null/underwater-dome.jpeg

or is there no difference?

Null

ps where did the text field go where the adress is shown in? I need it for sending purposes

also (plz don't be offended), it seems to have a lot of code for such a small feature, think I will have enough with the code i gave with an hover fix....

Twey
03-22-2006, 04:02 PM
My real question is, what loads faster (loads the pic faster)There is no difference (relative URLs might take a couple of milliseconds more or less to parse; it's negligable if so). The argument for relative URLs is that it makes the site easy to simply move elsewhere.
Can it be changed to only show (so whitout the http://www.site.com):
null/underwater-dome.jpeg
url = url.replace("http://" + window.location.host, "");

Null
03-22-2006, 05:00 PM
Ah okay, now i only need the hover fix, i know winter gave a great script, but is kinda too big for me and way to complexed (for a noob like me :)) So Twey if you have the time :) I have the cade as given a couple of posts above

Thx

mwinter
03-22-2006, 05:14 PM
The script shows the following line:
http://www.mlwinter.pwp.blueyonder.co.uk/dd/null/underwater-dome.jpeg

Can it be changed to only show (so whitout the http://www.site.com):
null/underwater-dome.jpegYes, the scheme and authority components can be stripped. The doShow function can be modified to:



function doShow(image) {
var match;

if (image && (match = /^([a-z]+:\/\/)?[^\/]*(\/.+)/i.exec(image.src))) {
addressText.data = match[2];
highlightElement(image);
}
}

My real question is, what loads faster (loads the pic faster) [a relative or absolute URL?]As Twey wrote, there is no difference. The browser will always resolve a relative URL to an absolute one anyway, so the only real question is which is more convenient for the author.


ps where did the text field go where the adress is shown in? I need it for sending purposesYou never said that. In fact, your original post suggested that it was simply for displaying the image address. There was no action attribute on the form element, and no submit button.

It pays to provide all relevant information when asking a question. The example has been modified.


also (plz don't be offended), it seems to have a lot of code for such a small feature, think I will have enough with the code i gave with an hover fix....The code does what it does, quickly and efficiently. If you want to use intrinsic events (http://mwinter.webhop.info/dd/null/show-source-intrinsic.html) instead, that can reduce the code, but at the expense of markup bloat. If there are only a few images, that trade-off might be acceptable. If not, dynamically adding the listeners (and subsequently removing them to avoid memory leaks in IE) is a nicer solution.

Another solution is to go back in time and convince Microsoft to make IE a better browser. That would also reduce the amount of baggage. :)

Mike

Null
03-22-2006, 05:26 PM
You never said that. In fact, your original post suggested that it was simply for displaying the image address. There was no action attribute on the form element, and no submit button.

It pays to provide all relevant information when asking a question. The example has been modified.
Yeah I just build things in steps, wanted to at a submit button later

Another solution is to go back in time and convince Microsoft to make IE a better browser. That would also reduce the amount of baggage. :)

Mike I will do that :D

But thx going to play some more with this code

Twey
03-22-2006, 05:37 PM
Another solution is to go back in time and convince Microsoft to make IE a better browser. That would also reduce the amount of baggage. :)Haha, count me in :)

Null
03-22-2006, 10:33 PM
Script works great, thx guys