码迷,mamicode.com
首页 > 编程语言 > 详细

再战JavaScript

时间:2016-07-13 13:37:09      阅读:171      评论:0      收藏:0      [点我收藏+]

标签:

下面我们接着介绍创建节点。

创建节点,插入节点的方式,就好像是买一个大袋子,一个大袋子里装着一些小袋子,小袋子里分别装着不同的东西。

我们来看看代码就一目了然了:

<script type="text/javascript">
        //新创建一个元素节点,并把该节点添加为文档中指定节点的子节点
        window.onload = function() {
            //新创建一个元素节点,返回值为指向元素节点的引用
            //<li></li>
            var liNode = document.createElement("li");
            //新创建一个文本节点
            var textNode = document.createTextNode("华盛顿");
            //将文本节点添加到li的子节点
            //<li>华盛顿</li>
            liNode.appendChild(textNode);
            var cityNode = document.getElementById("city");
            //新添加一个子节点,该子节点将会被添加到最后的位置
            cityNode.appendChild(liNode);

        }
    </script>

大袋子(city)里装着很多小袋子(li),小袋子里装着不同的东西(不同的城市名字的文本),没错吧?很简单。

难道JavaScript只能支持这么low的做法吗?当然不是,还可以在现有已经存在的节点中互换双方的位置。当然,需要一个中间变量做转换。

代码如下:

<script type="text/javascript">
    window.onload = function() {
        /*只能实现单向移动,被覆盖的节点还没拷贝
        var bjNode = document.getElementById("bj");
        var newNode = document.createElement("li");
        
        var cityNode = document.getElementById("city");
        //replaceChild()方法可以实现将"红警"移动到"北京"
        cityNode.replaceChild(newNode, bjNode);
         */
        
         /*
        var bjNode = document.getElementById("bj");
        var cityNode = document.getElementById("city");

        var hjNode = document.getElementById("hj");
        var gameNode = document.getElementById("game");

        //先将北京节点拷贝下来
        var tempNode = bjNode.cloneNode(true);

        gameNode.replaceChild(tempNode, hjNode);
        cityNode.replaceChild(hjNode, bjNode);
        */
        var bjNode = document.getElementById("bj");
        var hjNode = document.getElementById("hj");
        replaceEach(bjNode, hjNode);
    }
    //自定义互换两个节点的函数
    function replaceEach(aNode, bNode) {
        //1.获取aNode和bNode的父节点,使用parentNode属性
        var aParent = aNode.parentNode;
        var bParent = bNode.parentNode;
        
        //当父节点存在的情况下才进行互换
        if (aParent && bParent) {
            //2.克隆aNode
            var aNode2 = aNode.cloneNode(true);
            //3.分别调用aNode的父节点和bNode的父节点的peplaceChild()实现互换
            bParent.replaceChild(aNode2, bNode);
            aParent.replaceChild(bNode, aNode);
        }
    }
</script>

下面我们要介绍一下弹出可以选择是和否的对话框,也就是confirm()方法了。

练习需求:为每一个li节点添加一个confirm(),若确定,则删除,结合我们的removeChild()方法,这个练习so easy。

代码如下:

<script type="text/javascript">
    //为每一个li节点添加一个confirm(),若确定,则删除
    window.onload = function() {
        /*
        //测试:removeChild():删除节点
        var cityNode = document.getElementById("city");
        alert(cityNode.parentNode);
        //通过调用父节点的removeChild()来完成,更加快捷、方便
        cityNode.parentNode.removeChild(cityNode);
         */

        var liNodes = document.getElementsByTagName("li");
        var length = liNodes.length;
        for (var i = 0; i < length; i++) {
            liNodes[i].onclick = function() {
                //confirm()方法会返回一个boolean值,选择确定未true,取消为false
                var flag = confirm("确定要删除\"" + this.innerHTML + "\"吗?");
                if (flag) {
                    this.parentNode.removeChild(this);
                }
            }
        }
    }
</script>

JavaScript还提供了insertBefore()方法,允许我们可以将某节点插入到指定节点的前面。

代码如下:

//把#hj插入到#bj的前面
var cityNode = document.getElementById("city");
var bjNode = document.getElementById("bj");
var hjNode = document.getElementById("hj");
cityNode.insertBefore(hjNode, bjNode);

但是并没有提供insertAfter()方法。那我们就自定义一个吧!

