技术栈我爱编程

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

2018-06-02  本文已影响168人  LeeYaMaster

我是一名前端爱好者,在学习了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,供学习使用,目前我还正处于学习阶段,如果大家有更好的代码方式,可以指出来,我也好学习学习。

上一篇下一篇

猜你喜欢

热点阅读