Command works as html but not as DOM

A

Andrew Poulos

While this works on IE 6:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>aiff</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<script language="JavaScript" type="text/javascript">
//<![CDATA[
function playMedia() {
document.getElementById("objMedia").Play();
}
//]]>
</script>
</head>

<body>
<object id="objMedia"
style="visibility:hidden;"
classid="CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95"

codebase="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,4,5,715"
type="application/x-oleobject">
<param name="FileName" value="media/aif_sample.aif">
<param name="AutoStart" value="false">
</object>

<div onclick="playMedia();" style="position:absolute; left:475px;
top:242px; width:89px; height:25px; background-color: #00FFFF;">Play</div>
</body>
</html>


that is when I click the div the audio plays, the following DOM-based
code doesn't:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>aiff</title>
<script type="text/javascript">
//<![CDATA[
window.onload = function() {
var audObj = document.createElement("object");

audObj.setAttribute("id", "objMedia");
audObj.setAttribute("classid"," ...[clipped]... ");
audObj.setAttribute("codebase"," ...[clipped]... " );
audObj.setAttribute("type","application/x-oleobject");

var audParam = document.createElement("param");
audParam.setAttribute("name","FileName");
audParam.setAttribute("value","media/aif_sample.aif");
audObj.appendChild(audParam);

audParam = document.createElement("param");
audParam.setAttribute("name","AutoStart");
audParam.setAttribute("value","false");
audObj.appendChild(audParam);

document.body.appendChild(audObj);
}
function playMedia(med) {
document.getElementById("objMedia").Play();
}
//]]>
</script>
</head>

<body>
<div onclick="playMedia();" style="cursor:pointer; position:absolute;
left:475px; top:242px; width:89px; height:25px; background-color:
#00FFFF;">Play</div>
</body>
</html>


The page appears as I expect it would. There are no errors returned but
the audio never starts playing. Doing an alert on the id "objMedia"
returns Object.

If I edit the code to reflect settings that MZ would recognise then it
plays in MZ.

Why does IE refuse to start the audio?

Andrew Poulos
 
A

Andrew Poulos

Andrew said:
While this works on IE 6:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>aiff</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<script language="JavaScript" type="text/javascript">
//<![CDATA[
function playMedia() {
document.getElementById("objMedia").Play();
}
//]]>
</script>
</head>

<body>
<object id="objMedia"
style="visibility:hidden;"
classid="CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95"

codebase="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,4,5,715"

type="application/x-oleobject">
<param name="FileName" value="media/aif_sample.aif">
<param name="AutoStart" value="false">
</object>

<div onclick="playMedia();" style="position:absolute; left:475px;
top:242px; width:89px; height:25px; background-color: #00FFFF;">Play</div>
</body>
</html>

[clipped]

Further to this, if I use innerHTML then it also 'works':


<script type="text/javascript">
//<![CDATA[
window.onload = function() {
var str = "<object id='objMedia' ";
str += "style='visibility:hidden;' ";
str += "classid='...[clipped]...' ";
str += "codebase='...[clipped]...' ";
str += "type='application/x-oleobject'>";
str += "<param name='FileName' value='media/aif_sample.aif'>";
str += "<param name='AutoStart' value='false'>";
str += "</object>";

// I first created an empty div in the html with id 'med'
document.getElementById("med").innerHTML = str;

function playMedia() {
document.getElementById("objMedia").Play();
}
}
//]]>
</script>


Why is the DOM technique failing in IE?

Andrew Poulos
 
M

Michael Winter

[snip]
<script type="text/javascript">
//<![CDATA[

Marked sections are of no value in HTML as user agents don't parse it as
SGML, so changing </ in a string literal to <\/ is still necessary. You
can use it in XHTML but don't use comments unless you're serving the page
as HTML[1].

However, script hiding should be avoided. Just put the script in an
external file.

[snip]
Why is the DOM technique failing in IE?

Possibly because you're using setAttribute[2]. Unless you're scripting
XHTML documents, use the shortcut properties which the DOM HTML module
exposes.

