PDA

View Full Version : Toggle Background Img



wyclef
11-09-2005, 12:01 AM
Anyone know how to toggle a CSS Background Image with Javascript? This is as far as i've gotten but it doesn't really work...



var captions = document.getElementsByTagName('caption')
var captionLength = captions.length

function changeBackground(){
for(var i = 0;i < captionLenght; i++) {
var nodeObj = captions.item(i)
if( nodeObj.style.background-image = '/minus-bg.gif') {
nodeObj.style.background-image = '/plus-bg.gif';
}
else {
nodeObj.style.background-image = '/minus-bg.gif';
}
}
}

function setBG(){
for(var i = 0;i < captionLenght; i++) {
var nodeObj = captions.item(i)
nodeObj.onClick=changeBackground();
}
}
/*--------------------------------------------------*/
window.onload = function() {
setBG();
}

jscheuer1
11-09-2005, 05:47 AM
This code looks very bloated to me. I'm not familiar with the .item(i) method of referencing elements in an array. It may be fine, just not what I am used to. I would use captions[i] in place of captions.item(i). Also, when assigning an onclick in this manner, it must be defined as function and onclick is far preferable to onClick (less chance the script parser will reject it), for example, where you have:


nodeObj.onClick=changeBackground();

it needs to be:


nodeObj.onclick=function(){changeBackground(this);}

The red part, a reference to the individual element is not crucial but, I'll use it in just a moment.

Now, we need to think a bit about the changeBackground() function itself. Aside from your using only one equal sign in the if statement (two are required when testing equality) the code assigns this as the onclick event for each individual caption element. Do we really want the code in changeBackground() executed each time an individual caption element is clicked? Don't we want something more like this:


function changeBackground(el){
if (el.style.backgroundImage == '/minus-bg.gif')
el.style.backgroundImage = '/plus-bg.gif';
else
el.style.backgroundImage = '/minus-bg.gif';
}

Notes: Camel notation is required in place of hyphenated style properties in javascript. Not knowing your directory structure I have left '/minus-bg.gif' and like literals as is. Using the leading / means the file is in the root directory of either the domain (if live) or of the hard drive (if local). More likely you are looking for a file in the same directory as the page the script is on. If so, get rid of the leading /. If you are working across an entire site with a rich directory structure, use the exact path from the root to the image file ex:


'c:/webfiles/mysite/images/minus-bg.gif'

when working locally and:


'http://www.mysite.com/images/minus-bg.gif'

when uploading to the server. These are only example paths, change them in the code to reflect actual conditions. To summarize (with further simplifications included), this is how I would go about it:


<script type="text/javascript">
function changeBackground(el){
if (el.style.backgroundImage == 'minus-bg.gif')
el.style.backgroundImage = 'plus-bg.gif';
else
el.style.backgroundImage = 'minus-bg.gif';
}

function setBG(){
var captions = document.getElementsByTagName('caption')
for(var i = 0;i < captions.length; i++)
captions[i].onclick=function(){changeBackground(this);}
}

window.onload = setBG;
</script>

mwinter
11-09-2005, 01:43 PM
I'm not familiar with the .item(i) method of referencing elements in an array.Not, an array: a collection.

Objects that implement the HTMLCollection interface have item and namedItem methods. These are primarily for languages like Java. ECMAScript is expressive enough so that bracket notation can replace both of these (though they should still be implemented).


Also, when assigning an onclick in this manner, it must be defined as function and onclick is far preferable to onClick (less chance the script parser will reject it),Your assessment thus far is correct, but I disagree with the conclusion:


for example, where you have:


nodeObj.onClick=changeBackground();

it needs to be:


nodeObj.onclick=function(){changeBackground(this);}Simply remove the function call:



nodeObj.onclick = changeBackground;
The changeBackground function can now be redefined to use the this operator to refer to its node:



function changeBackground() {
var style = this.style;

if(style && ('string' == typeof style.backgroundImage)) {
style.backgroundImage = (-1 != style.backgroundImage.indexOf('minus-bg'))
? 'url(/plus-bg.gif)'
: 'url(/minus-bg.gif)';
}
}
Notice the addition of the url(...) functional notation. This must be included when specifying URLs in CSS.

Mike

