美文网首页技术栈我爱编程
JavaScript DOM练习,简易备忘录1.0版本

JavaScript DOM练习,简易备忘录1.0版本

作者: LeeYaMaster | 来源:发表于2018-06-02 13:48 被阅读168次

    我是一名前端爱好者,在学习了JavaScript DOM操作之后,突发奇想,写了一个备忘录,虽然还没保存以及动画功能,但是在2.0版本,我会实现以及优化。虽然这只是一个简易的备忘录,但是里面的干货满满哟!废话不多说,我们一起来看看有哪些知识点以及细节:

    1,弹性盒子布局

    2,绝对定位的使用

    3,rem与px

    4,获取input文本信息

    5,添加节点

    6,删除节点

    7,多选/取消按钮切换(精华)

    8,批量删除

    9,红色提示框显示与隐藏

    10,源码及下载地址

    项目截图:

    手机端

    1,弹性盒子布局,这是CSS3才出现的布局,flex布局具有便捷、灵活的特点,熟练的运用flex布局能解决大部分布局问题,特别对手机端适配很好,以及一些特殊布局,但是笔者认为这种布局适用于body以及主体那种大范围布局,对于一些细小的布局,则不太擅长,例如右上的多选按钮。

    弹性盒子布局

    html代码

     <body>
            <header></header>
             <div class="container"></div>
            <footer></footer>
    </body>
    

    css代码

    body{
            width: 100%;
            height: 100%;
            display: flex;
            display: -webkit-flex;
            flex-direction: column;
            -webkit-flex-direction: column;
            margin: 0;
            padding: 0;
            font-family: "微软雅黑";
            z-index: 1;
    }
    
    header{
            background-color: #18B4ED;
            position: relative;
            height: 4rem;
    }
    footer{
            background-color: #F2F2F2;
            height: 2.5rem;
    }
    .container{
            background-color: #F2F2F2;
            flex: 1;    
    }
    

    这里body设置成display: flex;便变成了弹性盒子布局,在里面,浮动,vertical,定位不起作用,但是只相对于它的第一层子元素,flex-direction:column 使整体布局从上到下排列,flex-direction:row,则是从左到右,
    flex-grow:1, 应用于container,使得container自动填充剩余空间,从而实现上中下布局(中间主体部分自适应)

    2,右上绝对定位
    绝对定位:绝对定位是不占位置的,它会像PS的图层一样单独做一层,至于第几层你可以通过[z-index]这个属性来设置,设置时,父元素可以设置position:relative;定位等等,这样他就是相对于父容器进行定位,如果没设置,则依次往上找,直到找到html这个节点。

    相对定位:相对定位的参照物是本身,在使用相对定位时,无论是否进行移动,元素仍然占据原来的空间。因此,移动元素会导致它覆盖其它框。

    使用场景:当你在你的显示屏下使用绝对定位的时候,会发现在其他显示器,布局会发生错乱,平板端,手机端同理,所以绝对定位很少用,但是,例如弹窗,或者侧边栏,亦或者此项目的右上按钮,则用绝对布局较好。所以定位最好依赖于父级元素的位置,而不能依赖于设备的高度和宽度,因为设备的宽总是在变化。

    这里的定位有一个小技巧,设置了CSS属性后,点开网页,打开F12调试工具,选中要进行定位的元素, F12的右下方,盒子模型会显示出定位的位置,在那里进行调试,会更加方便,如图: 使用F12调试工具进行定位

    我的绝对定位代码如下:

            z-index: 2;
            position: absolute;     
            right: 10px;
            top: 10px;
    

    这段代码z-index: 2;,在body设置成z-index:1,则定位位于body的上方,可以理解成PS的图层,这里的绝对定位,由于在header设置父元素,所以相对于它定位。

    3,rem与px
    px是你屏幕设备物理上能显示出的最小的一个点,这个点不是固定宽度的,不同设备上点的长宽、比例有可能会不同,电脑端,手机端,平板端,或者网吧的超宽屏幕等等。假设:你现在用的显示器上1px宽=1毫米,但我用的显示器1px宽=两毫米,我们两者看到的都会不一样,我的会变宽两倍。

    em尺寸:所有现代浏览器下默认字体尺寸是16px,例如谷歌,这时1em=16px。然后你人为的把body里面定义font-size:12px;(把浏览器默认16px改小了),此刻1em=12px。听起来虽然好,但是有个缺点,就是它继承父元素,例如在它的父元素设置font-size:20px;之后,那个地方的1em=20px了。而页面要整体,所以才有了rem。

    rem尺寸:em和rem都是CSS3的属性,rem只根据html或body的字体尺寸,这对于开发者来说更友好,美中不足的是部分浏览器不兼容,例如IE6-IE8。

    因为移动端的屏幕特殊之处,主要是不同类型手机像素比dpr的不同,所以不能直接使用px来进行设置元素的尺寸,为了适应手机端,使用rem保证了不同设备下视觉体验的一致性。

    4,获取input输入信息
    html代码

      <input type="text" placeholder="请输入备注信息" class="search-input" id="input"/>
      <button type="submit" class="search-btn" onclick="add()">添加</button>
    

    js代码

      var input = document.getElementById("input");
      function add(){
        var input_value = input.value;
        //jq的写法input_value = $("#input").val();
        //如果未输入,则返回
        if(input_value == ""){
            alert("请输入内容");
            return;
        }
        console.log(input_value);
        //清空输入的文本
        input.value = "";
      }
    

    错误代码

    var input = document.getElementById("input").value;
    

    这样会报错,显示input.value == null,因为你是点击按钮后,才获取,并且是实时的,所以应该放在函数里面,而不能在外面直接写死,这个在安卓开发中也很常见,另外,测试的时候,使用console.log比alert好,因为可以查看参数。

    5,添加节点

    function add(){
                //创建一个P标签的节点
                var content = document.createElement("p");
                //给节点添加html标签,如果只添加纯文本则使用.innerText方法,添加的时候使用字符串拼接
                content.innerHTML = "<input type='checkbox' class='show checkbox' name='check'/>"+input_value+
                        "<button class='btn_remove' onclick='remove(this)'>删除</button>";
                }
              //把刚才创建的节点,添加到main_content这个主体内容块上面去
                main_content.appendChild(content);
            }
    

    错误代码

     main_content.appendChild(input_value);
    
    使用错误代码,这里会报错,图上的234是测试用的,不用看 报错信息

    意思是input_value只是一个字符串,并不是节点,必须要用节点把字符串包起来才可以使用。

    6,删除节点
    在添加节点的时候,设置

            <button class='btn_remove' onclick='remove(this)'>删除</button>
    

    其中,必须设置参数,不然会删除其他的元素。

            function remove(obj){
                obj.parentNode.parentNode.removeChild(obj.parentNode);  
            }
    

    这里的obj.parentNode.parentNode指代的是它的父元素的父元素,使用删除方法时,必须声明要删除元素的父元素,才可以使用此方法,这段代码意思是,我要指定它的父元素的父元素,删除它的父元素。因为此项目中,不是删除本身,而是删除一整行话。以下代码,则是删除自己本身。

           function remove(obj){
              obj.parentNode.removeChild(obj);  
           }
    

    7,多选/取消按钮切换(精华)
    点击多选按钮,切换成取消按钮,在同一位置,这是笔者之前写的冗余代码:
    html部分:

        <button type="submit" class="nav-choice" onclick="choice_fun()" id="choice">多选</button>
        <button type="submit" class="nav-cancel" onclick="cancel_fun()" id="cancel">取消</button>
    

    css部分:

            .nav-choice{
                display: block;
                background-color: #12B7F5;
                border: 0;
                color: #fff;
                height: 2.5rem;
                z-index: 2;
                position: absolute;     
                right: 10px;
                top: 10px;
            }
           .nav-cancel{
                display: none;
                background-color: #12B7F5;
                border: 0;
                color: #fff;
                height: 2.5rem;
                z-index: 2;
                position: absolute;     
                right: 10px;
                top: 10px;
            }
    

    js部分:

            var choice = document.getElementById("choice");
            var cancel = document.getElementById("cancel");
            //多选,取消切换
            function choice_fun(){
                choice.style.display = "none";
                cancel.style.display = "block";
                btn_remove_bg.style.display = "block";
                for(var i = 0;i<main_check.length;i++){
                    main_check[i].className = 'show checkbox';
                }
            }
            //多选,取消切换
            function cancel_fun(){
                choice.style.display = "block";
                cancel.style.display = "none";
                btn_remove_bg.style.display = "none";
                for(var i =0;i<main_check.length;i++){
                    main_check[i].className = 'hide checkbox';
                }
            }
                    
    

    补充一下,JS上面有些代码,是其他模块的,在此功能中,只看方法里第一,二行。

    我们会发现,css和js代码,除了参数不一样,结构都一样,这里就要用到Java的封装思想啦,其实每种编程语言都有这种思想,把重复的代码提取出来,封装成一个方法,然后调用这个方法传入参数就可以啦,于是,笔者这样实现,使用了三目运算符:
    html部分:

    <button type="submit" class="nav-change show" onclick="change(true)" id="choice">多选</button>
    <button type="submit" class="nav-change hide" onclick="change(false)" id="cancel">取消</button>
    

    css部分:

            .nav-change{
                background-color: #12B7F5;
                border: 0;
                color: #fff;
                height: 2.5rem; 
                z-index: 2;
                position: absolute;     
                right: 10px;
                top: 10px;
            }
          
            .hide{
                display: none;
            }
            .show{
                display: show;
            }
    

    .hide和.show这两个CSS样式,是非常常见的,建议单独抽离出来,因为其他地方也肯定会用到,我也是看了bootstrap的源码,获得的这个思想,强烈建议用这个方式!
    js部分:

            var choice = document.getElementById("choice");
            var cancel = document.getElementById("cancel");
            function change(status){
                choice.style.display = status?"none":"block";
                cancel.style.display = status?"block":"none";
                btn_remove_bg.style.display = status?"block":"none";
                for(var i = 0;i<main_check.length;i++){
                    main_check[i].className = status?'show checkbox':'hide checkbox';
                }
            }
    

    使用三目运算符替代if,else,大大优化代码!强力建议!

    8,批量删除

    这里是之前用JS动态添加的节点代码,可以添加多个:

      <input type='checkbox' class='show checkbox' name='check'/>
    

    错误代码:

              var main_check = document.getElementsByName('check');
              function remvoe_check(){
                for(var i = 0;i<main_check.length;i++){
                    if(main_check[i].checked){
                        remove(main_check[i]);  
                    }
                }
              }
    

    代码讲解:1、这里的remove()方法,为之前的单个删除,直接复用之前的方法就行了。
    2、.checked为多选框选中时的状态
    3、getElementsByName获取到的是类数组,需要用for遍历出来
    4、用remove(main_check[i]);而不是remove(this);是因为this指代的函数方法执行的地方,这里指代删除按钮。

    至于为什么是错误代码,相信你使用了会发现,你勾选了6个,点击多选删除,却只能删除3个,勾选4个,删除2个,每次都只删一半,原因就在.length里面,你点击删除后,数组的长度会发生改变,所以需要在后面加上i--,才是最终的答案!
    正确代码:

                     function remvoe_check(){
                for(var i = 0;i<main_check.length;i++){
                    if(main_check[i].checked){
                        remove(main_check[i]);
                        i--;
                    }
                }
            }
    

    9,红色提示框显示与隐藏,我们点击添加之后,(你当前还没有待办事项哦!)这句话会消失,点击删除,当没有添加的备忘录时,会显示。嗯!相信我们第一下就想到了:监听!在Vue或者Angular等MVVM框架一行代码就可以实现,但是JS并不能实时监控呀,于是我们可以这样做:
    html部分:

                <div class="main_content" id="main_content">
                    <p class="main_hint">&nbsp;&nbsp;&nbsp;你当前还没有待办事项哦!</p>
                </div>
    

    js部分:

            function main_hint_change(){
                if(main_content.childElementCount > 1){
                    main_hint.className = "hide main_hint";
                }else{
                    main_hint.className = "show main_hint";
                }
            }
    

    代码讲解:childElementCount 意思为子元素的个数,一般是>0,但是此项目我把它本身也写进去了,所以是>1,但是问题来了?你并不能实时调用啦?其实,我们可以这样做:

            function remove(obj){
                //以上代码省略
                main_hint_change();
            }
            function add(){ 
                //以上代码省略
                main_hint_change();
            }
    

    于是便可以实时监控啦~~~

    10,源码:https://gitee.com/HuangJiaGongJue/Memo
    备忘录2.0版本:https://www.jianshu.com/p/10bddb2a349e
    此项目为一个小demo,供学习使用,目前我还正处于学习阶段,如果大家有更好的代码方式,可以指出来,我也好学习学习。

    相关文章

      网友评论

        本文标题:JavaScript DOM练习,简易备忘录1.0版本

        本文链接:https://www.haomeiwen.com/subject/dlrlsftx.html