Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Javascript > how to test for browser specific methods like document.selection.createRange

Reply
Thread Tools

how to test for browser specific methods like document.selection.createRange

 
 
lawrence
Guest
Posts: n/a
 
      11-20-2004
Is this the correct way to test for a method before I use it?
createRange() is, I believe, an IE only method.


function wrapSelectionInTag(selection, tag) {
if (document.selection.createRange) {
var range = document.selection.createRange();
if (range.parentElement() == element) range.text = '<' + tag +
'>' + range.text + '<\/' + tag + '>';
}
}
 
Reply With Quote
 
 
 
 
Michael Winter
Guest
Posts: n/a
 
      11-20-2004
On 20 Nov 2004 13:06:32 -0800, lawrence <(E-Mail Removed)> wrote:

> Is this the correct way to test for a method before I use it?


Nearly. You need to check for the object, selection, as well.

if(document.selection && document.selection.createRange) {
var range = document.selection.createRange();
/* ... */
}

Alternatively,

var sel;
if((sel = document.selection) && sel.createRange) {
var range = sel.createRange();
/* ... */
}

> createRange() is, I believe, an IE only method.


It is a proprietary method, but that doesn't necessarily mean only IE
supports it. I can't name any others that do, though.

[snip]

Mike


*Please* don't use tabs for indentation on Usenet. Convert them to spaces
before posting.

--
Michael Winter
Replace ".invalid" with ".uk" to reply by e-mail.
 
Reply With Quote
 
 
 
 
RobG
Guest
Posts: n/a
 
      11-21-2004
Michael Winter wrote:
[...]
>
>> createRange() is, I believe, an IE only method.

>
>
> It is a proprietary method, but that doesn't necessarily mean only IE
> supports it. I can't name any others that do, though.


Seems it's been adopted in DOM Level 2

<URL:http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113/ranges.html#Level2-DocumentRange-method-createRange>

I've tested it in Mozilla and Safari (it works...).
Rob.
 
Reply With Quote
 
Michael Winter
Guest
Posts: n/a
 
      11-21-2004
On Sun, 21 Nov 2004 21:16:16 +1000, RobG <(E-Mail Removed)> wrote:

> Michael Winter wrote:


[snip]

>> [createRange] is a proprietary method, but that doesn't necessarily
>> mean only IE supports it. I can't name any others that do, though.

>
> Seems it's been adopted in DOM Level 2
>
> [URL to DOM 2 Traveral and Range Specification]


[snip]

As I understand it, they are two different things.

The document.selection.createRange method, as introduced by Microsoft,
reflects text selected by the user.

The document.createRange method, as introduced by the W3C, selects a
portion of the document tree, allowing you to manipulate it as a block
(essentially).

Mike

--
Michael Winter
Replace ".invalid" with ".uk" to reply by e-mail.
 
Reply With Quote
 
Fred Oz
Guest
Posts: n/a
 
      11-21-2004
Michael Winter wrote:
[...]
> The document.selection.createRange method, as introduced by Microsoft,
> reflects text selected by the user.
>
> The document.createRange method, as introduced by the W3C, selects a
> portion of the document tree, allowing you to manipulate it as a block
> (essentially).


Ah yes, thanks.

Rob.
 
Reply With Quote
 
lawrence
Guest
Posts: n/a
 
      11-21-2004
Fred Oz <(E-Mail Removed)> wrote in message news:<41a08c76$0$25762$(E-Mail Removed)>...
> Michael Winter wrote:
> [...]
> > The document.selection.createRange method, as introduced by Microsoft,
> > reflects text selected by the user.
> >
> > The document.createRange method, as introduced by the W3C, selects a
> > portion of the document tree, allowing you to manipulate it as a block
> > (essentially).



I'm trying to create an online text editor to supplement the PHP/MySql
content management system that we've already built. I don't know
Javascript all that well, so some of these questions may be stupid.

I changed the tabs to spaces in Microsoft Word, I hope Word doesn't
add any garbage characters.

I get no syntax errors in FireFox, but I'm not getting any selection
either. I'm not sure how to pass the right reference is in the html
form at bottom. How do I say, "Hey, I'm this element"??? And do I get
a string identifier that I could use in getElementById(), or is it a
number I could use to reference the right index in elements[]????







<script type="text/javascript">