wyclef
11-09-2005, 04:56 PM
ok, i'm confused... doesn't "backgroundImage" have to be "background-image"? perhaps someone could post a working example of this that we can mull over?

mwinter
11-09-2005, 05:56 PM
ok, i'm confused... doesn't "backgroundImage" have to be "background-image"?In CSS, yes. However in a script, that would be interpreted as "subtract image from background", which is clearly undesirable.



if(document.getElementsByTagName) {
this.onload = function() {
var captions = document.getElementsByTagName('caption');

for(var i = 0, n = captions.length; i < n; ++i) {
captions[i&#93;.onclick = changeBackground;
}
};
}
using the changeBackground function I posted above.

Mike

mwinter
11-11-2005, 08:26 PM
I was going to respond to your comments, but it seems that you've deleted the post, so I'll just post my inevitable example (http://mwinter.webhop.info/dd/wyclef/).

Mike

Wedgy
11-15-2005, 05:23 AM
Notice the addition of the url(...) functional notation. This must be included when specifying URLs in CSS.

Mike
I'm confused too: Is this CSS or Javascript? or a mixture of both?

jscheuer1
11-15-2005, 06:14 AM
I'm confused too: Is this CSS or Javascript? or a mixture of both?

DHTML, don't you just love it! The answer, if I understand the question correctly is 'combination of both'. DHTML isn't really anything at all, technically speaking. It can draw from whatever is available.

While I am at it, I never responded to Mike's comments on my script in this thread. With the exception of my just plain error about forgetting to use the proper:


el.style.backgroundImage = "url('/minus-bg.gif')";

I think my code would work fine. However, I understand and like all of Mike's suggestions on this one (the background changing script), very neat and efficient. Good one Mike!

mwinter
11-15-2005, 12:46 PM
Notice the addition of the url(...) functional notation. This must be included when specifying URLs in CSS.I'm confused too: Is this CSS or Javascript? or a mixture of both?Assuming you're just referring to my mention of the url(...) functional notation (as that's what you quoted), that's defined by CSS.

See 4.3.4 URL + URN = URI (http://www.w3.org/TR/REC-CSS2/syndata.html#uri).

Mike

Wedgy
11-16-2005, 12:25 AM
Wow, thanks for the link.
I am still confused however:
In the link you provided, there is no indication or example of "url(blah)" being used in the middle of a Javascript function. It is described as a CSS2 definition, with its home in CSS stylesheets. Your code:


function changeBackground() {
var style = this.style;

if(style && ('string' == typeof style.backgroundImage)) {
style.backgroundImage = (-1 != style.backgroundImage.indexOf('minus-bg'))
? 'url(/plus-bg.gif)'
: 'url(/minus-bg.gif)';
}
}
This looks an awful lot like a piece of Javascript, and since I am assuming Javascript was invented before CSS2, I am surprised to see "url(blah)" here. I'd be even more surprised to find it described in a tutorial on Javascript due to the apparent anachronism.

What have I still got wrong here?

jscheuer1
11-16-2005, 05:44 AM
Mike may define it or characterize it differently but, its all Rock and Roll (read DHTML) to me. The specification for that portion of the code that is CSS is probably the way Mike states it is. Put it together with HTML and javascript, its DHTML. Javascript is always going to be periodically updated until it is finally completely outdated. I don't keep track of such things, last I noticed, we were up to v5 of javascript, I think. If a browser will recognize and use it, any javascript code is valid in that browser. What I consider simple CSS effects, like background images, are supported in virtually all modern browsers as both pure CSS and javascript code, if written to current standards.

mwinter
11-16-2005, 01:38 PM
I am still confused however:We seem to have our wires crossed.


In the link you provided, there is no indication or example of "url(blah)" being used in the middle of a Javascript function.Don't forget that it's functional notation. It looks like a function call, but it's just a form of delimiter. Anyway, the CSS specification wouldn't discuss use in scripts; it's out of its scope. :)


Your code:


function changeBackground() {
var style = this.style;

if(style && ('string' == typeof style.backgroundImage)) {
style.backgroundImage = (-1 != style.backgroundImage.indexOf('minus-bg'))
? 'url(/plus-bg.gif)'
: 'url(/minus-bg.gif)';
}
}This looks an awful lot like a piece of Javascript [...]That's because it is. Read what I wrote in my previous post. I was only referring to the notation because that's what you quoted. I was ignoring the code block itself, and I hoped I made that distinction clearly. Sorry for confusing you (and anyone else). :o



I don't keep track of such things, last I noticed, we were up to v5 of javascript, I think.We're up to ECMAScript (ECMA-262), 3rd Edition in modern, scriptable browsers. Implementations of that include JavaScript 1.5 and JScript 5.5.

Mike

Wedgy
11-17-2005, 02:57 PM
I guess its because I am always asking questions that probe the edges.

In my mind, I was thinking, "this is javascript, and there is this 'url(blah)' thing in the middle of a function call. Is it a mistake, or can the Javascript parser understand the piece of CSS being passed to it? Perhaps inside the browser, there is some subroutine that is used to parse and interpret the string, 'url(blah)'. If so, maybe not only does the CSS parsing section of code in the browser call this internal procedure/function, but perhaps in order to save code size, the Javascript code also knows of its existance and calls the code to parse this parameter being passed to the function."

Of course I know so little about interpreters (which I assume JS is one).
My experience has virtually always been in the use of compilers and assemblers.
In fact I don't even know if any of this is meaningful or relevant. Just my curiosity.

BigBody
11-18-2005, 12:57 PM
I have got wrong this code

document.body.style.backgroundImage = "url('bg.gif')"

Why? Please help me

jscheuer1
11-18-2005, 04:58 PM
I have got wrong this code

document.body.style.backgroundImage = "url('bg.gif')"

Why? Please help me

Looks good, is bg.gif in the same folder as the page? Also, this is javascript not css, pure css would be:


body {
background-image:url('bg.gif');
}

mwinter
11-18-2005, 05:59 PM
In my mind, I was thinking, "this is javascript, and there is this 'url(blah)' thing in the middle of a function call.But that 'thing' was a string. The script interpreter treats it as opaque (with the exception of escape sequences).


Is it a mistake, or can the Javascript parser understand the piece of CSS being passed to it?I think you're muddling your perception of Javascript with other things.

JavaScript, JScript, and other ECMAScript implementations are just scripting languages. They have a simple complement of built-in objects (Boolean, Number, Object, String, Array, Function, Error, Math, and RegExp), operators, functions, and control structures. By itself, ECMAScript isn't capable of much; it depends on host objects.

Browsers (and other environments - ECMAScript is general purpose) have to provide a great deal of other features. The de facto objects like location and document, as well as proprietary and standardised APIs are entirely separate.


Perhaps inside the browser, there is some subroutine that is used to parse and interpret the string, 'url(blah)'.Precisely. Modern browsers will implement the DOM 2 Style module that allows authors to obtain information about applied style sheet data, and to manipulate that data. JavaScript and all the others don't have a clue about CSS. However, the host objects that are bound into the language do.

Mike

BigBody
11-19-2005, 12:53 AM
Looks good, is bg.gif in the same folder as the page? Also, this is javascript not css, pure css would be:


body {
background-image:url('bg.gif');
}

I'm using javascript not css, and bg.gif is in the same folder as the page. I tried
document.body.background = 'bg.gif'
but it still have wrong

jscheuer1
11-19-2005, 03:21 AM
I'm using javascript not css, and bg.gif is in the same folder as the page. I tried
document.body.background = 'bg.gif'
but it still have wrong

What are you trying to do? Is this part of a script? As javascript code, it would need to be in order to do anything. If you have that happening then:


document.body.style.backgroundImage = "url('bg.gif')"

like you had at first, should work fine. BUT, this method can only be used on a body tag that has already been parsed by the browser. In other words, if the code is in the head and not executed 'onload', then there is no body yet, as far as the browser is concerned, so nothing to do. If possible, it is much easier to put the script containing this code in the body section of the page. That way the browser will have already 'seen' the body tag and can assign your style to it.

Wedgy
11-19-2005, 03:56 PM
I'm using javascript not css, and bg.gif is in the same folder as the page. I tried
document.body.background = 'bg.gif'
but it still have wrongI wonder if you have your javascript in the right spot:

i.e., not in the header, unless it is inside a function definition,
and if you want it executed on load, you may have to put something
in the body tag.

Otherwise, if it is in the <BODY> section,
it should be surrounded by <SCRIPT> tags properly filled out,
or else embedded in a mouseover command.