Mike


[1] In which case, why the heck aren't using HTML anyway? Serving
XHTML as HTML is a waste of effort.
[2] Microsoft's implementation of setAttribute is broken anyway. The
interface is completely different and to set the class attribute,
you must pass 'className' as the attribute name. That should only
be necessary when setting the class attribute using the shortcut
property. It's interesting to note though that Microsoft still
try to imply that they're following the W3C DOM.
 
A

Andrew Poulos

Michael said:
[snip]
<script type="text/javascript">
//<![CDATA[


Marked sections are of no value in HTML as user agents don't parse it
as SGML, so changing </ in a string literal to <\/ is still necessary.
You can use it in XHTML but don't use comments unless you're serving
the page as HTML[1].

This is where I get confused. I've seen <!-- and --> used but someone
said that this hasn't been necessary since Netscape 2. And often when I
see code samples posted I see //<![CDATA[ used.
However, script hiding should be avoided. Just put the script in an
external file.

As soon as I get the script working I'll move it into an external file.
[snip]
Why is the DOM technique failing in IE?

Possibly because you're using setAttribute[2]. Unless you're scripting
XHTML documents, use the shortcut properties which the DOM HTML module
exposes.

Mike


[1] In which case, why the heck aren't using HTML anyway? Serving
XHTML as HTML is a waste of effort.

I thought I'd set the doctype as HTML 4 Strict???
[2] Microsoft's implementation of setAttribute is broken anyway. The
interface is completely different and to set the class attribute,
you must pass 'className' as the attribute name. That should only
be necessary when setting the class attribute using the shortcut
property. It's interesting to note though that Microsoft still
try to imply that they're following the W3C DOM.

Thanks for the advice but I'm unclear as to what you mean by "shortcut
properties which the DOM HTML module exposes". The only shortcuts I know
of are in CSS.

Andrew Poulos
 
M

Martin Honnen

Andrew said:
Michael said:
On Tue, 21 Dec 2004 16:42:56 +1100, Andrew Poulos

[snip]
<script type="text/javascript">
//<![CDATA[



Marked sections are of no value in HTML as user agents don't parse it
as SGML, so changing </ in a string literal to <\/ is still
necessary. You can use it in XHTML but don't use comments unless
you're serving the page as HTML[1].


This is where I get confused. I've seen <!-- and --> used but someone
said that this hasn't been necessary since Netscape 2. And often when I
see code samples posted I see //<![CDATA[ used.

In HTML documents there was in ancient times when there were browsers
like Netscape 2 (which supported the <script> element) and for instance
Mosaic (which did not support the <script> element) around a need to
hide script code from the browsers like Mosaic so for embedded script
you had to use
<script language="JavaScript"><!--


//--></script>
to ensure that browsers like Mosaic that treated <script> as an unknown
element don't render the script code on the page.
However the <script> element is part of the HTML 4.01 specification, and
even HTML 3.2 in
<http://www.w3.org/TR/REC-html32#script>
already says:
---- quotation ----------------------------
<!ELEMENT STYLE - - CDATA -- placeholder for style info -->
<!ELEMENT SCRIPT - - CDATA -- placeholder for script statements -->

These are place holders for the introduction of style sheets and
client-side scripts in future versions of HTML. User agents should hide
the contents of these elements.
---- end of quotation ---------------------
so browsers or user agents since HTML 3.2 need to support the <script>
element and need to hide the script code without any need for script
authors to wrap the script code into SGML comments (i.e. <-- -->).
Of course for some time there was a need to still cater for old user
agents not supporting <script> but for years now such user agents are
extinct so if you write embedded script code in a HTML document nowadays
there is no need to use a comment wrapper around the script code.

