DOM和BOM
//window瀏覽器窗口,js可以控制一部分Browser Object Model //document頁面的主體部分Document Object Model //window location 本地 history 历史 screen 屏幕 navigator 信息 //window下的屬性 document.onmousemove=function(){ close();//关闭 open("http://www.163.com","网易","width=400,height=400");//打开 } console.log(innerWidth,innerHeight);//浏览器内部宽度,高度 console.log(outerWidth,outerHeight);//浏览器外部宽度,高度 // 窗口距离屏幕左上角的位置 console.log(screenLeft,screenTop) console.log(screenX,screenY) location.reload();//重载,刷新当前页面;reload(true)方法:刷新页面,如果参数为true,通过缓存刷新。[注意: 不要写在全局,不然浏览器就会一直处在刷新状态] //reload()方法用于刷新当前文档。reload() 方法类似于浏览器上的刷新页面按钮。 //如果把该方法的参数设置为 true,那么无论文档的最后修改日期是什么,它都会绕过缓存,从服务器上重新下载该文档。这与用户在单击浏览器的刷新按钮时按住 Shift 健的效果是完全一样。 location.href="http://www.163.com"; location.assign("http://www.163.com"); location.replace("http://www.163.com") // encodeURIComponent函数可把字符串作为 URI 组件进行编码 //http%3A%2F%2Fw3cschool.cc%2Fmy%20test.php%3Fname%3Dst%C3%A5le%26car%3Dsaab // decodeURIComponent document.onclick=function(){ console.log(location.href)//可以获取当前页面的地址 location.href="http://www.163.com";//可以设置跳转当前页面地址,獲取當前頁面的地址encodeURIComponent location.assign("http://www.163.com");//可以设置跳转当前页面地址 location.replace("http://www.163.com");//不产生历史记录 } console.log(location.hash);//获取#号后面的锚点 console.log(location.search);//获取?号后面的参数 console.log(location.hostname); console.log(location.pathname); console.log(location.port); console.log(location.protocol);//websocket聊天游戲協議,http/https協議,視頻二進制流的協議rtmp協議,qq無連接協議UDP,上傳提交内容ftp history.back(); history.forward(); history.go(-1);//回退1 history.go(0);//刷新 history.go(1);//前进1 history.pushState({a:1},"aaa"); history.replaceState({a:1},"aa"); console.log(history); console.log("aaa"); //仅改变网址,网页不会真的跳转,也不会获取到新的内容,本质上网页还停留在原页面 //做到改变网址却不需要刷新页面,这个特性后来用到了单页面应用中 //window.history.pushState(data, title, targetURL); //状态对象:传给目标路由的信息,可为空(一个与指定网址相关的状态对象,popstate事件触发时,该对象会传入回调函数。如果不需要这个对象,此处可以填null) //页面标题:目前所有浏览器都不支持,填空字符串即可 //可选url:目标url,不会检查url是否存在,且不能跨域。如不传该项,即给当前url添加data //特点:pushState()可以创建历史,可以配合popstate事件,可以使用history.go(-1)返回到上一个页面。 //window.history.replaceState(data, title, targetURL); //类似于pushState,但是会直接替换掉当前url,而不会在history中留下记录 //特点:replaceState不会加入到历史记录里面,用history.go(-1)会跳过当前页面相当于是history.go(-2)。 console.log(screen.availWidth,screen.availHeight);//不包含任务宽高 console.log(screen.width,screen.height);//整个屏幕宽高 console.log(navigator.userAgent); console.log(navigator.appName) console.log(navigator.appVersion) console.log(navigator.platform) console.log(getBrowserInfo()); function getBrowserInfo(){ if(navigator.userAgent.indexOf("Chrome")>-1) return "Chrome:"+navigator.userAgent.split("Chrome")[1].split(" ")[0].slice(1); if(navigator.userAgent.indexOf("Firefox")>-1) return "Firefox:"+navigator.userAgent.split("Firefox")[1].slice(1); } //Window 尺寸 //有三种方法能够确定浏览器窗口的尺寸。 //对于Internet Explorer、Chrome、Firefox、Opera 以及 Safari: window.innerHeight - 浏览器窗口的内部高度(包括滚动条) window.innerWidth - 浏览器窗口的内部宽度(包括滚动条) //对于 Internet Explorer 8、7、6、5: document.documentElement.clientHeight document.documentElement.clientWidth //或者 document.body.clientHeight document.body.clientWidth //实用的 JavaScript 方案(涵盖所有浏览器): var w=window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth; var h=window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight; //来自 navigator 对象的信息具有误导性,不应该被用于检测浏览器版本,这是因为: //navigator 数据可被浏览器使用者更改,一些浏览器对测试站点会识别错误,浏览器无法报告晚于浏览器发布的新操作系统,浏览器检测:由于 navigator 可误导浏览器检测,使用对象检测可用来嗅探不同的浏览器。 //由于不同的浏览器支持不同的对象,您可以使用对象来检测浏览器。例如,由于只有 Opera 支持属性 "window.opera",您可以据此识别出 Opera。例子:if (window.opera) {...some action...} window.name属性是一个字符串,表示当前浏览器窗口的名字。窗口不一定需要名字,这个属性主要配合超链接和表单的target属性使用。 //该属性只能保存字符串,如果写入的值不是字符串,会自动转成字符串。各个浏览器对这个值的储存容量有所不同,但是一般来说,可以高达几MB。 //只要浏览器窗口不关闭,这个属性是不会消失的。举例来说,访问a.com时,该页面的脚本设置了window.name,接下来在同一个窗口里面载入了b.com,新页面的脚本可以读到上一个网页设置的window.name。页面刷新也是这种情况。一旦浏览器窗口关闭后,该属性保存的值就会消失,因为这时窗口已经不存在了。 //如果两个窗口之间不需要通信,建议将子窗口的opener属性显式设为null,这样可以减少一些安全隐患。 var newWin = window.open('example.html', 'newWindow', 'height=400,width=400'); newWin.opener = null; //上面代码中,子窗口的opener属性设为null,两个窗口之间就没办法再联系了。 //通过opener属性,可以获得父窗口的全局属性和方法,但只限于两个窗口同源的情况(参见《同源限制》一章),且其中一个窗口由另一个打开。<a>元素添加rel="noopener"属性,可以防止新打开的窗口获取父窗口,减轻被恶意网站修改父窗口 URL 的风险。 //window.devicePixelRatio属性返回一个数值,表示一个 CSS 像素的大小与一个物理像素的大小之间的比率。也就是说,它表示一个 CSS 像素由多少个物理像素组成。它可以用于判断用户的显示环境,如果这个比率较大,就表示用户正在使用高清屏幕,因此可以显示较大像素的图片。 //window.innerHeight和window.innerWidth属性,返回网页在当前窗口中可见部分的高度和宽度,即“视口”(viewport)的大小(单位像素)。这两个属性只读。 //用户放大网页的时候(比如将网页从100%的大小放大为200%),这两个属性会变小。因为这时网页的像素大小不变(比如宽度还是960像素),只是每个像素占据的屏幕空间变大了,因为可见部分(视口)就变小了。 //注意,这两个属性值包括滚动条的高度和宽度。 //window.requestAnimationFrame()方法跟setTimeout类似,都是推迟某个函数的执行。不同之处在于,setTimeout必须指定推迟的时间,window.requestAnimationFrame()则是推迟到浏览器下一次重流时执行,执行完才会进行下一次重绘。重绘通常是 16ms 执行一次,不过浏览器会自动调节这个速率,比如网页切换到后台 Tab 页时,requestAnimationFrame()会暂停执行。 //如果某个函数会改变网页的布局,一般就放在window.requestAnimationFrame()里面执行,这样可以节省系统资源,使得网页效果更加平滑。因为慢速设备会用较慢的速率重流和重绘,而速度更快的设备会有更快的速率。 //该方法接受一个回调函数作为参数。 //window.requestAnimationFrame(callback)上面代码中,callback是一个回调函数。callback执行时,它的参数就是系统传入的一个高精度时间戳(performance.now()的返回值),单位是毫秒,表示距离网页加载的时间。 //window.requestAnimationFrame()的返回值是一个整数,这个整数可以传入window.cancelAnimationFrame(),用来取消回调函数的执行。 //下面是一个window.requestAnimationFrame()执行网页动画的例子。 var element = document.getElementById('animate'); element.style.position = 'absolute'; var start = null; function step(timestamp) { if (!start) start = timestamp; var progress = timestamp - start; // 元素不断向左移,最大不超过200像素 element.style.left = Math.min(progress / 10, 200) + 'px'; // 如果距离第一次执行不超过 2000 毫秒, // 就继续执行动画 if (progress < 2000) { window.requestAnimationFrame(step); } } //window.requestAnimationFrame(step); //上面代码定义了一个网页动画,持续时间是2秒,会让元素向右移动。 //它跟window.requestAnimationFrame()的区别在于,后者指定回调函数在下一次浏览器重排时执行,问题在于下一次重排时,系统资源未必空闲,不一定能保证在16毫秒之内完成;window.requestIdleCallback()可以保证回调函数在系统资源空闲时执行。 //需要注意的是,如果脚本网址与网页网址不在同一个域(比如使用了 CDN),浏览器根本不会提供详细的出错信息,只会提示出错,错误类型是“Script error.”,行号为0,其他信息都没有。这是浏览器防止向外部脚本泄漏信息。一个解决方法是在脚本所在的服务器,设置Access-Control-Allow-Origin的 HTTP 头信息。 //Access-Control-Allow-Origin: * ///然后,在网页的<script>标签中设置crossorigin属性。 <script crossorigin="anonymous" src="//example.com/file.js"></script> //上面代码的crossorigin="anonymous"表示,读取文件不需要身份信息,即不需要 cookie 和 HTTP 认证信息。如果设为crossorigin="use-credentials",就表示浏览器会上传 cookie 和 HTTP 认证信息,同时还需要服务器端打开 HTTP 头信息Access-Control-Allow-Credentials。 //window.resizeTo()方法用于缩放窗口到指定大小。 //它接受两个参数,第一个是缩放后的窗口宽度(outerWidth属性,包含滚动条、标题栏等等),第二个是缩放后的窗口高度(outerHeight属性)。 window.resizeTo( window.screen.availWidth / 2, window.screen.availHeight / 2 ) //上面代码将当前窗口缩放到,屏幕可用区域的一半宽度和高度。 //window.resizeBy()方法用于缩放窗口。它与window.resizeTo()的区别是,它按照相对的量缩放,window.resizeTo()需要给出缩放后的绝对大小。 //它接受两个参数,第一个是水平缩放的量,第二个是垂直缩放的量,单位都是像素。 window.resizeBy(-200, -200) //上面的代码将当前窗口的宽度和高度,都缩小200像素。
参考资料:
https://wangdoc.com/javascript/bom/index.html
DOM節點
// node 标签 注释 文本 文档 // 任何标签的nodeName都是该标签的大写字母 console.log(document.body.firstChild.nodeName==="DIV"); console.log(document.body.firstChild.constructor===HTMLDivElement); console.log(document.body.firstChild.nodeType); console.log(document.body.firstChild.nodeValue); document.getElementById("id");//通过id获取元素 var list=document.getElementsByTagName("div"); //通过标签名获取标签列表,只能通过document获取,HTMLCollection var list=document.getElementsByClassName("div1") //通过Class名获取标签列表,任何标签都可以获取其子项中Class列表,HTMLCollection console.log(list) var list=document.getElementsByName("sex"); //通过name属性获取节点列表,只能通过document获取,NodeList // NodeList // 选择选择器列表中的第一个元素 var div=document.querySelector(所有选择器) var div=document.querySelector("#div0"); var div=document.querySelector(".div1"); var div=document.querySelector("[type=text]"); var div=父容器.querySelector() // 选择选择器可以获取的所有元素 var div=document.querySelectorAll(所有选择器) var div0=document.getElementById("div0"); var list=div0.getElementsByClassName("div1"); console.log(list); div0.innerHTML="aaa"; var forms=document.getElementById("form0"); console.log(forms) var list=forms.getElementsByName("sex"); console.log(list); //nodeList是有forEach方法遍历 var list=document.getElementsByName("sex"); list.forEach(function(item){ console.log(item); }) // 节点遍历 console.log(document.body.children);//所有子元素的列表HTMLCollection console.log(document.body.childNodes);//所有子节点列表 console.log(document.body.firstChild);//第一个子节点 console.log(document.body.firstElementChild);//第一个子元素 console.log(document.body.lastChild);//最后一个子节点 console.log(document.body.lastElementChild);//最后一个子元素 console.log(document.body.lastElementChild.previousSibling);//上一个兄弟节点 console.log(document.body.lastElementChild.previousElementSibling);//上一个兄弟元素 console.log(document.body.firstElementChild.nextSibling);//下一个兄弟节点 console.log(document.body.firstElementChild.nextElementSibling);//下一个兄弟元素 console.log(document.body.firstChild.parentNode);//父节点 console.log(document.body.firstChild.parentElement);//父元素
DOM的創建和使用
//创建元素document.createElement(标签名) var div=document.createElement("div"); div.style.width="100px"; div.style.height="100px"; div.style.backgroundColor="red"; //appendChild追加到子元素中 父元素.appendChild(子元素) document.body.appendChild(div); var script=document.createElement("script"); var img=document.createElement("img"); var table=document.createElement("table"); var bn=document.querySelector("button"); var div0=document.querySelector("#div0"); bn.onclick=function(){ console.log('aaaa'); div0.innerHTML+="<div></div>";//会把button覆盖只能点击一次 } var str="aaa"; str+="aaa"; str=str+"aaa"; var bn=document.querySelector("button"); bn.onclick=function(){ var div=document.createElement("div"); document.body.appendChild(div); } function ce(type,style,parent){ var elem=document.createElement(type); for(var prop in style){ elem.style[prop]=style[prop]; } if(typeof parent==="string") parent=document.querySelector(parent); if(parent){ parent.appendChild(elem); } return elem; } var div=ce("div",{ width:"50px", height:"50px", backgroundColor:"red" }); document.body.appendChild(div); var div=ce("div",{ width:"50px", height:"50px", backgroundColor:"red" },"#div0"); document.addEventListener("click",clickHandler); function clickHandler(e){//事件函数里参数只能为e,包含点击的一部分数据 Utils.ce("div",{ width:"50px", height:"50px", backgroundColor:Utils.randomColor(), position:"absolute", left:e.x-25+"px", top:e.y-25+"px" },"body"); } // 碎片容器 var con=document.createDocumentFragment(); var ul=document.createElement("ul"); for(var i=0;i<10;i++){ var li=document.createElement("li"); li.innerHTML=i; ul.appendChild(li);//创建多个子元素放到页面,效率低下 } document.body.appendChild(ul); var con=document.createDocumentFragment(); for(var i=0;i<10;i++){ var div=document.createElement("div"); con.appendChild(div); } document.body.appendChild(con);
DOM插入複製和刪除替換
var span=document.createElement("span"); span.textContent="你好";//给div设置文本内容,不能设置html //textContent与innerHTML的区别:innerHTML主要的作用是在标签中设置新的html标签内容,是有标签效果的 //为了在元素中检索或写入文本,人们使用innerHTML。但是,textContent通常具有更好的性能,因为文本不会被解析为HTML。此外,使用textContent可以防止 XSS 攻击。 document.body.appendChild(div); // 父容器.insertBefore(要插入的元素,插入在谁的前面); document.body.insertBefore(div,document.body.firstChild) var div0=document.querySelector("#div0"); // 插入在子元素的最尾部 div0.appendChild(span); // 插入在子元素的最前面 div0.insertBefore(span,div0.firstChild); // 插入在元素的兄弟项前面 div0.parentElement.insertBefore(span,div0); // 插入在元素的兄弟项后面 div0.parentElement.insertBefore(span,div0.nextSibling); // 给指定元素列表中的内容增加外容器 function wrap(elemType,newType){ var elems=document.querySelectorAll(elemType); elems.forEach(function(item){ var parent=document.createElement(newType); item.parentElement.insertBefore(parent,item); parent.appendChild(item); }) } wrap("span","div"); function wrapAll(elemType,newType){ var elems=document.querySelectorAll(elemType); if(elems.length===0) return; var parent=document.createElement(newType); elems[0].parentElement.insertBefore(parent,elems[0]); elems.forEach(function(item){ parent.appendChild(item); }) } wrapAll("span","div"); // 创建文本节点 var txt=document.createTextNode("你好"); div0.insertBefore(txt,div0.firstElementChild); var p=document.createElement("p"); // 父容器.replaceChild(新的子元素,要替换掉旧元素); div0.replaceChild(p,div0.firstElementChild); // 删除节点 // 父容器.removeChild(子元素); // 子元素.remove() // 在删除时,元素仅仅是从页面中删除,不是从内存删除 div0.addEventListener("click",clickhandler); function clickhandler(){ console.log("aaa"); } div0.remove(); div0=null;//需要在设值null之前将事件也需要删除 document.body.appendChild(div0); // 如果在没有清楚内存的情况下还可以加入回去 div0.textContent=""; div0.innerHTML=""; // 复制 复制元素=复制目标.cloneNode(深浅复制) // true 深复制 复制元素和元素的所有子元素和节点 // false 浅复制 仅复制当前元素 var span1=document.querySelector("#span1"); var span2=span1.cloneNode(true); // 复制标签时,会标签的属性一起复制 span2.id="span2"; div0.appendChild(span2);
DOM屬性
var div=document.querySelector("div"); var input=document.querySelector("input"); div.aa=3; // DOM 对象属性 // DOM的对象属性,分为自定义型和原DOM对象属性 console.dir(div); // DOM的对象原属性与DOM对象的标签属性部分对应,部分有差别 div.className="div1";//就是设值class标签属性 div.id="div2"; div.style="width:100px;height:100px;" div.stlye.width="100px"; input.name="user"; input.checked=true; input.placeholder="用户名" div.aa=10; console.log(div.aa); // DOM 标签属性 // 设置标签的属性和值,值和属性都必须是字符类型 // DOM的标签属性命名,不能使用大小写区分不适用下划线区分 // 属性名必须全小写字母,并且使用-区分每个单词 div.setAttribute("shop-data","10"); // 获取标签属性 console.log(div.getAttribute("shop-data")); console.log(div.getAttribute("class")); // 删除标签属性 div.removeAttribute("shop-data"); document.body document.title document.head document.URL 当前页面地址 document.domain 域名 var str="欢迎同学们来千锋好程序员学习H5的课程。"; var i=0; setInterval(animation,400); function animation(){ i++; if(i>str.length-1) i=0; document.title=str.slice(i); }
DOM样式
var div0=document.querySelector("#div0"); div0.style.width="100px"; div0.style.height="100px"; div0.style.backgroundColor="red"; div0.style.width="100px"; div0.style.height="100px"; div0.style.border="1px solid #000000"; div0.style.backgroundColor="#FF0000"; // 上面的对象写法,需要将所有的css中-字母 替换为大写字母 // 例如 font-size fontSize // 而style字符串方式写法,按照原css行内样式填写 div0.style="width:100px;height:100px; padding-right: 0.1px;">Object.assign() 复制对象 浅复制 var o={a:1,b:2}; var o1={}; Object.assign(o1,o); o.a=10; console.log(o,o1); Object.assign(div0.style,{ width:"50px", height:"50px", backgroundColor:"red" }) // 增添class样式 div0.className="div1"; div0.className+=" div2"; div0.className=div0.className.replace("div1",""); // 如果DOM的行内样式有内容,可以通过这个方式获取对于的行内样式 // 如果DOM的样式在CSS中,这时候还没有渲染所以无法计算CSS的样式,这种style获取是不能获得CSS样式的 console.log(div0.style.width); // 想要获取计算后样式,就需要使用getComputedStyle获取元素的样式 console.log(getComputedStyle(div0).width);//不支持IE8及以下 console.log(div0.currentStyle.width); var style; try{ style=getComputedStyle(div0); }catch(error){ style=div0.currentStyle; } for(var i=0;i<document.styleSheets[0].cssRules.length;i++){ console.log(document.styleSheets[0].cssRules[i].selectorText) for(var j=0;j<document.styleSheets[0].cssRules[i].style.length;j++){ var key=document.styleSheets[0].cssRules[i].style[j]; // console.log(key, document.styleSheets[0].cssRules[i].style[key]); if(document.styleSheets[0].cssRules[i].selectorText===".div2"){ document.styleSheets[0].cssRules[i].style.color="green"; } } } console.log(document.styleSheets[0]); var styles={ ".div1":{ width:"50px", height:"50px", backgroundColor:"red" }, ".div2":{ fontSize:"20px", color:"#FFFFFF" } } Utils.setStyle(styles); init(); function init(){ var style=document.createElement("style"); document.head.appendChild(style); var styleSheet=document.styleSheets[document.styleSheets.length-1]; for(var prop in styles){ addCss(styleSheet,prop,styles[prop]); } } function addCss(styleSheet,selector,style){ // console.log(styleSheet,selector,style) // console.log(styleSheet.insertRule) var str=selector+" {"; for(var prop in style){ var value=style[prop] prop=prop.replace(/([A-Z])/g,function($1){ return "-"+$1.toLowerCase(); }) str+=prop+":"+value+";" } str+=" }"; styleSheet.insertRule(str,styleSheet.cssRules.length); }
DOM对象的常见属性
<!-- asdkjasldjaslkjdlaskjdlaksjdlaskjdlkasjdlksajdlkasjdlkasjdlkasjdlsakjdlaksjdlaskjdlakjsdlaskjdlkasjdlaksjdlaksjdlkasjdlaskjdlaksjdlkajsdlkajsdlkasjdlakjsdlkasjdlkasjdlaksjdlkasjdlaksjdlk<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> --> <!-- <div class="div0">lkajsdlkajsdlkjasdlkjsadlkjadlksjd<br>kjsadlkjadlksjd<br>kjsadlkjadlksjd<br>kjsadlkjadlksjd<br>kjsadlkjadlksjd<br>kjsadlkjadlksjd<br>kjsadlkjadlksjd<br>kjsadlkjadlksjd<br>kjsadlkjadlksjd<br>kjsadlkjadlksjd<br></div> --> <div class="div1"> <div class="div2"> asdlkasdlaksdlaskasdasdasdasdasdasdasdasdsadsadasddlas<br> asdlkasdlaksdlaskdlas<br> asdlkasdlaksdlaskdlas<br> asdlkasdlaksdlaskdlas<br> asdlkasdlaksdlaskdlas<br> asdlkasdlaksdlaskdlas<br> asdlkasdlaksdlaskdlas<br> asdlkasdlaksdlaskdlas<br> asdlkasdlaksdlaskdlas<br> asdlkasdlaksdlaskdlas<br> asdlkasdlaksdlaskdlas<br> asdlkasdlaksdlaskdlas<br> asdlkasdlaksdlaskdlas<br> asdlkasdlaksdlaskdlas<br> asdlkasdlaksdlaskdlas<br> asdlkasdlaksdlaskdlas<br> asdlkasdlaksdlaskdlas<br> asdlkasdlaksdlaskdlas<br> asdlkasdlaksdlaskdlas<br> </div> </div> var div=document.querySelector("div"); // 宽高 // clientWidth clientHeight 客户宽高 // offsetWidth offsetHeight 偏移宽高 // scrollWidth scrollHeight 滚动内容宽高 // DOM的宽高问题 console.log(div.clientWidth,div.clientHeight);//计算后宽高=宽高+padding-(如果有滚动条,减去滚动条宽高) console.log(div.offsetWidth,div.offsetHeight);//计算后宽高=宽高+padding+border console.log(div.scrollWidth,div.scrollHeight);//如果没有超出 等同于clientWidth和clientHeight // 如果超出就是实际内容所占的宽高,但是padding没有右侧和下侧 // 如果超出就是实际内容所占的宽高,但是padding没有右侧和下侧-(如果有滚动条,减去滚动条宽高) // html和body宽高问题 document.documentElement html标签 document.body body标签 console.log(document.body.clientWidth,document.body.clientHeight);//实际body的宽度和高度-滚动条宽高 console.log(document.body.offsetWidth,document.body.offsetHeight);//实际body的宽度和高度-滚动条宽高 console.log(document.body.scrollWidth,document.body.scrollHeight);//实际body中内容的宽高 console.log(document.documentElement.clientWidth,document.documentElement.clientHeight);//当前文档的可视宽高-(如果有滚动条,减去滚动条宽高) console.log(document.documentElement.offsetWidth,document.documentElement.offsetHeight);//当前文档的内容宽高-(如果有滚动条,减去滚动条宽高) console.log(document.documentElement.scrollWidth,document.documentElement.scrollHeight);//当前文档的可视宽高 //如果有滚动条,就是实际body撑开的宽高 // 位置 // clientLeft clientTop 客户位置 // offsetLeft offsetTop 偏移位置 // scrollLeft scrollTop 滚动条位置 // DOM的位置问题 var div2=document.querySelector(".div2"); div2.addEventListener("scroll",scrollHandler); console.log(div2.clientLeft,div2.clientTop);//边线的宽高 console.log(div2.offsetLeft,div2.offsetTop);//当前div到父容器左上角的距离(父容器是定位), // 它和position的left和top是相同的 console.log(div2.scrollLeft,div2.scrollTop);//当前元素的滚动条位置 // 前面的这些属性都是只读,但是这个是可以修改的 div2.scrollLeft=100;//滚动条位置设置 var rect=div2.getBoundingClientRect(); console.log(rect); rect.x===rect.left; rect.y===rect.top; 当前元素到可视窗口左上角的位置 function scrollHandler(e){ console.log(div2.scrollLeft,div2.scrollTop); } // html和body位置问题 // html和body的clientLeft ,offsetLeft 不考虑 // document.body.scrollTop=100; // 页面中的滚动是html的scrollTop和scrollLeft控制 // 早期的浏览器是body控制 // document.documentElement.scrollTop=200;
历史列表
<style> div{ width: 100px; height: 40px; font-size: 30px; line-height: 40px; text-align: center; border:1px solid #000000; float: left; margin-left: 50px; user-select: none; } p{ clear: both; display: none; } </style> <div>水果</div> <div>蔬菜</div> <div>零食</div> <div>饮料</div> <br> <br> <p>猕猴桃 苹果 梨</p> <p>白菜 土豆 地瓜</p> <p>辣条 牛肉干 薯片</p> <p>可乐 雪碧 果汁</p> var arr,divs; init() function init(){ // 当历史前进或者后退时就会收到这个事件 window.onpopstate=popStateHandler; arr=Array.from(document.getElementsByTagName("p")); divs=Array.from(document.getElementsByTagName("div")); arr[0].style.display="block"; for(var i=0;i<divs.length;i++){ divs[i].onclick=clickHandler; } } function clickHandler(){ var index=divs.indexOf(this); // history.pushState({state:1},"","#"+this.innerHTML); // 在历史记录列表中增加数据,后面的#内容标示当前跳转部分 history.pushState({index:index}, "", "#" +this.innerHTML); changeMenu(index); } function popStateHandler(){ console.log(history.state); changeMenu(history.state.index) } function changeMenu(index){ for(var i=0;i<arr.length;i++){ if(i===index){ arr[i].style.display="block"; }else{ arr[i].style.display="none"; } } }
普通列表
<style> div{ width: 100px; height: 40px; font-size: 30px; line-height: 40px; text-align: center; border:1px solid #000000; float: left; margin-left: 50px; user-select: none; } p{ clear: both; display: none; } </style> <div>水果</div> <div>蔬菜</div> <div>零食</div> <div>饮料</div> <br> <br> <p>猕猴桃 苹果 梨</p> <p>白菜 土豆 地瓜</p> <p>辣条 牛肉干 薯片</p> <p>可乐 雪碧 果汁</p> var arr,divs; init() function init(){ arr=Array.from(document.getElementsByTagName("p")); divs=Array.from(document.getElementsByTagName("div")); arr[0].style.display="block"; for(var i=0;i<divs.length;i++){ divs[i].onclick=clickHandler; } } function clickHandler(){ var index=divs.indexOf(this); for(var i=0;i<arr.length;i++){ if(i===index){ arr[i].style.display="block"; }else{ arr[i].style.display="none"; } } }
找徐峥
<style> div { width: 500px; height: 500px; border: 1px solid #000000; font-size: 0; } </style> <script src="./js/Utils.js"></script> <div></div> var n = 2, arr = []; init(); function init() { createImageCon(n); } function createImageCon(n) { /* document.querySelector("div").innerHTML=""; arr.length=0; */ for(var i=0;i<arr.length;i++){ arr[i].remove(); arr[i]=null; } arr.length=0; for (var i = 0; i < n * n; i++) { var img = Utils.ce("img", { width: 500 / n + "px", height: 500 / n + "px", }); if (i === 0) img.src = "img/1.png"; else img.src = "img/2.png"; arr.push(img); img.addEventListener("click", clickHandler); /* var url="" if(!bool)url=Math.random()>0.5 ? "img/1.png" : "img/2.png"; else url="img/2.png"; if(url==="img/1.png") bool=true; if(!bool && i===n*n-1) url="img/1.png"; console.log(url); img.src=url; */ } arr .sort(function () { return Math.random() - 0.5; }) .forEach(function (item) { document.querySelector("div").appendChild(item); }); } function clickHandler(e) { if (this.src.indexOf("1.png") > -1) { n++; } createImageCon(n); }
Utils.js
var Utils=(function(){ var time=0; var ids=0; var timeManage={}; return { timeStart:function(){ if(time) return; time=new Date().getTime(); }, timeEnd:function(){ var t=new Date().getTime()-time; time=0; return t; }, ts:function(){ ids++; timeManage[ids]=new Date().getTime(); return ids; }, te:function(id){ if(!timeManage[id]) return 0; var t=new Date().getTime()-timeManage[id]; delete timeManage[id]; return t; }, randomColor:function(){ var col="#"; for(var i=0;i<6;i++){ col+=Math.floor(Math.random()*16).toString(16); } return col; }, ce:function(type,style,parent){ var elem=document.createElement(type); if(style){ for(var prop in style){ elem.style[prop]=style[prop]; } } if(typeof parent==="string") parent=document.querySelector(parent); if(parent) parent.appendChild(elem); return elem; } } })();