思路是这样的:先检查指定节点是否为父节点的最后一个节点。如果是,那就直接appendChild(),因为这个方法默认放到最后;如果不是,那么就获取下一个节点,也就是.nextSibling()方法,然后再使用insertBefore()方法。

代码如下:

<script type="text/javascript">
    window.onload = function() {
        var bjNode = document.getElementById("bj");
        var hjNode = document.getElementById("hj");
        insertAfter(hjNode, bjNode);

    }
    
    //把newNode插入到refNode的后面
    function insertAfter(newNode, refNode) {
        //1.验证refNode是否为其父节点的最后一个节点
        var parentNode = refNode.parentNode;
        
        if (parentNode) {
            var lastNode = parentNode.lastChild;
            if (lastNode == refNode) {
                //2.若是,则直接使用父节点的appendChild()将其插入到最后
                parentNode.appendChild(newNode);
            }
            //3.若不是,则先获取refNode的下一个节点,再使用insertBefore()方法插入
            else {
                parentNode.insertBefore(newNode, refNode.nextSibling);
            }
        }
    }
</script>

下面我们要做几个练习,HTML文档如下:

<p>你喜欢哪个城市?</p>
    <ul id="city">
        <li id="bj">北京</li>
        <li>上海</li>
        <li>东京</li>
        <li>首尔</li>
    </ul>
    <br>
    <br>
    <p>你喜欢哪款单击游戏?</p>
    <ul id="game">
        <li id="hj">红警</li>
        <li>实况</li>
        <li>魔兽</li>
        <li>星际</li>
    </ul>
    <br>
    <br>
    <input type="radio" id="myCity" name="myChoose" value="city" />城市
    <input type="radio" id="myGame" name="myChoose" value="game" />游戏
    <p>
        name:<input type="text" id="name" name="name" />
    </p>
    <input type="submit" id="mySubmit" name="mySubmit" value="submit" />

需求如下:需求1:点击submit按钮时,检查是否选择type,若没有选择就给出提示:“请选择类型”;

    检查文本框中是否有输入(可以去除前后空格),若没有输入,则给出提示:“请输入内容”;

    若检查都通过,则在相应的ul节点中添加对应的li节点;

    需求2:使包括新增的li都能响应onclick事件,弹出li的文本值。

根据需求的描述,我们可以知道,其实所有的事件触发都在button上,那么就可以将所有的逻辑判断都加入到button上。

代码如下:

<script type="text/javascript">
    window.onload = function() {
        function showContent(liNode) {
            alert(liNode.innerHTML);
        }
        var liNodes = document.getElementsByTagName("li");
        var liLength = liNodes.length;
        for (var i = 0; i < liLength; i++) {
            liNodes[i].onclick = function() {
                showContent(this);
            }
        }
        //获取到按钮,并添加事件
        var btn = document.getElementById("mySubmit");
        btn.onclick = function() {
            //根据组名获取是否被选中的条件
            var types = document.getElementsByName("myChoose");
            var typeVal = null;
            var name = document.getElementById("name");

            var length = types.length;
            //判断单选按钮是否被选中
            for (var i = 0; i < length; i++) {
                if (types[i].checked) {
                    typeVal = types[i].value;
                    break;
                }
            }
            if (!typeVal) {
                alert("请选择类型");
                return;
            }
            //判断用户是否输入
            if (!name.value) {
                alert("请输入内容");
                return;
            }

            //都通过的情况将添加一条li
            var li = document.createElement("li");
            //获取文本框的内容
            var text = document.createTextNode(name.value);
            //将文本框的内容添加到li
            li.appendChild(text);
            li.onclick = function() {
                showContent(this);
            }
            //将li添加到typeVal指定的ul
            var ulNode = document.getElementById(typeVal);
            ulNode.appendChild(li);
        }
    }
</script>

新的需求如下:需求:为所有的li节点添加onclick响应函数;

       实现city子节点和game子节点对应位置的元素的互换。

思路是这样的:根据标签名获取到所有的li节点,这样一来,li就在一个数组里面有属于自己的下标了。根据提供的HTML文档,我们可以让(0,1,2,3)和+4的交换,让(4,5,6,7)和-4的交换。

交换结束之后,我们不仅仅是交换节点内容,我们还需要重新赋予onclick事件,还需要将新的下标赋予它。

代码如下:

