分享

漫话ID(上)——Name和ID的种种

 趋明 2012-03-15
 
http://www. 2009年03月04日 博客园 Aaron Wu

  页面元素中的ID这东西想必很多人都用过,在JavaScript函数中也经常要用到document.getElementById()这个方法来定位一个元素并操作它。在Web自动化测试中,我们也经常用到元素的id来定位元素,这样看起来id是个好玩意儿。

  在之前的一篇文章Selenium IDE实践中,Selenium录制的脚本中有下面这一段代码:

        [Test]
        public void TheNewTest()
        {
            selenium.Open("http://www.google.cn/");
            Assert.AreEqual("Google", selenium.GetTitle());
            selenium.Type("q", "Selenium 介绍");
            selenium.Click("btnG");
            selenium.WaitForPageToLoad("30000");
            Assert.AreEqual("Selenium 介绍 - Google 搜索", selenium.GetTitle());
            try
            {
                Assert.IsTrue(selenium.IsTextPresent("图片、新闻搜索"));
            }
            catch (AssertionException e)
            {
                verificationErrors.Append(e.Message);
            }
        }

   注意Aaron做了标记的那两行的两个方法,Selenium.Type()方法顾名思义是向某个控件输入内容的,看着Aaron的例子应该会明白第二个参数是输入的内容,那么第一个参数想必是控件的属性了。对,第一个控件是google搜索页面那个我们经常使用的输入框,如果我们用IE Developer Toolbar来查看该文本输入框,可以看到下面的内容:

<input title="Google 搜索" maxLength="2048" size="55" name="q" autocomplete="off"/>

  同样我们Selenium.Click的btnG则是Google页面上那个“Google Search”按钮的name

<input title="Google Search" maxLength="2048" size="55" name="q" autocomplete="off"/>

  这里面google使用的是元素的name属性,对应于document.getElementsByName()方法,也是定位元素的一种方法。下面问题来了,Name与ID有什么关系呢?

   话说表单的name与id其实是同一个意思,都是为了标记对象名称。它们所不同的是:name是Netscape的、id是Microsoft的,这种说法到底准不准确我们暂且不论,我们更关心的是怎么用好这两个东西。

  有总结如下:

  Name用作表单(form)的控件名,提交的数据都用控件的name而不是id来控制。因为有许多name会同时对应多个控件,比如checkbox和radio,而id必须是全文档中唯一的。此外浏览器会根据name来设定发送到服务器的request。如果用id,服务器无法得到数据的。Name还可以用于在其他frame或window指定target。对于name来讲,它有很多用途,不能完全由ID来代替。关于name的用途相关内容建议参看文末引用1原帖及帖下的热烈讨论。

  ID:根据HTML 4.0 的定义,除 BASE, HEAD, HTML, META, SCRIPT, STYLE, TITLE 标签外,id 都可用,包括了Body li a table tr td th p div span pre dl dt dd font b等.另外ASP.net进程在处理aspx页面时不允许有ID非唯一,这时页面会抛出异常。

漫话ID(上)——Name和ID的种种

  图片看不清楚?请点击这里查看原图(大图)。

  如果不是动态页面,我们是能成功在页面中加入多个相同的ID的,此时ID已经自动变成了数组, document.getElementById仍然有效,不过只拿到第一个。关于ID的作用也不在本文讨论了,相关内容可以参见引用2.

   其他需要注意的地方:id要符合标识的要求,比如大小写敏感,最好不要包含下划线(不兼容CSS)。而name基本上没有什么要求,甚至可以用数字。name主要用于动态网页,表单提交给某个服务器端脚本后接收变处理量使用。从源代码的规范性和兼容性角度出发,如在客户端脚本里要索引某个对象,建议用document.getElementById()方法,尽量不要直接使用NAME的值。有些标签是可以同时有name和id的,现在根据规范,建议用id来标识元素。

   下面给出Aaron找到的一个比较好的例子来说明一些问题(Aaron验证了其中的内容,并附加了Aaron版测试代码)。

  假设有了如下的html文档:

<form method="post" action="" name="testform">
<input type="text" name="textname" id=“textid” value="DEMO" />
</form>

  在IE浏览器里,我们可以通过下面的方法引用文本框:

   1:textname

   2:testform.textname

   3:document.all.textname

   4:document.all.demoform.textname

   5:document.forms[0].textname

   6:document.forms["testform"].textname

    7:document.forms["testform"].childNodes[0]

   8:document.forms["testform"].elements[0]

   9:document.getElementById("textid")

   10: document.getElementsByName("textname")[0]

  测试结果:

 

  IE 6

  IE 7

  IE 8 RC1

  FF 2.0

  FF 3.1b2

  结果为Null或Undefine的方法

  1

  1

  1

  1

  1

  注:在引用2原文中作者测试在IE6下方法1可通过,但Aaron的结果与之不一致,因此读者需要自己验证。同时在引用2中作者指出方法7会返回undefined,但Aaron在自己的测试环境中方法七也可以得到结果。原文中作者指出:第3、4种方法用到了document.all这个IE专有对象,FF3.0虽然返回了正确的值,不过却在控制台里发出了警告:非标准的属性 document.all。请使用 W3C 的标准形式 document.getElementById() 。

  测试2:在测试1的脚本头加入下列信息

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www./TR/html4/loose.dtd">

  测试结果:

 

  IE 6

  IE 7

  IE 8 RC1

  FF 2.0

  FF 3.1b2

  结果为Null或Undefine的方法

  1

  1

  1

  1

  2

  3

  4

  1

  2

  3

  4

  引用2中作者的测试结果中方法2 可以在FF2和FF3下运行通过,但在Aaron的机器上无法通过,另方法1在仍然未通过。 

   后记:本章中介绍的大部分内容都是Aaron从网络上摘录并添加了主要来源的引用链接,本文是Aaron在准备另外一篇文章过程中对积攒的资料的整理,错误纰漏之处请尽快提出,以防Aaron误人子弟~

  附:Aaron版简易测试脚本

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www./TR/html4/loose.dtd">
<html>
<head>
<title>Test ID & Name</title>
<script>
function getobject()
{
    alert("Begin~");
    //alert("1:textname——"+textname);
    //alert("2:testform.textname——"+testform.textname);
    //alert("3:document.all.textname——"+document.all.textname);
    //alert("4:document.all.demoform.textname——"+document.all.testform.textname);
    alert("5:document.forms[0].textname——"+document.forms[0].textname);
    alert("6:document.forms["testform"].textname——"+document.forms["testform"].textname);
    alert("7:document.forms["testform"].childNodes[0]——"+document.forms["testform"].childNodes[0]);
    alert("8:document.forms["testform"].elements[0]——"+document.forms["testform"].elements[0]);
    alert("9:document.getElementById("textid")——"+document.getElementById("textid"));
    alert("10:document.getElementById("textid")——"+document.getElementsByName("textname")[0]);
}
</script>
</head>
<body onload="getobject()">
<form method="post" action="" name="testform">
<input type="text" name="textname" id="textid" value="this is just for testing" />
</form>
</body>
</html>

 

  引用1:

  http://www.cnblogs.com/birdshome/archive/2005/01/31/html_id_name.html  (已与原作者联系并取得引用许可,感谢ing~)

  引用2:(Aaron无法保证均为原始链接,仅为Aaron实际引用的地址,如原作者有异议请尽快与Aaron联系以督促更改。)

  http://www.jb51.net/article/15300.htm

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多