我是一名前端爱好者,在学习了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"> 你当前还没有待办事项哦!</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,供学习使用,目前我还正处于学习阶段,如果大家有更好的代码方式,可以指出来,我也好学习学习。
网友评论