H5学习感悟05

js 的组成

  • ECMA Script
  • Bom
  • Dom

Dom 文档对象模型

文档树

获取元素

根据id获取元素

对象是有类型的,getElementById这个方法只能通过document来调用

<script>
    var div_first = document.getElementById("first");
    console.log(div_first);
</script>

根据标签名获取元素

var divs=document.getElementsByTagName("div");//伪数组
获取的是动态集合
获取子代元素
<div id="first">
    <div id="first_inner"></div>
    <div></div>
</div>

<script>

    var div_first = document.getElementById("first");
    var div_first_inner = div_first.getElementsByTagName("div")[0];
    console.log(div_first_inner);
</script>

获取元素的其他方式

getElementsByName
  • 在IE, OP浏览器会查id
  var arr=document.getElementsByClassName("dd");
  console.log(arr)
getElementsByClassName的问题
  • ie9之后才支持
根据选择器获取元素

ie8之后才支持

querySelector
  • id是# 类是.
  • 只能获取一个元素
<div id="first" class="dd">
    <div id="first_inner"></div>
    <div class="dd"></div>
</div>
<script>
    var  div= document.querySelector("#first>.dd")
    console.log(div);
</script>
querySelectorAll
  • 返回的是元素的数组
<div id="first" class="dd">
    <div id="first_inner"></div>
    <div class="dd"></div>
</div>
<script>
   var div= document.querySelectorAll("#first")[0];
   console.log(div);
</script>

注册事件

事件名称事件的作用
onclick点击事件

点击事件

<input type="button" value="确定" id="btn">
<script>
    var  btn=document.getElementById("btn");

    btn.onclick=function () {
        console.log("点击")
    }
</script>
<script>

    var btn=document.getElementById('btn');

    btn.addEventListener('click',function () {
        console.log('======');
    })

    btn.addEventListener('click',function () {
        console.log('111======');
    })

</script>

老版本的ie支持的点击事件

 btn.attachEvent('onclicl',function () {
        console.log('111======');
    });

获取焦点事件和失去焦点事件

<script>
    var text = document.getElementById('text');

    text.onfocus = function () {
        //获取焦点的事件
        if (this.value === "请输入搜索关键字") {
            this.value='';

        }
        this.className='black';

    }

    text.onblur=function () {
        //失去焦点
        if (this.value === '') {
            this.value='请输入搜索关键字';

        }
        this.className='grey';

    }
</script>

addEventListener

  • 可重复注册不会被覆盖
  • 浏览器兼容问题,ie9以后才兼容

点击事件的兼容性写法

/**
 * 注册事件的兼容性写法
 * @param element
 * @param eventName
 */
function addEventListener(element, eventName,fn) {
    if (element.addEventListener) {
        element.addEventListener(eventName,fn);
    }else if (element.attachEvent) {
        element.attachEvent('on'+eventName,fn);
    }else {
        element['on'+eventName]=fn;
    }
}

移除事件

    var btn=document.getElementById('btn');
    btn.onclick=function () {
        console.log('===77===');
        btn.onclick=null;
    }
  • 如果通过addEventListener注册事件有想要移除事件,就不能用匿名函数
    var btn=document.getElementById('btn');
    var fn=function(){
        console.log("===8888===")
        btn.removeEventListener('click',fn);
    }
    btn.addEventListener('click',fn);
  • ie老版本 移除事件的方法
    var btn = document.getElementById('btn');

    function btnClick() {
        console.log('111======');
        btn.detachEvent('onclick', btnClick)
    }

    btn.attachEvent('onclick', btnClick);

移除事件的兼容性写法

/**
 * 移除事件的兼容性写法
 * @param element
 * @param eventName
 */

function removeEventListener(element, eventName, fn) {
    if (element.removeEventListener) {
        element.removeEventListener(eventName,fn);
    }else if (element.detachEvent) {
        element.detachEvent('on'+eventName,fn);
    }else {
        element['on'+eventName]=null ;
    }
} 

事件冒泡

事件由里向外传递

事件的三个阶段

事件发生的阶段eventPhase 值
事件捕获1
执行当前点击的元素(目标阶段)2
事件冒泡3

元素.onclick 是无法进行事件捕获的

事件委托

<script src="../utils/JSUtils.js"></script>
<script>
    my$('ul').addEventListener('click',function (e) {
        //e.target 是真正触发事件的元素对象
        //e 事件参数,也是事件对象
        for (let i = 0; i < my$('ul').children.length; i++) {
            my$('ul').children[i].removeAttribute('class');
        }
        e.target.setAttribute('class','highlight');
        console.dir(e.target.innerText);
    })
</script>

事件对象

eventPhase事件发生的阶段(数值)
target获取真正触发事件的对象(通常指标签对象)老版本ie不兼容
currentTarget注册事件的对象
type事件的类型
clientX,clientY相对于浏览器可视界面的横纵坐标
pageX,pageY相对于文档的横纵坐标ie9之前不兼容

如何阻止事件冒泡

标准dom方法

e.stopPropagation()

老版本ie阻止事件冒泡的方法,谷歌现也支持