<script type="text/javascript">
    window.onload = function() {
        var liNodes = document.getElementsByTagName("li");
        var length = liNodes.length;
        for (var i = 0; i < length; i++) {
            //使用index储存当前节点的下标,因为在触发事件的时候i的值已经是超过length的那个值了
            liNodes[i].index = i;
            liNodes[i].onclick = function() {
                var targetIndex = 0;
                if (this.index < 4) {
                    targetIndex = this.index + 4;
                } else {
                    targetIndex = this.index - 4;
                }
                replaceEach(this, liNodes[targetIndex]);
            }
        }

        //显示为8,没有局部变量这一说
        //alert(i);
    }
    function replaceEach(aNode, bNode) {
        var aParent = aNode.parentNode;
        var bParent = bNode.parentNode;

        if (aParent && bParent) {
            //拷贝的时候并未将事件、index拷贝
            var aNode2 = aNode.cloneNode(true);
            //alert(aNode.index);
            //alert(aNode2.index);
            //alert(bNode.index);
            
            //克隆aNode的同时,把onclick事件也复制
            aNode2.onclick = aNode.onclick;
            aNode2.index = bNode.index;
            bNode.index = aNode.index;

            bParent.replaceChild(aNode2, bNode);
            aParent.replaceChild(bNode, aNode);
        }
    }
</script>

很简单吧!

下面我们又来一个一份新的HTML文档,文档如下:

你爱好的运动是?
    <input type="checkbox" id="checkedAll" />全选/全不选
    <br />
    <input type="checkbox" name="items" value="足球" />足球
    <input type="checkbox" name="items" value="篮球" />篮球
    <input type="checkbox" name="items" value="排球" />排球
    <input type="checkbox" name="items" value="乒乓球" />乒乓球
    <br />
    <input type="button" id="btnAll" value="全选" />
    <input type="button" id="btnNo" value="全不选" />
    <input type="button" id="checkedRev" value="反选" />

    <input type="button" id="send" value="提交" />

一看这份文档,我们第一反应肯定是与按钮事件响应有关了。

需求:当点击id为checkedAll的按钮时,先检查下面的爱好选择做出选择:如果爱好全部被选择,那么checkedAll按钮要做的事情就是“全不选”;否则就是“全选”功能。

   下面的button按钮根据名字就可以得知了。

   每当爱好全部被打上钩时,checkedAll按钮也要被打上钩;只要不满足前面的条件,checkedAll按钮不能被打上钩。

看上去很绕,其实理清了思路,非常简单。需求正好就是我们的思路方向。

代码如下:

<script type="text/javascript">
    window.onload = function() {
        var checkedAll = document.getElementById("checkedAll");
        var items = document.getElementsByName("items");
        var length = items.length;
        checkedAll.onclick = function() {
            var flag = 0;
            for (var i = 0; i < length; i++) {
                if (items[i].checked) {
                    //每当一个选项已经被选中时就加1
                    flag += 1;
                }
            }
            //只有当全部选项都被选中时,点击按钮的效果才是“全不选”
            if (flag == length) {
                for (var j = 0; j < length; j++) {
                    items[j].checked = false;
                }
                //记得把按钮本身的状态切换成一致,否则将会出现按钮本身未打钩而爱好的选项全打钩或者反过来的“灵异”现象
                this.checked = false;
            }
            //其余情况下,都是“全选”
            else {
                for (var k = 0; k < length; k++) {
                    items[k].checked = true;
                }
                this.checked = true;
            }
        }

        for (var l = 0; l < length; l++) {
            //给所有的爱好按钮增加事件
            items[l].onclick = function() {
                check();
            }
        }

        var btnAll = document.getElementById("btnAll");
        btnAll.onclick = function() {
            for (var i = 0; i < length; i++) {
                items[i].checked = true;
            }
            check();
        }

        var btnNo = document.getElementById("btnNo");
        btnNo.onclick = function() {
            for (var i = 0; i < length; i++) {
                items[i].checked = false;
            }
            checkedAll.checked = false;
        }

        var checkedRev = document.getElementById("checkedRev");
        checkedRev.onclick = function() {
            for (var i = 0; i < length; i++) {
                if (items[i].checked) {
                    items[i].checked = false;
                } else {
                    items[i].checked = true;
                }
            }
            check();
        }

        var send = document.getElementById("send");
        send.onclick = function() {
            for (var i = 0; i < length; i++) {
                if (items[i].checked) {
                    alert(items[i].value);
                }
            }
        }

        //当所有爱好都打钩时,全选按钮也打上钩,否则就不打钩
        function check() {
            var myFlag = 0;
            for (var m = 0; m < length; m++) {
                if (items[m].checked) {
                    myFlag += 1;
                }
            }
            if (myFlag == length) {
                checkedAll.checked = true;
            } else {
                checkedAll.checked = false;
            }
        }
    }