function insertAtCursor(myField, tag) {
if (document.selection && document.selection.createRange) {
var range = document.selection.createRange();
if (range.parentElement() == element) range.text = '<' + tag
+ '>' + range.text + '<\/' + tag + '>';
} else if (myField && myField.selectionStart) {
// MOZILLA/NETSCAPE support
// textControl.value.substring(textControl.selectionS tart,
textControl.selectionEnd)
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
myField.value = myField.value.substring(0, startPos) +
myValue + myField.value.substring(endPos, myField.value.length);
} else if (document.forms[0].myField) {
myField.value += '<' + tag + '>' + range.text + '<\/' + tag
+ '>';
} else {
alert("Awful sorry, but this web broswer doesn't support the
operations of this button");
}
}


function wrapSelectionMakeALink (element) {
var range = document.selection.createRange();
address = prompt('What address?', '');
address = '<a href=\\\"' + address + '\\\">';
if (range.parentElement() == element) range.text = address +
range.text + '<\/a>';
}

function wrapSelectionInsertImage (element) {
var range = document.selection.createRange();
address = prompt('Add address for image. If the image is on
your site, look in Image Info.', '');
address = '<img src=\\\"' + address + '\\\">';
if (range.parentElement() == element) range.text = address +
range.text;
}
</script>

<form method="post" action="#">
<input type="button" value="bold"
onclick="insertAtCursor(document.forms[0].elements[this], 'b')" />
<input type="button" value="italic"
onclick="insertAtCursor(document.forms[0].elements[this], 'i')" />
<input type="button" value="blockquote"
onclick="insertAtCursor(document.forms[0].elements[this],
'blockquote')" />
<input type="button" value="big headline"
onclick="insertAtCursor(document.forms[0].elements[this], 'h2')" />
<input type="button" value="small headline"
onclick="insertAtCursor(document.forms[0].elements[this], 'h5')" />
<input type="button" value="make a link"
onclick="wrapSelectionMakeALink()" /> <p> sdfsd </p>
<textarea>Type something here, damnit</textarea> <p> sadfsdaf </p>
<input type="submit">
</form> <script type="text/javascript">

function insertAtCursor(myField, tag) {
if (document.selection && document.selection.createRange) {
var range = document.selection.createRange();
if (range.parentElement() == element) range.text = '<' + tag
+ '>' + range.text + '<\/' + tag + '>';
} else if (myField.selectionStart) {
// MOZILLA/NETSCAPE support
// textControl.value.substring(textControl.selectionS tart,
textControl.selectionEnd)
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
myField.value = myField.value.substring(0, startPos) +
myValue + myField.value.substring(endPos, myField.value.length);
} else if (document.forms[0].myField) {
myField.value += '<' + tag + '>' + range.text + '<\/' + tag
+ '>';
} else {
alert("Awful sorry, but this web broswer doesn't support the
operations of this button");
}
}


function wrapSelectionMakeALink (element) {
var range = document.selection.createRange();
address = prompt('What address?', '');
address = '<a href=\\\"' + address + '\\\">';
if (range.parentElement() == element) range.text = address +
range.text + '<\/a>';
}

function wrapSelectionInsertImage (element) {
var range = document.selection.createRange();
address = prompt('Add address for image. If the image is on
your site, look in Image Info.', '');
address = '<img src=\\\"' + address + '\\\">';
if (range.parentElement() == element) range.text = address +
range.text;
}
</script>

<form method="post" action="#">
<input type="button" value="bold"
onclick="insertAtCursor(document.forms[0].elements[this], 'b')" />
<input type="button" value="italic"
onclick="insertAtCursor(document.forms[0].elements[this], 'i')" />
<input type="button" value="blockquote"
onclick="insertAtCursor(document.forms[0].elements[this],
'blockquote')" />
<input type="button" value="big headline"
onclick="insertAtCursor(document.forms[0].elements[this], 'h2')" />
<input type="button" value="small headline"
onclick="insertAtCursor(document.forms[0].elements[this], 'h5')" />
<input type="button" value="make a link"
onclick="wrapSelectionMakeALink()" /> <p> sdfsd </p>
<textarea>Type something here, damnit</textarea> <p> sadfsdaf </p>
<input type="submit">
</form>
 
Reply With Quote
 
lawrence
Guest
Posts: n/a
 
      11-22-2004
Okay, I managed to get my text editor working for IE and
Mozilla/FireFox, but only by hardcoding the reference to the textarea
on the form. What is the generic way to get an element to refer to
itself, and pass a reference to itself to a function?








<script type="text/javascript">