e.cancelBubble=true;

t.addEventListener('click',function (e) {
    console.log(e.eventPhase)
    console.dir(e.target);
    console.log(e.type)
    console.dir(e.currentTarget);
    console.log("thir");
    //e.stopPropagation();//阻止事件冒泡
    e.cancelBubble=true;
});
target 兼容写法
   var target=e.target||e.srcElement;

获取浏览器滚动的距离

document.body.scrollLeft横向滚动的距离
document.body.scrollTop纵向滚定的距离

获取页面滚动距离的兼容问题

/**
 * 获取浏览器的滑动距离
 * @returns {{scrollLeft: number, scrollTop: number}}
 */

function getScroll() {
    return {
        scrollLeft: document.body.scrollLeft || document.documentElement.scrollLeft,
        scrollTop: document.body.scrollTop || document.documentElement.scrollTop
    }
}

获取鼠标在页面上的位置的兼容问题

/**
 * 获取鼠标在页面位置
 * @param e  鼠标的时间对象
 * @returns {{pageY: (*|number), pageX: (*|number)}}
 */
function getMousePosition(e) {
    return{
        pageX:e.pageX||e.clientX+getScroll().scrollLeft,
        pageY:e.pageY||e.clientY+getScroll().scrollTop
    };
}

取消默认行为的执行

return false;
e.preventDefault();
e.returnValue=false;ie老版本的方法,谷歌也支持

<a id="a" href="http://www.baidu.com">666</a>
<script>
    my$("a").onclick=function () {
        console.log("====???");
        return false;
    }
</script>
<a id="a" href="http://www.baidu.com">666</a>
<script>
    my$("a").onclick = function (e) {
        console.log("====???");
        e = e || window.event;
        e.preventDefault();
    }
</script>
<a id="a" href="http://www.baidu.com">666</a>


<script>
    my$("a").onclick = function (e) {
        console.log("====???");
        e = e || window.event;
        // e.preventDefault();

        e.returnValue=false;//ie老版本的方法,谷歌也支持
    }
</script>

键盘事件

onkeydown键盘按下
onkeyup键盘按下松开
keyCode键盘的ascll码a=65,48-57是数字
key键值
<input type="text" id="text">

<script>
    my$('text').onkeydown=function (e) {
        console.log("onkeydown",e.keyCode,e.key);
        if ((e.keyCode<48||e.keyCode>57)&&e.keyCode!==8){
            e.preventDefault();
            //e.cancelBubble=true;
        }
    }

    my$('text').onkeyup=function (e) {
        console.log("onkeyup",e.keyCode,e.key);
    }
</script>

属性操作

自定义属性

获取自定义属性

<div id="555" persionid="dd"></div>
<script>
    var  div=document.getElementById("555");
    console.log(div.persionid);//获取不到的
    console.log(div.getAttribute("persionid"));
</script>

设置自定义属性

setAttribute 不仅可以设置自定义属性,也可以设置已有属性

<script>
    div.tag='777';//设置不了
    div.setAttribute('tag','666');
</script>

删除属性

    li.removeAttribute('class')

非表单元素的属性

获取标签的某个属性值

标签.属性名

<a href="www.baidu.com" title="百度" id="link">点击跳转</a>
<img src="../file/5d089c5a851d1-家长订阅.png" alt="图片加载失败" id="img">

<script>

    var link=document.getElementById('link');
    var img=document.getElementById('img')
    console.log(link.id);
    console.log(link.href);
    console.log(link.title);
</script>

获取class属性

className

<button id="btn">影藏</button>

<div id="tag" class="show"></div>


<script>

    var btn = document.getElementById('btn');

    btn.onclick = function () {
        let div = document.getElementById("tag");
        console.log(div.className)
        if (div.className == "show") {
            btn.innerText = "显示"
            div.className = "hidden";
        } else {
            btn.innerText = "影藏"
            div.className = "show"
        }

    }
</script>

表单元素

表单元素的属性

<script>
    var btn = document.getElementById('btn');
    btn.onclick = function () {
        var text = document.getElementById('text');
        if (!text.disabled){
          btn.innerText='启用';
        }else {
            btn.innerText='禁用';
        }
        text.disabled = !text.disabled;
        console.log(text.disabled)
        console.log(text.type)
    }
</script>

如何取消a标签的默认跳转效果

onclick事件里拦截 retrun false

   arr_a[i].onclick=function () {
                p.innerText=arr[i].name;
                console.log(arr[i].name);
                show.src=arr[i].pic;
                return false;//取消a的默认行为
            }

innerText 与innerHTML,textContent 的区别

innerText如果内容中有标签会把标签过滤掉,去掉空格换行旧版的火狐,ie9以下只支持
innerHTML如果内容中有标签会把标签获取到,原封不动获取(包括空格换行)效率较低,因为要解析标签
textContent如果内容中有标签会把标签过滤掉,去掉空格换行

兼容处理

/**
 * 获取标签内容的兼容方法
 * @param element
 */

