js通过id获取元素的值(js查找元素的方法)

本内容是《Web前端开发之Javascript视频》的课件,请配合大师哥《Javascript》视频课程学习。

Document 接口描述了任何类型的文档的通用属性与方法,根据不同的文档类型(例如HTML、XML)提供了不同的API,比如,使用 “text/html” 作为内容类型的HTML文档,实现了 HTMLDocument,而XML文档则实现了XMLDocument,HTMLDocument和XMLDocument接口都是继承自Document接口;

Javascript通过Document类型表示文档;在浏览器中,document对象是Document的一个实例,更具体一点,是HTMLDocument的一个实例,其表示整个HTML页面;并且document对象也是window对象的一个属性,可以将其作为全局对象来访问;因此document对象,既属于BOM又属于DOM的对象;

Document节点的特征:

  • nodeType的值为9
  • nodeName的值为#document
  • nodeValue的值为null
  • parentNode的值为null

其子节点可能是一个DocumentType(最多一个)、Element(最多一个,即html)、ProcessingInstruction或Comment;

console.log(document);  // 在FF控制台可以看出是属于HTMLDocument类型console.log(document.nodeType); // 0console.log(document.nodeName); // #documentconsole.log(document.nodeValue);  // nullconsole.log(document.parentNode);  // nullconsole.log(document.childNodes.length);  // 2

文档的子节点:

DOM标准规定Document节点的子节点可以是DocumentType、Element、ProcessingInstruction或Comment;

<!-- 这是一个comment --><html lang=\"en\"><head>    <title>Document</title></head><body><script>console.log(document.childNodes); // 使用FF查看 NodeList(3)</script></body></html>

documentElement属性:

返回文档直接子节点,始终指向HTML页面中的<html>元素,也就是文档的根元素,并且它一定是文档的根元素;

// 注意:在HTML中的第二行有可能是注释console.log(document.childNodes[2]);  // <html>console.log(document.documentElement);  // <html>console.log(document.lastChild);  // <html>

借助这个只读属性,能方便地获取到任意文档的根元素;

body属性:

作为HTMLDocument的实例,document对象还有一个body属性,直接指向<body>;

console.log(document.body);

对于一个拥有<frameset>元素的文档来说,返回的是最外层的<frameset>元素;

另外,该属性是可写的,且为该属性赋的值必须是一个<body>元素;

// 如果HTML结构为body id=\"oldBody\",则:console.log(document.body.id);  // oldBodyvar newBody = document.createElement(\"body\");newBody.id = \"newBody\";document.body = newBody;console.log(document.body.id);  // newBody

head属性:

指向<head>元素,这个Document对象扩展的一个属性,类型为HTMLHeadElement;

如果有多个<head>元素,则返回第一个;

document.head 是个只读属性,为该属性赋值只会静默失败,如果在严格模式中,则会抛出TypeError异常;

需要注意的是,如果文档源代码中未显式的包含<head>和<body>元素,浏览器将隐式的创建它们;

doctype属性:

该属性是DocumentType 类型,表示了一个包含文档类型的节点对象,指向<!DOCTYPE>标签;

文档当中最多只有一个DocumentType元素;

console.log(document.doctype);  // <!DOCTYPE html>console.log(document.doctype.nextSibling); // <html>console.log(document.childNodes[0]); // <!DOCTYPE html>

如果存在文档声明,则将其作为document的第一个子节点,解析DOCUMENTTYPE_NODE类型,如果没有声明,则为null;

注:DocumentType对象不能动态创建,它是只读的;

查找元素(选取文档元素):

在DOM中,取得特定的某个或某组元素,并执行一些操作,这是最重要的应用了;

为了获取文档中的这些元素Element对象,DOM定义了许多方式,如:用指定的id属性、name属性、标签名、CSS类或CSS选择器;

取得元素的操作可以使用document对象的几个方法来完成;Document类型为此提供了两个方法;

getElementById()方法:

该方法接收一个参数,即要获取的元素的ID;如果找到就返回这个元素,类型是HTMLElement,如果不存在,则返回null;该参数ID是区分大小写的;

如果页面中多个元素的ID值相同,只返回文档中第一次出现的元素;