function insertAtCursor(myField, tag) {
if (document.selection && document.selection.createRange) {
var range = document.selection.createRange();
if (range.text == '') {
alert("You haven't selected any text to change.");
} else {
range.text = '<' + tag + '>' + range.text + '<\/' + tag + '>';
}
} else if (myField && myField.selectionStart) {
// MOZILLA/NETSCAPE support
// myField.value.substring(myField.selectionStart,
myField.selectionEnd)
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
var elementName = myField.id;
if (startPos != 0 || endPos != 0) {
var mySelection =
myField.value.substring(myField.selectionStart, myField.selectionEnd);
mySelection = '<' + tag + '>' + mySelection + '<\/' + tag +
'>';
document.getElementById(elementName).value =
myField.value.substring(0, startPos) + mySelection +
myField.value.substring(endPos, myField.value.length);
} else {
alert("You haven't selected any text to change.");
}
} else if (document.forms[0].myField) {
myField.value += '<' + tag + '>' + range.text + '<\/' + tag +
'>';
} else {
alert("Awful sorry, but this web broswer doesn't support the
operations of this button");
}
}


function insertAtCursorLink (myField) {
if (document.selection && document.selection.createRange) {
address = prompt('What is the address you want to link to?',
'http://');
var range = document.selection.createRange();
if (range.text == '') {
alert("You haven't selected any text to change.");
} else {
range.text = '<a href=\"' + address + '\">' + range.text +
'<\/a>';
}
} else if (myField && myField.selectionStart) {
// MOZILLA/NETSCAPE support
address = prompt('What is the address you want to link to?',
'http://');
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
var elementName = myField.id;
if (startPos != 0 || endPos != 0) {
var mySelection =
myField.value.substring(myField.selectionStart, myField.selectionEnd);
mySelection = '<a href=\"' + address + '\">' + mySelection +
'<\/a>';
document.getElementById(elementName).value =
myField.value.substring(0, startPos) + mySelection +
myField.value.substring(endPos, myField.value.length);
} else {
alert("You haven't selected any text to change.");
}
} else if (document.forms[0].myField) {
myField.value += '<' + tag + '>' + range.text + '<\/' + tag +
'>';
} else {
alert("Awful sorry, but this web broswer doesn't support the
operations of this button");
}
}

function insertAtCursorImage (myField) {
var range = document.selection.createRange();
address = prompt('Add address for image. If the image is on your
site, look in Image Info.', '');
address = '<img src=\\\"' + address + '\\\">';
if (range.parentElement() == element) range.text = address +
range.text;
}
</script>

<form method="post" action="#">
<input type="button" value="bold"
onclick="insertAtCursor(document.forms[0].elements['dog'], 'b');" />
<input type="button" value="italic"
onclick="insertAtCursor(document.forms[0].elements['dog'], 'i');" />
<input type="button" value="blockquote"
onclick="insertAtCursor(document.forms[0].elements['dog'],
'blockquote');" />
<input type="button" value="big headline"
onclick="insertAtCursor(document.forms[0].elements['dog'], 'h2');" />
<input type="button" value="small headline"
onclick="insertAtCursor(document.forms[0].elements['dog'], 'h5');" />
<input type="button" value="make a link"
onclick="insertAtCursorLink(document.forms[0].elements['dog'])" />
<p> sdfsd </p>
<textarea id='dog' name='dog'>Type something here, damnit</textarea>
<p> sadfsdaf </p>
<input type="submit">
</form>
 
Reply With Quote
 
Michael Winter
Guest
Posts: n/a
 
      11-22-2004
On 21 Nov 2004 23:25:02 -0800, lawrence <(E-Mail Removed)> wrote:

> Okay, I managed to get my text editor working for IE and
> Mozilla/FireFox, but only by hardcoding the reference to the textarea on
> the form. What is the generic way to get an element to refer to itself,
> and pass a reference to itself to a function?


In an event listener, the this operator refers to the element. However,
that's useless to you as you're buttons are not referring to themselves,
they're referring to another element in the same form.

The best you can do is shorten the reference from

document.forms[0].elements['textarea-name-or-id']

to

this.form.elements['textarea-name-or-id']

in the onclick attributes.


In this code, you've missed the point of providing a reference to a
control. Namely, you take an element reference, obtain its id, then use
getElementById to get the reference again.

> function insertAtCursor(myField, tag) {
> if (document.selection && document.selection.createRange) {
> var range = document.selection.createRange();
> if (range.text == '') {
> alert("You haven't selected any text to change.");
> } else {
> range.text = '<' + tag + '>' + range.text + '<\/' + tag + '>';
> }
> } else if (myField && myField.selectionStart) {


A better test would be

} else if('number' == typeof myField.selectionStart) {

which would succeed if the selection started at offset zero. You don't
need to test for myField as you know that will exist (you passed it!).

> // MOZILLA/NETSCAPE support
> // myField.value.substring(myField.selectionStart,
> myField.selectionEnd)
> var startPos = myField.selectionStart;
> var endPos = myField.selectionEnd;
> var elementName = myField.id;


This is where the silliness begins. You have the element - you don't need
the id. Delete that line.

> if (startPos != 0 || endPos != 0) {
> var mySelection = myField.value.substring(
> myField.selectionStart,
> myField.selectionEnd);


You've stored the values of these two properties in startPos and endPos,
so you may as well use them.

> mySelection = '<' + tag + '>' + mySelection + '<\/' + tag
> + '>';
> document.getElementById(elementName).value
> = myField.value.substring(0, startPos) + mySelection
> + myField.value.substring(endPos, myField.value.length);


Just

myField.value = ...

will do.

> } else {
> alert("You haven't selected any text to change.");
> }
> } else if (document.forms[0].myField) {


This looks for the field named (or identified as) myField in the first
form in the document. That will fail every time as you have no controls
called myField.

Change it to

} else {

and delete the last else block.

[snip]

You need to check for similar mistakes in the other functions.

There are only a couple of other comments.

> function insertAtCursorLink (myField) {


[snip]

> range.text = '<a href=\"' + address + '\">' + range.text + '<\/a>';


You don't need to escape those double quotes. Writing

'" "' or "' '"

is fine. It's

'' '' or "" ""

where the inner pair of quotes needs to be escaped:

'\' \'' or "\" \""

[snip]

> function insertAtCursorImage (myField) {


[snip]

> address = '<img src=\\\"' + address + '\\\">';


That would produce

<img src=\"...\">

which is invalid. Again, the escaping backslashes aren't needed.

[snip]

> <form method="post" action="#">


action=""

will post back to the same page. Note that while IE handles this fine, it
can't, for some reason, interpret

<a href="">

correctly.

[snip]

> <textarea id='dog' name='dog'>Type something here, damnit</textarea>


You can omit the id attribute here as you don't need it.

[snip]

From your other post.

> document.forms[0].elements[this]


You might want to remind yourself of the last post I made in your "Check
if key is defined in associative array" thread. I pointed out that the
expression inside square brackets is converted to a string before it is
looked-up.

In the expression above, the this operator refers to an INPUT element.
When that is converted to a string, IE will attempt to find '[object]',
and better browsers will try to find '[object HTMLInputElement]'.
Obviously, that won't match any of the controls in your form, which is why
it failed.

Mike

--
Michael Winter
Replace ".invalid" with ".uk" to reply by e-mail.
 
Reply With Quote
 
lawrence
Guest
Posts: n/a
 
      12-01-2004
"Michael Winter" <(E-Mail Removed)> wrote in message
> The best you can do is shorten the reference from
> document.forms[0].elements['textarea-name-or-id']
> to
> this.form.elements['textarea-name-or-id']
> in the onclick attributes.


This is how I referenced it all year but I was hoping for something
simpler. I've gone back to it now.

Thanks much for all the help with the javascript code. This is going
into some open source code. Do you want your name mentioned in the
credits for advice with javascript?





> > } else if (myField && myField.selectionStart) {

>
> A better test would be
>
> } else if('number' == typeof myField.selectionStart) {
>
> which would succeed if the selection started at offset zero. You don't
> need to test for myField as you know that will exist (you passed it!).


Good point. I find the syntax of typeof to be strange. If it was
typeof() with parenthesises I'd have an easier time with it. Is it a
function? Or is it a type of casting? A casting test?





> > // MOZILLA/NETSCAPE support
> > // myField.value.substring(myField.selectionStart,
> > myField.selectionEnd)
> > var startPos = myField.selectionStart;
> > var endPos = myField.selectionEnd;
> > var elementName = myField.id;

>
> This is where the silliness begins. You have the element - you don't need
> the id. Delete that line.


Done.







> > } else {
> > alert("You haven't selected any text to change.");
> > }
> > } else if (document.forms[0].myField) {

>
> This looks for the field named (or identified as) myField in the first
> form in the document. That will fail every time as you have no controls
> called myField.
>
> Change it to
>
> } else {
>
> and delete the last else block.


Good point. I changed it to just:

} else {
myField.value += '<' + tag + '>' + range.text + '<\/' + tag +
'>';
}

But is there any way I can test and find out if a browser will allow
me to add text to a textarea? If the operation fails I'd like to tell
the user that something is wrong. Otherwise they will sit there
clicking the button and wondering if something is supposed to happen.






> > function insertAtCursorLink (myField) {

> [snip]
> > range.text = '<a href=\"' + address + '\">' + range.text + '<\/a>';

> You don't need to escape those double quotes.


It's all escaped in the end. It get sent to the screen by the print()
function in PHP. The code was all escaped and I unescaped the portion
I wanted to ask questions about because I thought the escapes would be
confusing on comp.lang.javascript. I didn't un-escape the code that I
wasn't asking about. Sorry about posting it.




> > <form method="post" action="#">

> action=""
> will post back to the same page. Note that while IE handles this fine, it
> can't, for some reason, interpret
> <a href="">
> correctly.


Right. Sorry, I should have offered more context. The little demo I
offered was for debugging purposes only. In the final product PHP sets
the action of the from correctly.



> [snip]
>
> > <textarea id='dog' name='dog'>Type something here, damnit</textarea>

>
> You can omit the id attribute here as you don't need it.


It's the name that I use here then?

this.form.name

I need the id to reference the item to Javascript, don't I?



> From your other post.
>
> > document.forms[0].elements[this]

>
> You might want to remind yourself of the last post I made in your "Check
> if key is defined in associative array" thread. I pointed out that the
> expression inside square brackets is converted to a string before it is
> looked-up.
>
> In the expression above, the this operator refers to an INPUT element.
> When that is converted to a string, IE will attempt to find '[object]',
> and better browsers will try to find '[object HTMLInputElement]'.
> Obviously, that won't match any of the controls in your form, which is why
> it failed.


Thanks again much for your help.
 
Reply With Quote
 
Michael Winter
Guest
Posts: n/a
 
      12-01-2004
On 30 Nov 2004 23:08:41 -0800, lawrence <(E-Mail Removed)> wrote:

[snip]

> Thanks much for all the help with the javascript code.


You're welcome.

> This is going into some open source code. Do you want your name
> mentioned in the credits for advice with javascript?


I'm not particularly bothered either way. If you think I've helped you
sufficiently to deserve it, please yourself, but I won't mind if you
don't.

[snip]

> I find the syntax of typeof to be strange. If it was typeof() with
> parenthesises I'd have an easier time with it. Is it a function? Or is
> it a type of casting? A casting test?


It's a unary (one argument) operator like new and logical NOT (!). You can
use parentheses, but it does nothing special, just the usual precedence
modifications. For example, the expression

typeof identifier == 'string'

would apply the typeof operator to the variable, identifier, obtaining the
type *as* a string, and compare it to the string literal, 'string'. It
could also be written as:

typeof (identifier) == 'string'

Alternatively, the expression

typeof (identifier == 'string')

would first evaluate the comparison, then obtain the type that results
from that comparison. As this form of comparison[1] always evaluates to
true or false, the typeof operator would always yield 'boolean'.

The reason that parentheses are not usually used with operators like
typeof is to actually avoid confusion: they aren't functions, so they
shouldn't be made to look like functions. If you do want to add
parentheses, go ahead, but don't forget what you're actually using.

[snip]

> But is there any way I can test and find out if a browser will allow me
> to add text to a textarea?


If the browser can be scripted, it's probably fair to say it will always
perform one of the code paths. The modification of a form control value is
a fairly basic operation. It may fail in ancient browsers, but we're
talking pre-IE4/NN4.

> If the operation fails I'd like to tell the user that something is
> wrong. Otherwise they will sit there clicking the button and wondering
> if something is supposed to happen.


You should consider that for users that have no scripting ability at all.
It might be a good idea to dynamically add the buttons so that they won't
exist should scripting be disabled.

[snip]

[lawrence, then me:]
>>> <textarea id='dog' name='dog'>Type something here, damnit</textarea>

>>
>> You can omit the id attribute here as you don't need it.

>
> It's the name that I use here then?
>
> this.form.name
>
> I need the id to reference the item to Javascript, don't I?


No, not in this case. The TEXTAREA element is contained in a form so you
can use the name to get the reference:

formObj.elements['name']

Good luck,
Mike


[1] Equality (==) and strict equality (===) operations always yield a
boolean. However, if one of the arguments in a relational (<, >, etc)
comparison is NaN when converted to a number, the result will be undefined.

--
Michael Winter
Replace ".invalid" with ".uk" to reply by e-mail.
 
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
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
Running a specific test in a test file. Hunt Jon Ruby 1 12-15-2008 01:38 PM
Is there a way to find the class methods of a class, just like'methods' finds the instance methods? Kenneth McDonald Ruby 5 09-26-2008 03:09 PM
object-like macro used like function-like macro Patrick Kowalzick C++ 5 03-14-2006 03:30 PM
test test test test test test test Computer Support 2 07-02-2003 06:02 PM



Advertisments