</script>

最后一份HTML文档从天而降。文档如下:

<p align="center">添加新员工</p>
    <table align="center">
        <tr>
            <td>name:<input type="text" id="name" name="name" /></td>
            <td>email:<input type="text" id="email" name="email" /></td>
            <td>salary:<input type="text" id="salary" name="salary" /></td>
        </tr>
    </table>
    <p align="center">
        <input type="button" id="add" name="add" value="新增" />
    </p>
    <hr>
    <table id="employeeTable" align="center" border="1" cellpadding="5"
        cellspacing="0">
        <tr>
            <th>name</th>
            <th>Email</th>
            <th>Salary</th>
            <th></th>
        </tr>
        <tr>
            <td>Tom</td>
            <td>tom@tom.com</td>
            <td>5000</td>
            <td><input type="submit" name="delete" value="Delete" /></td>
        </tr>
        <tr>
            <td>Mary</td>
            <td>mary@mary.com</td>
            <td>10000</td>
            <td><input type="submit" name="delete" value="Delete" /></td>
        </tr>
    </table>

需求:新增按钮:将员工的姓名、邮箱和薪水添加到表格中;

删除按钮:confirm()提示是否将"员工名字"信息删除?确定将整行员工信息删除,否则什么也不做。

新增按钮要做的事情,其实就是文章一开始要叙述的东西,也就是把某物品装进大袋子的事情。

删除按钮,其实只要能获取到它的父节点,也就解决了。

代码如下:

<script type="text/javascript">
    window.onload = function() {
        //删除按钮触发的函数
        function deleteInfo(node) {
            var currentTr = node.parentNode.parentNode;
            var name = currentTr.getElementsByTagName("td")[0];
            var flag = confirm("是否将\"" + name.innerHTML + "\"信息删除?");
            //当点击确定后触发事件
            if (flag) {
                /*
                第一个parentNode是td,第二个parentNode是tr,第三个parentNode是table
                也就是说根据delete按钮所在的列所在的行所在的表格中删除掉整行(很拗口是吧?)
                 */
                node.parentNode.parentNode.parentNode
                        .removeChild(node.parentNode.parentNode);
            }
        }

        var addBtn = document.getElementById("add");
        addBtn.onclick = function() {
            //3个引用的value值可以获取到文本框的值
            var nameNode = document.getElementById("name");
            var emailNode = document.getElementById("email");
            var salaryNode = document.getElementById("salary");

            //获取table元素节点
            var tableNode = document.getElementsByTagName("table")[1];
            //创建一个tr节点,后面会添加到table元素节点中
            var newTrNode = document.createElement("tr");
            //创建一个td节点,后面会添加到tr元素节点中
            var newName = document.createElement("td");
            //创建一个文本节点,添加到td元素节点中
            newName.appendChild(document.createTextNode(nameNode.value));

            var newEmail = document.createElement("td");
            newEmail.appendChild(document.createTextNode(emailNode.value));

            var newSalary = document.createElement("td");
            newSalary.appendChild(document.createTextNode(salaryNode.value));

            var newDelete = document.createElement("td");
            var newDeleteBtn = document.createElement("input");
            newDeleteBtn.type = "button";
            newDeleteBtn.name = "delete";
            newDeleteBtn.value = "Delete";
            //新创建的button也应该能触发删除函数
            newDeleteBtn.onclick = function() {
                deleteInfo(this);
            }
            newDelete.appendChild(newDeleteBtn);

            newTrNode.appendChild(newName);
            newTrNode.appendChild(newEmail);
            newTrNode.appendChild(newSalary);
            newTrNode.appendChild(newDelete);

            tableNode.appendChild(newTrNode);
        }

        //为所有已经存在的删除按钮添加删除函数事件
        var deleteNodes = document.getElementsByName("delete");
        var length = deleteNodes.length;
        for (var i = 0; i < length; i++) {
            deleteNodes[i].onclick = function() {
                deleteInfo(this);
            }
        }
    }
</script>

今天就到这里,我们下次再见!

再战JavaScript

标签:

原文地址:http://www.cnblogs.com/LeaderHonestQuality/p/5666391.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!