Clipping in Javascript

D

Doug van Vianen

Hi,

I am trying to show a clipped part of a picture on a webpage and
move it on the page and/or change the clipping to a different part
of the picture. I show the picture in the body of the page by
using

<div id=div1 style="position:absolute; top:200; left:400; width:200;
height:200; z-index:1; background-image:url(ole01.jpg);
clip:rect(0,150,50,100)"></div>

This shows the appropriate clipped part of the picture at the correct
location. I try to use the following Javascript code in the head to
change the position of the picture clip:

<script language="JavaScript">
<!--
function Dochange(ident) {
var ref=document.getElementById(ident);
ref.style.left=300;
}
-->
</script>}

and the following button in a form:

<input type="submit" name="Change" value="Change" size=20
onClick="Dochange('div1')">

The code is accessed when the button is clicked (I used an alert to
check this), but nothing happens to the position of the clipped
picture and no error message appears. Can someone help me?

When I get this working I would like to add any statements necessary
in the Javascript to change the clipping area. Would it be something
like

ref.style.clip:rect(0,50,50,0);

or what?

Thank you.

Doug van Vianen
(e-mail address removed)
 
M

Martin Honnen

Doug van Vianen wrote:

<div id=div1 style="position:absolute; top:200; left:400; width:200;
height:200; z-index:1; background-image:url(ole01.jpg);
clip:rect(0,150,50,100)"></div>

Try with
top: 200px;
left: 400px;
and so on to have proper CSS and then try
ref.style.left=300;

ref.style.left = '300px';
here and

<input type="submit" name="Change" value="Change" size=20
onClick="Dochange('div1')">

<input type="button" onClick="Dochange('div1')"
here
 
R

RobB

Doug said:
Hi,

I am trying to show a clipped part of a picture on a webpage and
move it on the page and/or change the clipping to a different part
of the picture. I show the picture in the body of the page by
using

<div id=div1 style="position:absolute; top:200; left:400; width:200;
height:200; z-index:1; background-image:url(ole01.jpg);
clip:rect(0,150,50,100)"></div>

This shows the appropriate clipped part of the picture at the correct
location. I try to use the following Javascript code in the head to
change the position of the picture clip:

<script language="JavaScript">
<!--
function Dochange(ident) {
var ref=document.getElementById(ident);
ref.style.left=300;
}
-->
</script>}

and the following button in a form:

<input type="submit" name="Change" value="Change" size=20
onClick="Dochange('div1')">

The code is accessed when the button is clicked (I used an alert to
check this), but nothing happens to the position of the clipped
picture and no error message appears. Can someone help me?

When I get this working I would like to add any statements necessary
in the Javascript to change the clipping area. Would it be something
like

ref.style.clip:rect(0,50,50,0);

or what?

Thank you.

Doug van Vianen
(e-mail address removed)

It's a CSS property, like any other, although the manipulation of it
can get a bit sticky as the four clip values are combined.

1) Get the element reference
2) Specify the style.clip property
3) Assign it a new string value in the combined format

var el;
if (el = document.getElementById('div1'))
el.style.clip = 'rect(40px,auto,auto,40px)';

Use 'auto' to return that specific clip value to fully revealed
(unclipped).

One of the few lovable things about Netscape 4 is it's parsing out of
the separate clip values into read/write properties. IE exposes
separate .currentStyle properties for each clip, but they're read-only.
<script type="text/javascript"> ["language" attribute deprecated]
 
R

RobG

RobB wrote:
[...]
if (el = document.getElementById('div1'))
el.style.clip = 'rect(40px,auto,auto,40px)';

Probably should test style too:

if (el = document.getElementById('div1') && el.style)
...
 
R

RobB

RobG said:
RobB wrote:
[...]
if (el = document.getElementById('div1'))
el.style.clip = 'rect(40px,auto,auto,40px)';

Probably should test style too:

if (el = document.getElementById('div1') && el.style)
...

Why? Are there browsers that support getElementById and not Style
objects?
 
R

Richard Cornford

RobB said:
RobG said:
RobB wrote:
[...]
if (el = document.getElementById('div1'))
el.style.clip = 'rect(40px,auto,auto,40px)';

Probably should test style too:

if (el = document.getElementById('div1') && el.style)
...
Why? Are there browsers that support getElementById and
not Style objects?

If - document.getElementById - has been emulated in its absence for
increased back compatibility then there is every chance that it will
return element references that do not implement a - style - object. This
would be particularly significant for authors of code that may be
deployed alongside code written by others as the fact that you know that
you did not emulate getElementById in its absence does not guarantee
that those other authors haven't.

Generally it is best to verify everything practical in javascript, and
therefor worth considering how that testing may effectively be done
without itself becoming a burden to the executing code.

Richard.
 
R

RobG

RobB wrote:

[...]
Why? Are there browsers that support getElementById and not Style
objects?

I have no idea, maybe not - but support for one feature should not be
used to infer support for another. Unless you can guarantee that every
browser that supports getElementById *does* support the style object,
it seems prudent to test it.
 
G

Grant Wagner

RobG said:
RobB wrote:
[...]
That would seem to be the operant question: when does
pants-and-suspenders (and cummerbund & drawstring) object testing of