var mydiv = document.getElementById(\"mydiv\");console.log(mydiv);可以封装一个通过ID查找多个元素的函数,如:/*** 函数接受任意多的字符串参数* 返回一个对象* 如果一个id对应的元素未定义,则抛出错误*/function getElements(/*ids...*/){    var elements = {};  // 一个空map映射对象    for(var i=0; i<arguments.length; i++){        var id = arguments[i];        var elt = document.getElementById(id);        if(elt == null)            throw new Error(\"No element with id:\" + id);        elements[id] = elt;    }    return elements;}console.log(getElements(\"mydiv\",\"mylist\"));console.log(getElements(\"mydiv\",\"mylist\")[\"mydiv\"]);

getElementById方法不会搜索不在文档中的元素;当创建一个元素,并且分配ID后,必须要使用appendChild、insertBefore等方法把元素插入到文档中,之后才能使用getElementById()方法获取到;

var elt = document.createElement(\"div\");elt.id = \"myelt\";document.body.appendChild(elt);  // myelt,添加到文档对后,才能被获取到到var el = document.getElementById(\"myelt\");console.log(el);  // null

getElementsByName()方法:

返回给定name 属性的所有元素NodeList集合对象;

var mytexts = document.getElementsByName(\"mytext\");console.log(mytexts); // dom2.html:17 NodeList(2) [p, div]

该方法定义在HTMLDocument类中,而不在Document类中,所以它只针对HTML文档可用,也就是只有HTMLDocument类型才有的方法,在XML文档中不可用;

<fieldset>    <legend>选择你最喜欢的城市</legend>    <ul>        <li><input type=\"radio\" value=\"北京\" name=\"city\" id=\"beijing\" />            <label for=\"beijing\">北京</label></li>        <li><input type=\"radio\" value=\"南京\" name=\"city\" id=\"nanjing\" />            <label for=\"nanjing\">南京</label></li>        <li><input type=\"radio\" value=\"蚌埠\" name=\"city\" id=\"bengbu\" />            <label for=\"bengbu\">蚌埠</label></li>    </ul></fieldset><script>var citys = document.getElementsByName(\"city\");console.log(citys);</script>

该方法返回的是NodeList对象,在NodeList中返回的元素按照在文档中的顺序排序的,所以可以使用方括号语法来取得每个元素;

console.log(document.getElementsByName(\"city\")[0]);

但IE与Edge返回的是HTMLCollection;但namedItem()方法是属于HTMLCollection类型的,所以,非IE调用namedItem()方法会抛出异常;并且在IE中namedItem()只会返回第一项,因为每一项的name特性都是相同的;

console.log(citys.namedItem(\"city\"));

为某些HTML元素设置name属性,将自动在windows对象中创建对应的属性,对Document对象也是类似的;比如,为<form>、<img>、<iframe>、<applet>、<embed>或<object>元素设置name属性,即在Document对象中创建以此name属性值为名字的属性;

<form name=\"myform\"></form><script>console.log(document.myform);</script>

即使如此,建议不要用这种方式来获取元素,最好还是显式的使用getElementsByName()方法;

getElementsByTagName()方法:

该方法是通过标签名来获取元素,其接收一个参数,即要取得元素的标签名;返回拥有零个或多个元素的HTMLCollection集合对象,其是动态集合,与NodeList非常类似;;

var spans = document.getElementsByTagName(\"span\");console.log(spans); // HTMLCollection

其拥有length属性,可以通过方括号或者item()方法来访问HTMLCollection对象中的项;还拥有一个namedItem()方法,该方法可以通过元素的name属性取得集合中的项,但可以简写为使用方括号访问;即如果是数值,则调用item(),如果是字符串索引,就调用namedItem();

var divs = document.getElementsByTagName(\"div\");console.log(divs);console.log(divs[0]);console.log(divs.item(1));console.log(divs.namedItem(\"innerDiv\"));console.log(divs[\"innerDiv\"]);console.log(images[0].src);images.item(1).src = \"images/3.jpg\";

如果传入“*”,则取得页面中所有元素;(在JS和CSS中,*就是匹配所有的通配符);

var nodes = document.getElementsByTagName(\"*\");console.log(nodes);

会打印出页面中所有的元素,按照它们出现的顺序(没有层次之分);

在HTML中,该方法参数不需要区分大小写,而在XML中,区分大小写;

Element类也定义了getElementsByTagName()方法,其原理和Document一样,但是它只选取调用该方法的元素的后代元素;

var mydiv = document.getElementById(\"mydiv\");// 也可以通过getElementsByTagName来获取// var mydiv = document.getElementsByTagName(\"div\")[0];var spans = mydiv.getElementsByTagName(\"span\");console.log(spans);

文档信息:

作为HTMLDocument的一个实例,document对象还有一些标准的Document对象所没有的属性;这些属性提供了document对象所表现的网页的一些信息;

从BOM角度来看document对象是window对象的属性,由一系列集合构成,这些集合可以访问文档的各个部分,并提供页面自身的信息,可以认为document即为加载的html文档;

document.title:包含着<title>元素中的文本,通过它,可以获取或修改当前页面的标题;

var originalTitle = document.title;console.log(originalTitle);document.title = \"zeronetwork title\";// 标题跑马灯效果var str=\"北京零点网络科技有限公司-\";document.title = str;function titleMove(){    str = str.substring(1,str.length) + str.substring(0,1);    document.title = str;}setInterval(\"titleMove()\",1000);

lastModified:返回文档被最后修改的日期和时间;

cookie:允许Javascript读写的HTTP cookie的特殊属性;

location:与window对象的location属性引用同一个Location对象;

URL:包含页面完整的URL;一般情况下,该属性的值与location.href 属性相同;但不包含Location对象的动态变化,即在 URL 重定向发生的时候,这个URL属性保存了文档的实际URL,不会发生变化,而 location.href会发生变化;location.href 是可写的,document.URL是只读的;

console.log(document.URL);console.log(location.href);document.URL = \"demo.html\";  // 无效console.log(document.URL);// location.href = \"demo1.html\";  // 跳转

referrer:来源页面的URL(链接到当前页面的那个页面),如果没有来源,referrer为空字符串;该属性是只读的;

console.log(document.referrer);

这个属性在分析网站SEO数据时特别有用;

var referrer = document.referrer;var origin = location.origin;console.log(referrer);console.log(origin);if(referrer){    if(referrer.indexOf(origin) == 0){        document.write(\"站内浏览\");    }else{        document.write(\"从外链:\" + referrer + \"进入\");    }}else{    document.write(\"直接打开\");}

查找搜索关键词:

var ref = document.referrer;console.log(ref);if(ref.indexOf(\"http://127.0.0.1:5500/search.html?\") == 0){    var args = ref.substring(ref.indexOf(\"?\") + 1).split(\"&\");    for(var i=0; i<args.length; i++){        if(args[i].substring(0,2) == \"q=\"){            document.write(\"<h2>搜索的是:</h2>\");            keys = args[i].substring(2).split(\"+\");            for(var k in keys){                document.write(decodeURIComponent(keys[k]) + \"<br>\");            }            break;        }    }}

domain属性:获取或设置当前文档的域名;

该属性允许当Web页面之间交互时,相同域名下互相信任的Web服务器之间协作放宽同源策略安全限制,其是可读的,但有安全限制,即不能为domain赋任意值;

不能将该属性设置为URL中不包含的域;

// FF提示“The operation is insecure.”,Chrome提示不是127.0.0.1的子域名// document.domain = \"www.zeronetwork.cn\";  // 异常console.log(document.domain);

document对象的集合:

除了属性和方法,document对象还有一些特殊的集合;这些集合都是HTMLCollection对象,为访问文档的常用部分提供了快捷方式,包括:

document.anchors:包含文档中所有带name特性的<a>元素;这个属性已经从Web标准中删除了,但浏览器还支持,所以尽量不要再使用;

<!-- link.html页面 --><h1>零点程序员</h1><h2><a name=\"one\">Web前端开发</a></h2><div style=\"height: 1000px;background-color: purple;\">DIV</div><h2><a name=\"two\">后端开发</a></h2><div style=\"height: 1000px;background-color: green;\">DIV</div><h2><a name=\"three\">苹果开发</a></h2><div style=\"height: 1000px;background-color: blue;\">DIV</div><!-- 主页面 --><p>    <input type=\"button\" value=\"Web前端开发\" onclick=\"jump(\'one\')\" />    <input type=\"button\" value=\"后端开发\" onclick=\"jump(\'two\')\" />    <input type=\"button\" value=\"苹果开发\" onclick=\"jump(\'three\')\" /></p><script>var win = window.open(\"link.html\",\"newWin\",\"width=250,height=150\");function jump(name) {    console.log(name);    if(win.document.anchors[name]){        win.location.hash = name;        win.focus();    }else{        alert(\"锚不存在\")    }}</script>

document.links:包含文档中所有带href特性的<a>元素或<area>元素;

var mydiv = document.getElementById(\"mydiv\");var links = document.links;for(var i=0,len=links.length; i<len; i++){    var aNode = document.createElement(\"a\");    aNode.href = links[i].href;    var href = document.createTextNode(links[i].innerText);    aNode.appendChild(href);    mydiv.appendChild(aNode);}

打开外链进行提醒:

var links = document.links;for(var i=0,len=links.length; i<len; i++){    var link = links[i];    link.addEventListener(\"click\",function(e){        e.preventDefault();        if(e.target.host !== location.host)            jump(e.target.innerText, e.target.href);        else            location.href = e.target.href;                },false);}function jump(title,href){    var div = document.createElement(\"div\");    div.id = \"jumpDiv\";    document.body.appendChild(div);    var str = document.createTextNode(\"你要访问的:\" + href + \"不属于本网站,你要继续访问吗?\");    div.appendChild(str);    var aGo = document.createElement(\"a\");    aGo.href = href;    aGo.target = \"_blank\";    aGo.appendChild(document.createTextNode(\"继续\"));    div.appendChild(aGo);    var aBack = document.createElement(\"a\");    aBack.href = \"Javascript:void(0);\";    aBack.appendChild(document.createTextNode(\"关闭\"));    aBack.onclick = closeJumpDiv;    div.appendChild(aBack);}function closeJumpDiv(){    var jumpDiv = document.getElementById(\"jumpDiv\");    if(jumpDiv)        jumpDiv.parentNode.removeChild(jumpDiv);}

document.applets:包含文档中所有的<applet>元素;

document.forms:包含文档中所有的<form>元素,与document.getElementsByTagName(“form”)得到的结果是相同的;

<form name=\"myform\">    <!-- id也可为以-->    <input type=\"text\" id=\"username\" /></form><form name=\"yourform\"></form><script>console.log(document.forms); // HtmlCollectionconsole.log(document.forms.myform);console.log(document.forms[0]);console.log(document.forms[\"myform\"]);console.log(document.forms.myform.username);</script>

document.embeds:包含文档中所有的<embeds>元素;

document.plugins:包含文档中所有的插件;注意和navigator.plugins的区别;

console.log(document.plugins);  // HTMLCollectionconsole.log(navigator.plugins);  // pluginArray

document.images:包含文档中所有的<img>元素实时集合,集合中的每个元素代表了一个image元素的HTMLImageElement,与document.getElementsByTagName(“img”)得到的结果是相同的;

document.scripts:返回一个HTMLCollection对象,包含了当前文档中所有<script>元素的集合;

document.all:只读属性,返回一个HTMLAllCollection,包含了页面上的所有元素;已从Web标准中删除,但是浏览器都支持,但建议不要使用;与document.getElementsByTagName(“*”)得到的结果基本相同的;

console.log(document.all);  // HTMLAllCollectionconsole.log(document.getElementsByTagName(\"*\"));  // HTMLCollectionconsole.log(document.all[9]);document.all[9].innerHTML = \"零点程序员\";// id或name为\"mydiv\"的元素,但是有区别的,为name的元素只是插入textdocument.all[\"mydiv\"].innerHTML = \"<h2>零点程序员</h2>\"; 

以上这些集合始终都可以通过HTMLDocument对象访问到,而且,它们都是动态的;但现在已经被document.getElementsByTagName()所取代,部分已经废弃不应该再使用,但是仍然常常被使用,因为他们使用起来很方便;

文档写入:

document对象,可以将文本字符串写入文档流中;

write()与writeln()方法:

这两个都接受一个字符串参数,即要写入到输出流中的文本;write()会原样写入,writeln()则会在字符串的末尾添加一个换行符(\\n);

这两个方法会将其字符串参数连接起来,然后将结果字符串插入到文档中调用它们的脚本元素的位置;

document.write(\"<h1>\" + document.title + \"</h1>\");document.write(\"<strong>\" + (new Date()).toString() + \"</strong>\");

不光输出内容,还会解析为DOM元素;

参数可以是多种形式,如:

// 部分替换为writeln()方法var username = \"wangwei\";document.write(\"我的名字:\" + username + \"<br/>\");document.write(\"sum:\" + (5 + 4));document.write(\"<ul>\");document.write(\"<li>HTML</li>\",\"<li>CSS</li>\",\"<li>Javasc </li>\");document.write(\"</ul>\")var arr = [\"<p>zeronetwork</p>\",\"<p>wangwei</p>\",\"<p>web</p>\"];document.write(arr.join(\"\"));function func(){    return \"func\";}document.write(func + \"<br>\");document.write(function(){    return \"Happy\";}());

只有在解析文档时才能使用write()方法输出HTML到当前文本,如果把write()方法放到一个函数内或者在文档加载结束后再调用document.write(),那么输出的内容将会重写整个页面;如:

window.onload = function(){    document.write(\"零点程序员\");}

这里有个问题,理论上来说,重写了整个页面后,原页面中的所有变量和值都应该被清除,但事实却不是这样的,IE是这样的行为,但其他浏览器会保留原内容中的变量和值;

var num = 10;function fun(){    document.write(\"fun\");}var mydiv = document.getElementById(\"mydiv\");window.onload = function(){    document.write(\"重写了整个页面\");    console.log(num);    fun();    document.body.appendChild(mydiv);}正因为它们不兼容,所以不要在新文档流中调用原内容中的变量和值;

open()与close()方法:

可以使用write()方法在其他的窗口或框架页中来创建整个全新文档,但一般会配合close和open方法一起使用;

open()和close()分别用于打开和关闭网页的输出流;如果是在页面加载期间使用write()或writeln()方法,则不需要用到这两个方法,因为文档此时是打开状态;向一个已经加载完成的文档写入数据时,会自动调用 document.open,并且会擦除该文档的所有内容,因为已经加载完成的文档,它的文档流已经关闭,就是已经自动调用了document.close();

可以多次调用write()来逐步建立新文档的内容;传递给write的内容可能缓存起来,所以一旦完成了数据写入,建议调用 document.close()来结束该写序列,以告诉HTML解析器,文档已经达到了文件的末尾,写入的数据会被解析到文档结构模型(DOM)里,此时应该结束解析并显示新文档;

btn.onclick = function(){    document.open();  // 可以省略document.write(\"重写了整个页面\");    document.close();}

此时,如果在close()方法后,再调用write()方法就会重写整个新窗口的内容,如:

// 在onclick事件处理函数中继续添加document.write(\"文档又被重写了\");

注意:无法关闭系统创建的文档流,如果,我们在全局环境中直接执行close()方法,会发现没有效果,原因就是无法关闭系统创建的文档流,我们只能关闭自己打开的文档流;

在新窗口也是同样的道理;

var oNewWin=window.open(\"about:blank\",\"newwindow\",\"width=400,width=200\");oNewWin.document.open();oNewWin.document.write(\"<h1>新窗</h1>\");oNewWin.document.write(\"<div>这是一个新窗口</div>\");oNewWin.document.close();

在使用write()方法时,最好一次性写入;

<input type=\"button\" id=\"btn\" value=\"写入\"><script>var newWin = null;function makeNewWin(){    newWin = window.open(\"about:blank\",\"newWin\",\"width=400,height=300\");}var btn = document.getElementById(\"btn\");btn.onclick = function(){    // 如果newWin不存在或已关闭,再次打开    if(!newWin || newWin.closed)        makeNewWin();    newWin.focus();    var title = \"零点程序员\";    var newStr = \"<!DOCTYPE html>\";    newStr += \"<html><head>\";    newStr += \"<title>\" + title + \"</title></head>\";    newStr += \"<body>\";    newStr += \"<h1>零点程序员</h1>\";    newStr += \"<div>这是内容</div>\";    // 把body拆分成</b和ody>,否则会抛出异常    newStr += \"</b\" + \"ody></html>\";     newWin.document.write(newStr);    newWin.document.close();}</script>

document.open()另类的用法:

2个参数的open()方法,语法为document.open(type, replace),如:

document.open(\"text/html\",\"replace\");

type指定了所需写入的数据的MIME类型,默认值为”text/html”,replace(如有设置,值为一个字符串“replace”)指定了新文档从父文档继承历史条目;

使用open()方法,在IE中会产生历史条目,其他浏览器不会产生,因此这种用法只会在IE中有效果;而如果指定了replace参数,IE就不会产生历史条目,也就是父文档的记录被覆盖了;

这种形式现在已经弃用;

3个参数的open()方法,是Window.open()的一个别名;

var doc = document.open(\"https://www.zeronetwork.cn/\",\"\",\"width=400;\");// 打开新窗口console.log(doc);  // Windowdoc.document.write(\"<h1>零点程序员</h1>\");  // 重写doc.document.close();// doc.close();  // 会关闭窗口

动态加载外部资源:

使用write()和writeln()两个方法,还可以动态加载外部资源,如Javascript文件等,但要注意,不能直接包含字符串“</script>”,因为会导致代码不能正确的解析;

document.write(\"<script type=\\\"text/javascript\\\" src=\\\"file.js\\\">\" + \"<\\/script>\");// 或者document.write(\"<script type=\\\"text/javascript\\\" src=\\\"file.js\\\">\" + \"</scr\" + \"ipt>\");

这种方法经常在广告和统计功能的第三方中使用;

为什么不直接使用<script>标签,而直接使用动态载入呢?原因有两个:

一是脚本的URL不能写死,比如要动态添加一些参数,用户设备的分辨率啊,当前页面 URL 啊,防止缓存的时间戳之类的,这些参数只能先用 JS 获取到,再比如国内常见的网站统计代码:

<script>var cnzz_protocol = ((\"https:\" == document.location.protocol) ? \" https://\" : \" http://\");document.write(unescape(\"%3Cspan id=\'cnzz_stat_icon_1279580898\'%3E%3C/span%3E%3Cscript src=\'\" + cnzz_protocol +  \"s9.cnzz.com/stat.php%3Fid%3D1279580898\' type=\'text/javascript\'%3E%3C/script%3E\"));</script>

它之所以使用write()方法,而不使用<script>元素,就是为了先用 JS 判断出该用http还是https 协议;

另外,有可能需要在脚本里加载另外一个脚本文件或嵌入的JS内容有可能会修改页面内容,而这些操作只需要第三方自己维护,不需要自己的网站去维护;

在实际开发中,write()并不常用,innerHTML属性和其他DOM技术提供了更好的方法来为文档增内容;比如,可以利用innerHTML来输出内容:

var mydiv = document.getElementById(\"mydiv\");mydiv.innerHTML = \"<h1>零点程序员</h1><p>开设了Web前端课程</p>\";// 重写body内所有内容document.body.innerHTML = \"<h1>零点程序员</h1><p>开设了Web前端课程</p>\";包装一个对象,类似于write()和close()方法:// 为设置元素的innerHTML定义简单的\"流式\"APIfunction ElementStream(elt){    if(typeof elt === \"string\")        elt = document.getElementById(\"elt\");    this.elt = elt;    this.buffer = \"\";}// 连接所有的参数,添加到缓存中ElementStream.prototype.write = function(){    this.buffer += Array.prototype.join.call(arguments, \"\");};// 类似write(),只是多增加了换行符ElementStream.prototype.writeln = function(){    this.buffer += Array.prototype.join.call(arguments, \"\") + \"\\n\";};// 从缓存设置元素的内容,然后清空缓存ElementStream.prototype.close = function(){    this.elt.innerHTML = this.buffer;    this.buffer = \"\";}var mydiv = document.getElementById(\"mydiv\");var elt = new ElementStream(mydiv);elt.write(\"<h1>零点程序员</h1>\");elt.writeln(\"<p>王唯</p>\");elt.close();
(0)
小多多的头像小多多创始人

相关推荐

发表回复

登录后才能评论