As for //<![CDATA[ //]]> as a wrapper for script code, that is something
that has other reasons, it is certainly not necessary or helpful if you
write documents according to the HTML 4.01 specification. That construct
is (often) necessary if you want to author XHTML 1.0 and serve those
documents to HTML user agents with the content type text/html as then
you have to obey both X(HT)ML and HTML rules, to use a '<' character in
your embedded script code e.g.
for (var i = 0; i < whatever.length; i++)
and to have well-formed XML you need a CDATA wrapper e.g.
<script type="text/javascript"><![CDATA[
for (var i = 0; i < whatever.length; i++) { }
]]></script>
as otherwise you break XML rules, but as the CDATA wrapper is not
understood by HTML user agents you need to hide it in a script comment
so you end up with
<script type="text/javascript">
//<![CDATA[
for (var i = 0; i < whatever.length; i++) { }
//]]></script>
to obey to both XML and HTML rules.
That whole approach is tedious, one of the many things that make writing
XHTML 1.0 backwards compatible to HTML browsers tedious and error prone
while XHTML 1.0 doesn't offer anything for document authors that HTML
4.01 doesn't have so you will find many regulars in this group or a HTML
group that suggest to stick with HTML 4.01, see
<http://www.hut.fi/u/hsivonen/xhtml-the-point>
<http://www.hixie.ch/advocacy/xhtml>
 
M

Michael Winter

[snip]
This is where I get confused. I've seen <!-- and --> used but someone
said that this hasn't been necessary since Netscape 2. And
often when I see code samples posted I see //<![CDATA[ used.

The reason for using SGML comment delimiters (<!-- -->) within both SCRIPT
and STYLE elements in the past was that old browser didn't understand what
they were. As the HTML Specification states that browsers should render
the contents of any unrecognised elements, you ended up with pages showing
code. To solve this you could do two things:

1) Move the script to an external file.
2) Wrap it in comments.

As I understand it, every current user agent (UA) does recognise SCRIPT
and STYLE elements, even if they can't do anything with them, so script
hiding is unnecessary. Furthermore, if you decided to move to XHTML (if
that becomes viable in the future), you'd have a bigger problem: the
script would be ignored entirely. The comments would be treated literally,
hiding the code even from capable browsers.

Marked sections have a different purpose: they instruct the UA to treat
the content in some way. In the case of <![CDATA[...]]>, it basically
instructs the UA to ignore any tags. This would mean you could write

<script type="text/javascript">
<![CDATA[
var myString = '<a href="...">...</a>';
]]>
</script>

rather than

<script type="text/javascript">
var myString = '<a href="...">...<\/a>'; // Notice the backslash
</script>

without worrying about the link being treated as an element, or the ETAGO
(</) being thought of as the end of the SCRIPT element[*]. Again, moving
the script to an external file is another way around this.

As I said previously, marked sections are useless in HTML as *very* few
browsers (if any at all) treat HTML as SGML. You'd just end up causing a
syntax error.

[snip]
[1] In which case, why the heck aren't using HTML anyway?
Serving XHTML as HTML is a waste of effort.

I thought I'd set the doctype as HTML 4 Strict???

You did. It was just an aside. Sorry for the confusion there.

[snip]
Thanks for the advice but I'm unclear as to what you mean by "shortcut
properties which the DOM HTML module exposes". The only
shortcuts I know of are in CSS.

All of the standard attributes for HTML elements are exposed to HTML
documents as properties. So, rather than writing

myLink.setAttribute('href', '...');

you can write

myLink.href = '...';