Belt and braces? ;-)
this sort become a 'burden', occupying a significant volume of the
codebase? I've never seen a script which intentionally enhanced
functionality by patching in getElementById in user agents which did
not implement Style objects, although I suppose anything is possible.
Should everything be tested for before assuming its implementation?
When may asumptions be made?

A good question and worth pondering. However, before navel gazing,
lets look at the practicalities. I put each of the following into a
separate function, then called them 1000 times from separate
functions,
hopefully avoiding any conflicts between the two:

It is neither a performance issue, nor a burden, if handled properly:

Once at the beginning of your code you could do:

document.getElementStyleById = (function()
{
if (document.getElementById)
{
return function(id)
{
var node;
if ((node = document.getElementById(id)) && node.style)
{
return node.style;
}
return null;
}
}
else if (document.all)
{
return function(id)
{
var node;
if ((node = document.all[id]) && node.style)
{
return node.style;
}
return null;
}
}
})();

By the way, I'm surprised no one noticed, but:

if (node = document.getElementById(id) && node.style)

won't work. It will be interpreted as:

if (node = (document.getElementById(id) && node.style))

and generate an error that "node has no properties" (or worse, test
the -style- property of some other object assigned to -node-). To make
it work properly, you need extra brackets:

if ((node = (document.getElementById(id)) && node.style)
 
D

Dr John Stockton

JRS: In article <b%[email protected]>, dated Thu, 20 Jan
2005 19:53:43, seen in Grant Wagner
document.getElementStyleById = (function()
{
if (document.getElementById)
{
return function(id)
{
var node;
if ((node = document.getElementById(id)) && node.style)
{
return node.style;
}
return null;
}
}
else if (document.all)
{
return function(id)
{
var node;
if ((node = document.all[id]) && node.style)
{
return node.style;
}
return null;
}
}
})();

Would the following not work, assuming I've correctly edited gESBI ?

if (document.all && !document.getElementById) {
document.getElementById = function(id) {
return document.all[id] } }

document.getElementStyleById = (function()
{
return function(id)
{
var node;
if ((node = document.getElementById(id)) && node.style)
{
return node.style;
}
return null;
}
})();

Having executed the first part is likely to be useful elsewhere.
 
G

Grant Wagner

Dr John Stockton said:
JRS: In article <b%[email protected]>, dated Thu, 20 Jan
2005 19:53:43, seen in Grant Wagner
Would the following not work, assuming I've correctly edited gESBI ?

if (document.all && !document.getElementById) {
document.getElementById = function(id) {
return document.all[id] } }

document.getElementStyleById = (function()
{
return function(id)
{
var node;
if ((node = document.getElementById(id)) && node.style)
{
return node.style;
}
return null;
}
})();

Having executed the first part is likely to be useful elsewhere.

Yes, when I wrote my example I was thinking that it was pretty obvious
that I had a lot of duplicate code there, but I didn't give much thought
about how to best factor out the commonality. Although the second part
doesn't need to return a function now and could be re-written as:

document.getElementStyleById = function(id)
{
var node;
if ((node = document.getElementById(id)) && node.style)
{
return node.style;
}
return null;
}
}

One point, and both you and I are guilty of doing it. We are treating
document.all[id] as equivilent to document.getElementById(id), and they
are not. It is possible for document.all[id] to return a NodeList,
document.getElementById(id) never will (or should not).

Extra code (or care) is required to ensure that document.all[] returns a
single Node. A simple solution to prevent any errors might be:

if (document.all && !document.getElementById) {
document.getElementById = function(id)
{
var node = document.all[id];
if (node && 'undefined' != typeof node.length)
{
return node[0];
}
else
{
return node;
}
}
}

Whether returning the first Node of a NodeList of matches is "correct"
would have to be determined by the situation.
 
D

Dr John Stockton

JRS: In article <[email protected]>, dated Fri, 21 Jan
2005 19:35:26, seen in Grant Wagner
One point, and both you and I are guilty of doing it. We are treating
document.all[id] as equivilent to document.getElementById(id), and they
are not. It is possible for document.all[id] to return a NodeList,
document.getElementById(id) never will (or should not).

Extra code (or care) is required to ensure that document.all[] returns a
single Node. A simple solution to prevent any errors might be:

if (document.all && !document.getElementById) {
document.getElementById = function(id)
{
var node = document.all[id];
if (node && 'undefined' != typeof node.length)
{
return node[0];
}
else
{
return node;
}
}
}

Whether returning the first Node of a NodeList of matches is "correct"
would have to be determined by the situation.


(a) I suppose getElementById will return the first of a list.

(c) The substitute getElementById needs to be documented to say
specifically when it will, or may, return a nodelist. So does FAQ
DynWrite.

(c) The identifier document.getElementById is rather long; maybe it
is better to define a function findID to use instead.


So I'd try

if (document.all && !document.getElementById) {

findID = function(id) {
var node = document.all[id];
return (node && 'undefined' != typeof node.length) ? node[0] : node
}

}


If it was felt useful to have document.all[id] return a nodelist,
then ISTM that it should be useful to have code so that IE6 cam also get
a list :-

if (!document.all && document.getElementById) { ... // ??
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top