function getInnerText(element) {
    if (typeof element.innerText === 'string') {
        return element.innerText;
    } else {
        return element.textContent;
    }
}

样式操作

<ul id="ul">
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
    <li>7</li>
    <li>8</li>
    <li>9</li>
    <li>10</li>
</ul>

<script>
    var ul = document.getElementById("ul");
    var arr = ul.children;//获得所有的子元素
    for (let i = 0; i < arr.length; i++) {
        if (i%2==0){
            //奇数行
            arr[i].style.backgroundColor='#f00';
        }else {
            arr[i].style.backgroundColor='#0f0';
        }
    }
</script>

设置样式要.style设置

节点操作

##节点与元素的区别

  • 个人认为元素相当于html的标签
  • 节点的含义就比较广泛,包含了元素
节点的类型nodeNamenodeTypenodeValue
元素节点1null
属性节点
文本节点#text3空格,换行,字符
注释节点#comment8注释的内容
  • 换行+空白 属于文本节点

父子节点

获取所有的子节点

作用
childNodes获取所有的子节点包括:元素节点,文本节点,注释节点NodeList
children获取所有的子元素HTMLCollection
hasChildNodes判断某个元素是否含有子节点(包含文本节点)
firstElementChild获得第一个元素节点ie9以上,有兼容问题
<script>
    //获取子节点
    console.log(div.firstChild);
    console.log(div.firstElementChild)
    console.log(div.hasChildNodes());
    console.log(typeof  div.childNodes);//子节点
    console.dir(div.childNodes);
    console.log(typeof  div.children);//子元素
    console.dir(div.children);

</script>

获得第一个元素节点的兼容性写法

/**
 * 获取第一个子元素的兼容性代码
 * @param element
 * @returns {ChildNode | *|Element}
 */

function getFirstElement(element) {
    if (element.firstElementChild){
        return element.firstElementChild;
    }else {
        var arr=element.childNodes;
        for (let i = 0; i <arr .length; i++) {
            if (arr[i].nodeType===1){
                return arr[i];
            }
        }
    }
}

组织a标签跳转的几种写法

   <li class="current"><a href="javascript:void 0;">AA</a></li>
        <li><a href="javascript:void(0);">BB</a></li>
        <li><a href="javascript:undefined;">CC</a></li>

兄弟节点

方法
nextSibling获取下一个兄弟节点
nextElementSibling获取下一个兄弟元素
previousSibling获取上一个兄弟节点
previousElementSibling获取上一个兄弟元素
/**
 * 获取上一个兄弟元素
 * @param element
 * @returns {Node | (() => (Node | null)) | ActiveX.IXMLDOMNode|null}
 */

function getPreviousElementSibling(element) {
    let el=element;
    while (el=el.previousSibling){
        if (el.nodeType===1){
            return el;
        }
    }

    return null;

}


/**
 * 获取下一个兄弟元素
 * @param element
 * @returns {ChildNode | (() => (Node | null)) | ActiveX.IXMLDOMNode | Node|null}
 */
function getNextElementSibling(element) {
    let el=element;
    while (el=el.nextSibling){
        if (el.nodeType===1){
            return el;
        }
    }

    return null;
}

动态创建元素

方式特点
document.write会把整个页面覆盖掉
innerHTML
createElement在内存中创建一个dom对象(推荐)
  • 通常innerHTML的性能比createElement要高
  • 如果使用innerHTML里的子元素注册了事件,又把
    innerHTML=’’,就会导致元素清空,但事件依然绑定,引发内存泄漏
  • removeChild 清空元素并且清除掉元素的事件

document.write innerHTML

<script>
    var div=document.getElementById("tag");
    //document.getElementById("tag").innerHTML="666";
    //document.write("Name<p>hcy</p>");
    var  xhr=new XMLHttpRequest();
    xhr.open('get','./photo.php');
    xhr.send();
    xhr.responseType='json';
    xhr.onreadystatechange=function () {
        if (this.readyState!=4){
            return;
        }
        var array=this.response;
        console.log(array);
        var html=[];
        html.push('<ul>');
        for (let i = 0; i < array.length; i++) {
            html.push("<li class=\"myli\">");
            html.push(array[i].name);

            html.push('</li>');
        }
        html.push('</ul>');
        div.innerHTML=html.join('');
    }
</script>

createElement

<script>
    //在内存中创建一个dom对象
    var p=document.createElement("p");
    p.innerText=666;
    var div=document.getElementById("tag");
    div.appendChild(p);

</script>

动态移除元素

removeChild必须要直接父级的标签删除子标签,不能隔代删除
insertBefore把元素插入到页面的指定位置
replaceChild把当前元素的标签替换
<script>
    //在内存中创建一个dom对象
    var p=document.createElement("p");
    p.innerText=999;
    var div=document.getElementById("tag");
    //div.appendChild(p);
    div.insertBefore(p,div.children[0]);

</script>
<script>
    //在内存中创建一个dom对象
    var p=document.createElement("p");
    p.innerText=999;
    var div=document.getElementById("tag");
    //div.appendChild(p);
    div.replaceChild(p,div.children[0]);

</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值