[toc]
## previously
```
document.getElementById(); //上下文只能是document;只会获取到一个元素 不用[n]来获取 id嘛 独有的
context.getElementByTagName(); //把指令容器中子子孙孙辈分的所有标签名为TAGNAME的都获取到了,放在一个数组中
context.getElementsByClassName(CLASSNAME);//同上,但是在IE6~8下不兼容
document.getElementsByName(); //上下文只能是document;在IE浏览器中只对表单元素的name起作用
document.body
document.documentElement
context.querySelector/context.querySelectorAll //在IE6~8下不兼容;并且获取的是static NodeList
```
```
//->描述节点和节点之间关系的属性(在标准的浏览器中会把空格和换行当做文本节点来处理)
childNodes
//->元素节点,不过在IE6~8和标准浏览器不一样,会把注释加进来?;值获取儿子;
children
//->Element在IE6~8不兼容
parentNode
previousSibling/previousElementSibling
nextSibling/nextElementSibling
lastChild/lastElementChild
firstChild/firstElementChild
```
```
元素1 文本3 注释8 document9
```
DOM的增删改
```
createElement
document.createDocumentFragment()
appendChild
insertBefore
cloneNode(true/false)
replaceChild
removeChild
get/set/removeAttribute
```
DOM盒子模型
```
getComputedStyle
```
## children
获取某一个容器中的元素子节点(只是儿子)
```
//->首先获取所有的子节点(childNodes),在所有的子节点中把元素节点过滤出来(nodeType === 1)
function children(curEle,tagName){
var ary = [];
if(/MSIE(6|7|8)/i.test(navigator.userAgent)){
var nodeList = curEle.childNodes; //var连写时一般让短的在前面
for(var i=0,len=nodeList.length;i<len;++i){
if(curNode.nodeType===1){
ary[ary.length] = curNode;
}
}
}else{
//children下获取到的是一个类数组,是一个对象,So要转换为数组
ary = Array.prototype.slice.call(curEle.children);
}
//->二次筛选
if(typeof tagName === 'string'){
for(var k=0;k<ary.length;++k){ //需要使用.length作为动态的边界判断
var curEleNode = ary[k];
if(curEleNode.nodeName.toLowerCase===tagName.toLowerCase()){
ary.splice(k,1);
k--; //因为删除了,后面的会上移
}
}
}
return ary;
}
console.log(children(oDiv));
```
## prev
```
//prev:获取上一个哥哥元素节点
//首先获取当前元素的上一个哥哥节点,判断是否为元素节点,不是的话基于当前的继续找上面的哥哥节点...一直找到哥哥元素节点为止,如果没有哥哥元素界定啊,返回null即可
function prev(curEle){
if(flag){ //如果是标准浏览器
return curEle.previousElementSibling;
}
var pre = curEle.previousSibling;
while(pre&&pre.nodeType!==1){
pre = pre.previousSibling;
}
return pre;
}
```
## next
```
function next(curEle){
if(flag){
return curEle.nextElementSibling;
}
var next = curEle.nextSibling;
while(next&&next.nodeType==1){
next = next.nextSibling;
}
return next;
}
```
## prevAll
```
function prevAll(curEle){
var ary = [];
var pre = this.prev(curEle);
while(pre){
ary.unshift(pre);
pre = this.prev(pre);
}
return ary;
}
```
## nextAll
```
function nextAll(curEle){
var ary = [];
var next = this.next(curEle);
while(pre){
ary.push(next);
next = this.next(next);
}
return ary;
}
```
## sibling
获取相邻的两个元素节点
```
function sibling(curEle){
var pre = this.prev(curEle);
var nex = this.next(curEle);
var ary = [];
pre?ary.push(pre):null;
nex?ary.push(nex):null;
return ary;
}
```
## siblings
获取所有的兄弟元素节点
```
function siblings(curEle){
return this.prevAll(curEle).concat(this.nextAll(curEle));
}
```
## index
获取当前元素的索引
```
function index(curEle){
return this.prevAll(curEle).length;
}
```
## firstChild和lastChild
```
function firstChild(curEle){
var chs = this.children(curEle); //所有子节点
return this.length>0?chs[0]:null;
}
//->lastChild:获取最后一个元素子节点
function lastChild(curEle){
var chs = this.children(curEle); //所有子节点
return this.length>0?chs[chs.length-1]:null;
}
```
## append
```
function append(newEle,container){
container.appendChild(newEle);
}
```
## prepend
把新的元素添加到容器中的第一个子元素节点的前面
```
function prepend(newEle,container){
var fir = this.firstChild(container);
if(fir){
container.insertBefore(newEle,fir);
return;
}
container.appendChild(newEle)
}
```
## insertBefore
把新元素追加到指定元素的前面
```
function insertBefore(newEle,oldEle){
oldEle.parentNode.insertBefore(newEle,oldEle);
}
```
## insertAfter
把新的元素追加到指定元素的后面
```
function insertAfter(newEle,oldEle){
var nex = this.next(oldEle);
if(nex){
oldEle.parentNode.insertBefore(newEle,nex);
return;
}
oldEle.parentNode.appendChild(newEle);
}
```
## hasClass
```
//->hasClass:验证当前元素中是否包含className这个样式类名
function hasClass(curEle,className){
//curEle.className //->"box bg border"
//->"bg" /\s+bg\s+/
//->"box" /^box\s+/
//->"border" /\s+border$/
var reg = new RegExp("(^| +)"+className+"( +|$)");
return reg.test(curEle.className);
}
console.log(hasClass(box,"bg"));
console.log(hasClass(box,"position"));
```
## addClass
```
function addClass(curEle,className){
if(!hasClass(curEle,className)){
curEle.className += " "+className;
}
}
addClass(box,'position');
```
但这么写仍然会重复
```
addClass(box,'position bg'); //这么写仍然会重复
```
以空格拆分为数组,一个一个进行处理
```
function addClass(curEle,className){
//->为了防止className传递进来的值包含多个样式类名,我们把传递进来的字符串按照一到多个空格拆分成数组中的每一项
var ary = className.replace(/^ +| +$/g,'').split(/ +/g);
//->循环数组,一项项的进行验证添加即可
for(var i=0,len=ary.length;i<len;++i){
var curName = ary[i];
if(!hasClass(curEle,curName)){
curEle.className += " "+curName;
}
}
}
```
## removeClass
```
function removeClass(curEle,className){
//->为了防止className传递进来的值包含多个样式类名,我们把传递进来的字符串按照一到多个空格拆分成数组中的每一项
var ary = className.replace(/^ +| +$/g,'').split(/ +/g);
//->循环数组,一项项的进行验证添加即可
for(var i=0,len=ary.length;i<len;++i){
var curName = ary[i];
if(!hasClass(curEle,curName)){
var reg =new RegExp("(^| +)"+curName+"( +|$)");
curEle.className = curEle.className.replace(reg," ");
}
}
}
```
## getElementsByClassName
- 只要包含传入的类名就会被选中
- 若果传入的字符串中包含多个类名,那么是选中包含所有这些类名的元素(和传入字符串中的这些个类名的空格多少与先后顺序没有关系)
- 若没有匹配中的,则返回空集合
```
//->getElementsByClass:通过元素的样式类名获取一组元素集合
//->className:要获取的样式类名(可能是一个也可能是多个)
//->获取元素的上下文->如果这个值不传递的话,默认应该是document
function getElementsBycClass(className,context){
conext = context||document;
var classNameAry = className.replace(/^ +| +$/g,'').split(/ +/g); //先去掉首尾空格,然后再按照中间的空格把它里面的每一项拆分成数组
var ary = [];
//->获取指定的上下文中所有的元素标签,循环这些标签,获取每一个标签的className样式类名的字符串
var nodeList = context.getElementsByTagName("*"); //->获取指定上下文中的所有的元素标签
for(var i=0,len=nodeList.length;i<len;++i){
var curNode = nodeList[i];
//->判断curNode.className是否即包含"w3"也包含"w1" ,如果两个都包含的话,curNode就是我想要的,否则就不是我想要的
var isOk = true;//->我们假设curNode中包含了所有的样式
for(var k=0;k<classNameAry.length;++k){
var reg = new RegExp("(^| +)+curNameAry[k]+( +|$)")
if(!reg.test(curNode.className)){
isOk = false;
break;
}
}
if(isOk){ //拿每一个标签分别和所有样式类名比较后,如果结果还是true的话,说明当前元素标签包含了所有的样式,也是我们想要的
ary.push(curNode);
}
}
return ary;
}
console.log(getElementsByClass("w3 w1 "));
```
## setCss
在JS中给元素设置样式属性值,我们只能通过`curEle.style[attr]=value`这种方式给当前元素设置行内样式
setCss给当前元素的某一个样式属性设置值(增加在行内样式上的)
```
function setCss(curEle,attr,value){
//->在JS中设置float样式值的话也需要处理兼容
if(attr==="float"){
curEle['style']['cssFloat'] = value;
curEle['style']['styleFloat'] = value;
return;
}
//->如果打算设置的是元素的透明度,我们需要设置两套样式来兼容所有的浏览器
if(attr === 'opacity'){
curEle['style']['opacity'] = value;
curEle['style']['filter'] = "alpha(opacity="+value*100+")";
return;
}
// ->对于某些样式属性,如果传递进来的值没有加单位,我们需要把单位默认的补充上,这样的话,这个方法就会人性化一些
var reg = null;
reg = /^(width|height|top|bottom|left|right|((margin|padding)(Top|Bottom|Left|Right)?))$/;
if(reg.test(attr)){
if(!isNaN(value)){ //如果为true,说明加单位了
value+='px';
}
}
curEle['style'][attr] = value;
}
setCss(box,'left','100px');
setCss(box,'left',200);
setCss(box,'background',"red");
setCss(box,"opacity",0.1);
setCss(box,"borderTop","10px solid #000");
setCss(box,"padding","10px 20px 30px 40px");
setCss(box,"padding",10); //复合值的话 只支持4个值都相同的情况下不加单位
```
## setGroupCss
```
function setGroupCss(curEle,options){
//->通过检测options的数据类型,如果不是一个对象,则不能进行批量的设置
options = options||0; //排除null和undefined
if(Object.prototype.toString.call(options)!=="[object Object]"){
return;
}
for(var key in options){
if(options.hasOwnProperty(key)){
this.setCss(curEle,key,options[key]);
}
}
}
utils.setGroupCss(box,{
width:200
,backgroundColor:"red"
,opacity:0.1
,float:"right"
,borderTop:"10px solid #000"
,padding:10
})
```
## css
此方法实现了获取、单独设置、批量设置元素的样式值
```
function css(curEle){
var argTwo = arguments[1];
if(typeof argTwo === 'string'){ //->第一个参数值是一个字符串,这样的话很有肯能就是在获取样式,为什么说是很有可能呢?因为还需要判断是否存在第三个参数,如果第三个参数存在的话,就不是获取了,而是在单独的设置样式属性值
var argThree = arguments[2];
if(!argThree){ //->第三个参数不存在;
// return this.getCss(curEle,argTwo);
return this.getCss.apply(this,arguments);
}
//->第三个参数存在则为单独设置
// this.setCss(curEle,argTwo,argThree);
this.setCss.apply(this,arguments);
}
argTwo = argTwo || 0;
if(argTwo.toString === "[object Object]"){
//->批量设置样式属性值
this.setGroupCss.apply(this.arguments);
}
}
```
其中的`!argThree`有bug,
因为有可能这个值是个0这样判断的话就会进来,但并不是死我们所期望的,它本应该是设置值,应该判断它是不是undefined
```
if(typeof argument[2]==='undefined'){}
```
- 空白目录
- window
- location
- history
- DOM
- 什么是DOM
- JS盒子模型
- 13个核心属性
- DOM优化
- 回流与重绘
- 未整理
- 文档碎片
- DOM映射机制
- DOM库封装
- 事件
- 功能组件
- table
- 图片延迟加载
- 跑马灯
- 回到顶部
- 选项卡
- 鼠标跟随
- 放大镜
- 搜索
- 多级菜单
- 拖拽
- 瀑布流
- 数据类型的核心操作原理
- 变量提升
- 闭包(scope)
- this
- 练习题
- 各种数据类型下的常用方法
- JSON
- 数组
- object
- oop
- 单例模式
- 高级单例模式
- JS中常用的内置类
- 基于面向对象创建数据值
- 原型和原型链
- 可枚举和不可枚举
- Object.create
- 继承的六种方式
- ES6下一代js标准
- babel
- 箭头函数
- 对象
- es6勉强笔记
- 流程控制
- switch
- Ajax
- eval和()括号表达式
- 异常信息捕获
- 逻辑与和或以及前后自增
- JS中的异步编程思想
- 上云
- 优化技巧
- 跨域与JSONP
- 其它跨域相关问题
- console
- HTML、XHTML、XML
- jQuery
- zepto
- 方法重写和方法重载
- 移动端
- 响应式布局开发基础
- 项目一:创意简历