The DOM HTML specification (<URL:http://www.w3.org/TR/DOM-Level-2-HTML>)
lists all of the members for HTML elements.

As far as I can remember, only the class attribute is an oddity. As many
languages reserve the keyword 'class' (including ECMAScript), it was
changed to className. So:

myElement.setAttribute('class', '...');

becomes

myElement.className = '...';

though as I noted last time, the first version wouldn't work in IE anyway
as it requires className for both[+].

Hope that helps,
Mike


[*] I don't think anyone's aware of a browser that does this, but
it's considered a safe practice and avoids HTML validation errors
for inline scripts.
[+] It's reasonable to assume that in every case, IE maps

myElement.setAttribute(name, value)

to

myElement[name] = value;
 
A

Andrew Poulos

Michael said:
This is where I get confused. I've seen <!-- and --> used but someone
said that this hasn't been necessary since Netscape 2. And
often when I see code samples posted I see //<![CDATA[ used.

The reason for using SGML comment delimiters (<!-- -->) within both
SCRIPT and STYLE elements in the past was that old browser didn't
understand what they were. As the HTML Specification states that
browsers should render the contents of any unrecognised elements, you
ended up with pages showing code. To solve this you could do two things:

Thanks for clearing this, and thanks to Martin Honnen.
[+] It's reasonable to assume that in every case, IE maps

myElement.setAttribute(name, value)

to

myElement[name] = value;
I tried it but a line that reads:

audObj.type = "application/x-oleobject"
or
audObj["type"] = "application/x-oleobject"

cause IE 6 to complain about trying to set a property (that can't be
set) at runtime.

It did, though, get me thinking and I wondered if IE could only add an
attribute to an element that was actually appended to the document and
not just created. So I moved the setting of the attributes of the
'object' element to after the point where its appended and it worked -
although I still did have to use a 'shortcut' for the style attribute:

<script type="text/javascript">
var audObj;

window.onload = function() {
audObj = document.createElement("object");

var audParam = document.createElement("param");
audParam.name = "FileName";
audParam.value = "media/aif_sample.aif";
audObj.appendChild(audParam);

audParam = document.createElement("param");
audParam.name = "AutoStart";
audParam.value = "false";
audObj.appendChild(audParam);

document.body.appendChild(audObj);

audObj.id = "objMedia";
audObj.style.visibility = "hidden";
audObj.classid = "CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95";
audObj.codebase = "...[clipped]...";
audObj.setAttribute("type","application/x-oleobject");

document.getElementById("play").onclick = function() {
audObj.Play();
}
}
</script>


While it working is good I'm disturbed that:
a. moving setting of the attributes for 'object' works but if I also do
it for 'param' I get errors,
b. I don't know why its working.


Andrew Poulos
 
M

Michael Winter

[snip]
audObj.type = "application/x-oleobject"
or
audObj["type"] = "application/x-oleobject"

cause IE 6 to complain about trying to set a property (that can't be
set) at runtime.

What? Would it be possible to put a small demo online? IE didn't complain
when I assigned to the type attribute, but perhaps it's because I'm not
doing precisely what you are.
It did, though, get me thinking and I wondered if IE could only add an
attribute to an element that was actually appended to the
document and not just created.

Usually, the opposite is necessary. However, that only tends to apply to
properties that are marked as read-only: they can be written to (sometime
only once) when they're created, but only read once they've been added.
The type property is read/write at any time.

[snip]
I still did have to use a 'shortcut' for the style attribute:

You would. The style property is an object, and its properties represent
what's specified in the style attribute.
<script type="text/javascript">
var audObj;

Any reason why that's global? The code you posted doesn't require it.

[snip]
audObj.classid = "CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95";

For some bizarre reason, the DOM doesn't define a property for that
attribute. You probably could use what you have above, or you might see if
the data attribute/property gives the same result.
audObj.codebase = "...[clipped]...";

The 'b' in codebase must be capitalised.

[snip]

Mike
 
A

Andrew Poulos

Michael said:
[snip]
audObj.type = "application/x-oleobject"
or
audObj["type"] = "application/x-oleobject"

cause IE 6 to complain about trying to set a property (that can't be
set) at runtime.

What? Would it be possible to put a small demo online? IE didn't
complain when I assigned to the type attribute, but perhaps it's
because I'm not doing precisely what you are.

Here's a link to one that works in IE 6:
<url>http://members.iinet.net.au/~apoulos/fre/fre.html</url>

and one that pops up an error (with the script debugger installed):
Usually, the opposite is necessary. However, that only tends to apply

Yes, for me it is only an IE thing.
to properties that are marked as read-only: they can be written to
(sometime only once) when they're created, but only read once they've
been added. The type property is read/write at any time.

[snip]
<script type="text/javascript">
var audObj;

Any reason why that's global? The code you posted doesn't require it.

Nope, I was wrong.
For some bizarre reason, the DOM doesn't define a property for that
attribute. You probably could use what you have above, or you might see
if the data attribute/property gives the same result.

Both worked OK.
audObj.codebase = "...[clipped]...";

The 'b' in codebase must be capitalised.

Really? I just tried it and it didn't seem to make any difference.


Andrew Poulos
 
M

Michael Winter

[snip]
Here's a link to one that works in IE 6:
<url>http://members.iinet.net.au/~apoulos/fre/fre.html</url>

The URL delimiter should be written as <URL:...>. So the URL above should
be

<URL:http://members.iinet.net.au/~apoulos/fre/fre.html>

What you wrote caused the "</url" part to be included. Anyway...

That page doesn't "work", it just doesn't error. If you check the type
attribute after you attempt to set it with setAttribute, you'll get an
empty string - the operation failed.
and one that pops up an error (with the script debugger installed):
<url>http://members.iinet.net.au/~apoulos/fre/fre2.html</url>

I've played with this code for quite a while now and have a solution. I'll
go through the various issues one at a time.

1) You do need to set the classid attribute, so just use what you
have so far (obj.classid = '...';) to do that.
2) In order for the PARAM elements to be used, you need to add them
to the OBJECT *before* you set any of the OBJECT element's
attributes. Alternatively, set the media player properties
programatically:

obj.AutoStart = false;
obj.FileName = '...'; // or obj.Open('...') asynchronously

(in that order!)
3) Ignore the type attribute. You will *not* be able to set it. From
what I found whilst playing, the type attribute can only be set
from code if the value is of a limited subset of MIME types, and
even then, the permitted types depend on the other attributes of
the element.

[snip]
Both worked OK.

No, they don't. If you keep the OBJECT element visible, you'll see that
the interface only appears if classid is set.

[snip]
Really? I just tried it and it didn't seem to make any difference.

That's because *you* don't need it. The attribute is only needed if the
user doesn't have the necessary control installed on their machine. Anyone
with Windows '98 SE (or later) should have the Windows Media Player 6.4
control (according to Microsoft's documentation). The 'b' does need to be
capitalised. :)

My final comment is that when you add the OBJECT element in those demos,
you add them directly to the BODY element. That would create an invalid
document tree as only block or SCRIPT elements may be children of the BODY
element under a Strict DTD. Don't forget that DOM operations must still
conform to the rules of the mark-up your document uses.

Hope that helps,
Mike
 
A

Andrew Poulos

Michael Winter wrote:

I've played with this code for quite a while now and have a solution.
I'll go through the various issues one at a time.

Thanks for spending the time.
1) You do need to set the classid attribute, so just use what you
have so far (obj.classid = '...';) to do that.
2) In order for the PARAM elements to be used, you need to add them
to the OBJECT *before* you set any of the OBJECT element's
attributes. Alternatively, set the media player properties
programatically:

obj.AutoStart = false;
obj.FileName = '...'; // or obj.Open('...') asynchronously

(in that order!)

I'm using the method 1) but I've found that I can only add attributes to
OBJECT after I've appended OBJECT.
3) Ignore the type attribute. You will *not* be able to set it. From
what I found whilst playing, the type attribute can only be set
from code if the value is of a limited subset of MIME types, and
even then, the permitted types depend on the other attributes of
the element.
Ok.


No, they don't. If you keep the OBJECT element visible, you'll see that
the interface only appears if classid is set.

You're right, I shouldn't have doubted.

My final comment is that when you add the OBJECT element in those
demos, you add them directly to the BODY element. That would create an
invalid document tree as only block or SCRIPT elements may be children
of the BODY element under a Strict DTD. Don't forget that DOM
operations must still conform to the rules of the mark-up your document
uses.

Good point.
Hope that helps,

Yes it helps a lot.


Andrew Poulos
 

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,994
Messages
2,570,223
Members
46,814
Latest member
SpicetreeDigital

Latest Threads

Top