Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Javascript > feature detection to replace use of "navigator.userAgent" in Yahoo! UI event.js?

Reply
Thread Tools

feature detection to replace use of "navigator.userAgent" in Yahoo! UI event.js?

 
 
petermichaux@gmail.com
Guest
Posts: n/a
 
      09-01-2006
Hi,

I'm picking apart the Yahoo! UI event.js library and stripping it down
to just what I need. I'm also trying to make the parts I use better.
I'm stumped on how to fix the code for the getPageX() method. This
method is supposed to give the same value in IE as other browsers for
the event position relative to the left of the page. This value will be
greater than the position relative to the left of the browser if the
browser is scrolled to the right. What would be the appropriate feature
detection to use for the conditional in the following line?

if ( this.isIE ) {

Thank you,
Peter


isSafari: (/Safari|Konqueror|KHTML/gi).test(navigator.userAgent),

isIE: (!this.isSafari && !navigator.userAgent.match(/opera/gi) &&
navigator.userAgent.match(/msie/gi)),


getPageX: function(ev) {
var x = ev.pageX;
if (!x && 0 !== x) {
x = ev.clientX || 0;

if ( this.isIE ) {
x += this._getScroll()[1];
}
}
return x;
},

_getScroll: function() {
var dd = document.documentElement, db = document.body;
if (dd && dd.scrollTop) {
return [dd.scrollTop, dd.scrollLeft];
} else if (db) {
return [db.scrollTop, db.scrollLeft];
}
return [0, 0];
}

 
Reply With Quote
 
 
 
 
RobG
Guest
Posts: n/a
 
      09-01-2006
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> Hi,
>
> I'm picking apart the Yahoo! UI event.js library and stripping it down
> to just what I need. I'm also trying to make the parts I use better.
> I'm stumped on how to fix the code for the getPageX() method. This
> method is supposed to give the same value in IE as other browsers for
> the event position relative to the left of the page. This value will be
> greater than the position relative to the left of the browser if the
> browser is scrolled to the right. What would be the appropriate feature
> detection to use for the conditional in the following line?
>
> if ( this.isIE ) {


Don't use browser sniffing at all, use the stuff from quirksmode for
detecting the mouse coordinates:

<URL: http://www.quirksmode.org/js/events_properties.html >


Matt Kruse also has a utilities library to do much the same thing:

<URL: http://www.javascripttoolbox.com/lib/util/ >


[...]

--
Rob

 
Reply With Quote
 
 
 
 
petermichaux@gmail.com
Guest
Posts: n/a
 
      09-01-2006

RobG wrote:
> (E-Mail Removed) wrote:
> > Hi,
> >
> > I'm picking apart the Yahoo! UI event.js library and stripping it down
> > to just what I need. I'm also trying to make the parts I use better.
> > I'm stumped on how to fix the code for the getPageX() method. This
> > method is supposed to give the same value in IE as other browsers for
> > the event position relative to the left of the page. This value will be
> > greater than the position relative to the left of the browser if the
> > browser is scrolled to the right. What would be the appropriate feature
> > detection to use for the conditional in the following line?
> >
> > if ( this.isIE ) {

>
> Don't use browser sniffing at all, use the stuff from quirksmode for
> detecting the mouse coordinates:
>
> <URL: http://www.quirksmode.org/js/events_properties.html >
>
>
> Matt Kruse also has a utilities library to do much the same thing:
>
> <URL: http://www.javascripttoolbox.com/lib/util/ >


Hi Rob,

Thanks for the links. The quirksmode link gives a nice, concise
solution. Trusting that it is a robust way of doing things, I ended up
with a very short function

getPageX: function(e) {
if (e.pageX) {
return e.pageX;
} else if (e.clientX) {
return e.clientX + document.body.scrollLeft +
document.documentElement.scrollLeft;
}
},

What to do in the case neither e.pageX nor e.clientX exist? Probably
will never happen?

Thanks again!
Peter

 
Reply With Quote
 
RobG
Guest
Posts: n/a
 
      09-01-2006

(E-Mail Removed) wrote:
> RobG wrote:

[...]
> > Don't use browser sniffing at all, use the stuff from quirksmode for
> > detecting the mouse coordinates:
> >
> > <URL: http://www.quirksmode.org/js/events_properties.html >
> >
> >
> > Matt Kruse also has a utilities library to do much the same thing:
> >
> > <URL: http://www.javascripttoolbox.com/lib/util/ >

>
> Hi Rob,
>
> Thanks for the links. The quirksmode link gives a nice, concise
> solution. Trusting that it is a robust way of doing things, I ended up
> with a very short function
>
> getPageX: function(e) {
> if (e.pageX) {
> return e.pageX;
> } else if (e.clientX) {
> return e.clientX + document.body.scrollLeft +
> document.documentElement.scrollLeft;
> }
> },


I like use an ePos() function that returns an object with x & y
properties that are the event co-ords - but that's just my preference.
Then I can test the returned value simply:

var eventXY = ePos(event);
if (ePos){...}

If you just return a value, then to account for the fact that zero is a
valid return value you have to do something like:

var eventX = getPageX(event);
if ('number' == typeof eventX) {...}


> What to do in the case neither e.pageX nor e.clientX exist? Probably
> will never happen?


Never say never Mobile browsers are becoming more prevelent, while
their support for JavaScript is generally great, their scriptable DOM
support leaves a lot to be desired.

According to Quirksmode, pageX/clientX goes back to IE 5 and Navigator
4, hopefully that is far enough for you. Anyhow, return some value you
can recognise as "not supported" (say null) and deal with it in the
calling function.

if ('number' == typeof eventX) {
/* do something with the returned value */
} else {
/* not supported, deal with it */
}


--
Rob

 
Reply With Quote
 
Richard Cornford
Guest
Posts: n/a
 
      09-01-2006
(E-Mail Removed) wrote:
> RobG wrote:
> > (E-Mail Removed) wrote:

<snip>
>>> What would be the appropriate feature
>>> detection to use for the conditional in the following line?
>>>
>>> if ( this.isIE ) {

> >
> > Don't use browser sniffing at all, use the stuff from quirksmode for
> > detecting the mouse coordinates:
> >
> > <URL: http://www.quirksmode.org/js/events_properties.html >
> >
> >
> > Matt Kruse also has a utilities library to do much the same thing:
> >
> > <URL: http://www.javascripttoolbox.com/lib/util/ >

>
> Hi Rob,
>
> Thanks for the links. The quirksmode link gives a nice, concise
> solution. Trusting that it is a robust way of doing things, I ended up
> with a very short function
>
> getPageX: function(e) {
> if (e.pageX) {
> return e.pageX;
> } else if (e.clientX) {
> return e.clientX + document.body.scrollLeft +
> document.documentElement.scrollLeft;
> }
> },
>
> What to do in the case neither e.pageX nor e.clientX exist?
> Probably will never happen?


That may never happen, but a browser providing - pageX - only can still
have its value at zero and so return undefined. It is also possible
that the code may be exposed to a browser where - clientX - is not
accompanied by both of - body - and - documentElement -, so error out,
or that both of - body - and - documentElement - may be returning the
same scroll value for the browser (that was certainly true of some
Opera 7 releases, and usually worked as most scripts employed the first
of the two that appeared to provide a value so it did not matter if
both did).

(Opera <= 6 also had a bug in that they only supported - clientX/Y - on
events but returned page related offsets instead of window related).

Probably a better strategy might be to stop thinking in terms of
getting scroll positions from objects at the point of working out mouse
offsets from the page but instead to use a reliable cross-browser
scroll-offset reporting method and only apply it when an event only has
- clientX/Y - available.

<URL:
http://jibbering.com/faq/faq_notes/n....html#bdScroll >

Richard.

 
Reply With Quote
 
petermichaux@gmail.com
Guest
Posts: n/a
 
      09-01-2006

Richard Cornford wrote:
> (E-Mail Removed) wrote:
> > RobG wrote:
> > > (E-Mail Removed) wrote:

> <snip>
> >>> What would be the appropriate feature
> >>> detection to use for the conditional in the following line?
> >>>
> >>> if ( this.isIE ) {
> > >
> > > Don't use browser sniffing at all, use the stuff from quirksmode for
> > > detecting the mouse coordinates:
> > >
> > > <URL: http://www.quirksmode.org/js/events_properties.html >
> > >
> > >
> > > Matt Kruse also has a utilities library to do much the same thing:
> > >
> > > <URL: http://www.javascripttoolbox.com/lib/util/ >

> >
> > Hi Rob,
> >
> > Thanks for the links. The quirksmode link gives a nice, concise
> > solution. Trusting that it is a robust way of doing things, I ended up
> > with a very short function
> >
> > getPageX: function(e) {
> > if (e.pageX) {
> > return e.pageX;
> > } else if (e.clientX) {
> > return e.clientX + document.body.scrollLeft +
> > document.documentElement.scrollLeft;
> > }
> > },
> >
> > What to do in the case neither e.pageX nor e.clientX exist?
> > Probably will never happen?

>
> That may never happen, but a browser providing - pageX - only can still
> have its value at zero and so return undefined. It is also possible
> that the code may be exposed to a browser where - clientX - is not
> accompanied by both of - body - and - documentElement -, so error out,
> or that both of - body - and - documentElement - may be returning the
> same scroll value for the browser (that was certainly true of some
> Opera 7 releases, and usually worked as most scripts employed the first
> of the two that appeared to provide a value so it did not matter if
> both did).
>
> (Opera <= 6 also had a bug in that they only supported - clientX/Y - on
> events but returned page related offsets instead of window related).
>
> Probably a better strategy might be to stop thinking in terms of
> getting scroll positions from objects at the point of working out mouse
> offsets from the page but instead to use a reliable cross-browser
> scroll-offset reporting method and only apply it when an event only has
> - clientX/Y - available.
>
> <URL:
> http://jibbering.com/faq/faq_notes/n....html#bdScroll >


Hi Richard,

Thanks for the info and the link.

I really did think that the quirksmode way of assuming document.body
and document.documentElement both exist seems a little suspicious.

The link you sent is an interesting approach. It seems a bit convoluted
but looks like it must be very efficient in use as it doesn't have to
if-else with each call. Is this code your work?

Thanks again,
Peter

 
Reply With Quote
 
petermichaux@gmail.com
Guest
Posts: n/a
 
      09-01-2006
Richard Cornford wrote:

> Probably a better strategy might be to stop thinking in terms of
> getting scroll positions from objects at the point of working out mouse
> offsets from the page but instead to use a reliable cross-browser
> scroll-offset reporting method and only apply it when an event only has
> - clientX/Y - available.


Looking in Flanagan's book (4th ed p383), It looks like pageX/Y in
Netscape 4 would also need the scroll amounts added.


> <URL:
> http://jibbering.com/faq/faq_notes/n....html#bdScroll >



Using the function on jibbering, how does this function look?

getPageX: function(e) {
var x;
if (e.pageX) {
x=e.pageX;
} else if (e.clientX) {
x=e.clientX
} else {
return null;
}
return x + scrollInterface.getScrollX();
},


I wanted to cut this down to something like the following but I
couldn't get it working

getPageX: function(e) {
var x = (e.pageX) ? e.pageX : (e.clientX) ? e.clientX : return
null;
return x + scrollInterface.getScrollX();
},


I'm still surprised that a little tasks like finding an event location
is so challenging.

In fact, I don't really care about supporting Netscape 4 with it's lack
of clientX. Similarly, I don't really care about supporting browsers
without document.getElementById().

Thanks,
Peter

 
Reply With Quote
 
Richard Cornford
Guest
Posts: n/a
 
      09-07-2006
(E-Mail Removed) wrote:
<snip>
> Using the function on jibbering, how does this function
> look?
>
> getPageX: function(e) {
> var x;
> if (e.pageX) {


You have repeated one of the logical mistakes in the Yahoo library and
failed to consider that a - pageX - may legitimately be numeric zero,
which type-converts to boolean false;

> x=e.pageX;
> } else if (e.clientX) {
> x=e.clientX
> } else {
> return null;


NaN is the sensible value to return to indicate a failure from a
function call that would otherwise return another numeric value, and
the - isNaN - function is available for performing a discriminating test
for failure on the result.

> }
> return x + scrollInterface.getScrollX();


If the event object has a - pageX - property you don't want to be adding
scroll offsets to the - x - value. That addition should be restricted to
the - if(typeof e.clientX == 'number') - branch (if not more guarded).

> },
>
>
> I wanted to cut this down to something like the following but I
> couldn't get it working
>
> getPageX: function(e) {
> var x = (e.pageX)?e.pageXe.clientX)?e.clientX:return null;

<snip>

The - return - keyword forms a Statement, while the conditional operator
takes Expressions as its operands. A syntax error would be expected
here.

return (
(typeof e.pageX == 'number')?
e.pageX:
(
(typeof e.clientX == 'number')?
(
e.clientX + scrollInterface.getScrollX()
):
NaN
)
);

- would be the single Statement formulation of your code.

> I'm still surprised that a little tasks like finding an event
> location is so challenging.


You can rise to a challenge or hide from it. Why do you think the
general standard of scripting on the Internet is so poor?

> In fact, I don't really care about supporting Netscape 4
> with it's lack of clientX.


Why would that be a problem as it supports - pageX -? The code you have
written will work fine with Netscape 4, so long as the - pageX - is not
zero.

> Similarly, I don't really care about supporting
> browsers without document.getElementById().


That attitude will get in the way of your learning browser scripting.
Learn to design systems that still makes sense (and in e-commerce terms;
makes money) with client-side scripting disabled and you will find
yourself in a position to cope regardless of whether a browser
provides - document.getElementById - or not. And in a position to make
informed decisions about when designing/creating such a system is
appropriate.

Richard.


 
Reply With Quote
 
Richard Cornford
Guest
Posts: n/a
 
      09-07-2006
(E-Mail Removed) wrote:
<snip>
> I really did think that the quirksmode way of assuming
> document.body and document.documentElement both exist
> seems a little suspicious.


I am not a fan of the quirksmode attitude towards browser scripting.
There seems to be a lot of throwing up of hands in horror and then
walking away from the problems.

> The link you sent is an interesting approach. It seems
> a bit convoluted


It is convoluted, but internal complexity inside self-contained
components that follow the logic of the problem through to the point
where they should not need ongoing maintenance is not a great concern of
mine. The external interface is simple and that should be the only
concern of anyone using the component.

> but looks like it must be very efficient in use as it
> doesn't have to if-else with each call.


Yes, I don't like repeating tests on each call to a function in an
environment/context where all tests after the first a bound to return
the same result as the first.

> Is this code your work?


Would that matter?

Richard.


 
Reply With Quote
 
petermichaux@gmail.com
Guest
Posts: n/a
 
      09-07-2006
Hi Richard,

Thank you for the detailed reply.

[snip]

> > I'm still surprised that a little tasks like finding an event
> > location is so challenging.

>
> You can rise to a challenge or hide from it. Why do you think the
> general standard of scripting on the Internet is so poor?


I definitely want to rise to the challenge. A lot of the browser
incompatibility workarounds are quite subtle and it's great exprienced
people here are willing to share their experience. I also think that
the prototype.js, Scriptaculous, Yahoo! UI developers should spend more
time here asking quesitons and reading the discussions. Perhaps they
have to maintain an appearance of expertise.

Peter

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
MS recommends "feature detection" David Mark Javascript 24 06-15-2010 08:17 PM
Detecting Mac OS X (When feature detection doesn't work?) petermichaux@gmail.com Javascript 2 07-30-2006 09:45 PM
pyrex functions to replace a method (Re: replace a method in class:how?) Brian Blais Python 1 06-27-2006 12:13 PM
Feature detection in XSL template VK XML 17 05-25-2006 01:32 AM
'in' operator and feature detection technique... Luke Matuszewski Javascript 21 02-11-2006 09:42 AM



Advertisments