在我们写页面时,
有时会发现自己写的css样式无法生效,导致这种现象的原因有很多,下面列举一些常见的原因希望可以帮到你,欢迎评论区补充。
如果你反复检查认为代码没有问题,那么可能是浏览器缓存的问题。在排查前先试一下清除浏览器缓存,重启浏览器或者换个浏览器等手段,无效后再进行进一步排查。有可能自己什么都没有做错,就是因为缓存或者浏览器的问题导致,重置一下也许问题就解决了。
浏览器的‘F12’元素审核,看看哪些样式没有应用上。
写错属性名致使无法与html匹配,或属性值不符合规范;
html标签没写完整,漏了“<”或者”>”等;
,;{}看看这些符号是不是不小心使用了中文或者全角符号;
<span>设CSS样式不起作用:例如:要定义span居中,必须先让span成块级元素显示,也就是说,要先定义span的display:block;属性,然后再给span添加边距属性margin:0px auto;
css样式中间没有加分号;
为什么css样式里有时候使用分号隔开有时候是用空格呢?
对同一个属性进行设置时是用空格隔开,比如border:1px solid red; 对不同的属性进行设置时是用分号隔开,比如width:300px;height:300px;
如果你的样式完全不生效,首先确认关联了样式表没有,或者关联的样式位置、名字是否正确;
<link rel="stylesheet" type="text/css" href="mycss.css"/>
看看自定义的CSS样式引入标签是否放在bootstrap框架样式引用之后,确保不会被在加载页面时被框架的样式覆盖。
<link rel="stylesheet" type="text/css" href="css/bootstrap.css"/> <link rel="stylesheet" type="text/css" href="mycss.csvs"/>
后代子代选择等,涉及多个标签,类名、id等,子选择器的顺序、名字等写错了,均可能导致出错;
html里的标签忘记写类名、id了,而选择器用了这些漏写的类名、id等,样式自然不会生效。
后代选择器忘了写空格;
看看是不是有多余的空格比如: div.box{} 这类选择器会不会写成了 div .box{};
把CSS、HTML网页文件都统一保存为UTF-8格式;即在头标签中添加<meta charset="UTF-8">
因为 一般网页里采用UTF-8的编码格式,而外部的CSS文件默认的是ANSI的编码格式,一般情况下是不会有问题。然而当CSS文件中包含中文注释,就可能会出现问题。
样式层叠问题
看看你的css优先级是否出现问题,优先级高的会把低的覆盖掉导致无法看到样式;
本身设置了样式,则从父级继承来的样式就不生效了;
css样式优先级排序:!important > 行内样式>ID选择器 > 类选择器 > 标签 > 通配符 > 继承 > 浏览器默认属性(同优先级时,后面的层叠前面的样式);
排查顺序:
XHTML
是可扩展超文本标记语言,是一种更纯洁,更严格,更规范的html
代码。html
文件由文件头和文件体两部分组成。标签的分类:双标签,单标签。
HTML的全局标准属性
在HTML中,规定了8个全局标准属性。
class用于定义元素的类名。
id用于指定元素的唯一id。
style用于指定元素的行内样式。
title用于指定元素的额外信息。
accesskey用于指定激活某个元素的快捷键。
支持accesskey属性的元素有<a>, <area>, <button>, <input>, <label>, <legend>, <textarea>。
tabindex用于指定元素在tab键下的次序。
支持tabindex属性的元素有<a>,<area>,<button>,<input>,<object>,<select>,<textarea>
dir用于指定元素中内容的文本方向。
dir的属性值只有ltr和rtl两种,分别是left to right和right to left。
lang用于指定元素内容的语言。
HTML的全局事件属性
Window窗口事件
onload,在页面加载结束后触发。
onunload,在用户从页面离开时触发,如单击跳转,页面重载,关闭浏览器窗口等。
Form表单事件
onblur,当元素失去焦点时触发。
onchange,在元素的元素值被改变时触发。
onfocus,在元素获得焦点时触发。
onreset,当表单中的重载按钮被点击时触发。
onselect,在元素中文本被选中后触发。
onsubmit,在提交表单时触发。
Keyboard键盘事件
onkeydown,在用户按下按键时触发。
onkeypress,在用户按下按键后,按着按键时触发。
该属性不会对所有按键生效,不生效按键如:alt,ctrl,shift,esc。
onkeyup,当用户释放按键时触发。
Mouse鼠标事件
onclick,当在元素上单击鼠标时触发。
onblclick,当在元素上双击鼠标时触发。
onmousedown,当在元素上按下鼠标按钮时触发。
onmousemove,当鼠标指针移动到元素上时触发。
onmouseout,当鼠标指针移出元素时触发。
onmouseover,当鼠标指针移动到元素上时触发。
onmouseup,当在元素上释放鼠标按钮时触发。
Media媒体事件
onabort,当退出媒体播放器时触发。
onwaiting,当媒体已停止播放但打算继续播放时触发。
HTML元素
<!DOCTYPE>
,声明文档类型。<html>
,HTML元素真正的根元素。<head>
,定义html
文档的文档头。
head中包含的元素 title,定义HTML文档的标题 base,为页面上的所有链接规定默认地址或者默认目标 link,用于定义文档与外部资源之间的关系 meta,提供关于HTML的元数据 style,用于为HTML文档定义样式信息 script,用于定义客户端脚本
body
,定义html
文档的文档体。content-Type
,用于设定网页的字符集,便于浏览器解析与渲染页面。cache-control,用于告诉浏览器如何缓存某个响应及缓存多长时间。
参数:
no-cache,发送请求,与服务器确认该资源是否被更改,如果没有,则使用缓存
no-store,允许缓存,每次都要去服务器上下载完整的响应
public,缓存所有响应
private,只为单个用户缓存
max-age,表示当前请求开始,相应响应在多久内能被缓存和重用,不去服务器重新请求,max-age=60表示响应可以再缓存和重用60秒
<meta http-equiv=cache-control" content="no-cache">
1
expires,用于设定网页的到期时间,过期后重新到服务器上重新传输。
refresh,网页将在设定的时间内,自动刷新并转向设定的网址
Set-Cookie,用于设置网页过期。
无语义元素:<span>,<div>,<span>是内联标签,用在一行文本中,<div>是块级标签。
div用于存放需要显示的数据,css用于指定如何显示数据样式,做到结构与样式相互分离。
查看div+css样式HTML:点击下方链接跳转,可查看源码:
div-css.html
格式化元素
普通文本
<b>,定义粗体文本
<big>,定义大号字
<em>,定义着重文字
<i>,定义斜体字
<small>,定义小号字
<strong>,定义加重语气
<sub>,定义下标字
<sup>,定义上标字
<ins>,定义插入字
<del>,定义删除字
计算机输出
<code>,定义计算机代码
<kbd>,定义键盘输出样式
<samp>,定义计算机代码样本
<tt>,定义打字机输入样式
<pre>,定义预格式文本
术语
<abbr>,定义缩写
<acronym>,定义首字母缩写
<address>,定义地址
<bdo>,定义文字方向
<blockquote>定义长的引用
<q>,定义短的引用语
<cite>,定义引用,引证
<dfn>,定义一个概念,项目
图像热区链接
图像热区链接,是什么呢?当你在看一些购物网页的时候,一张图片上,可以在不同的地方链接到不同的目标位置,点击不同的地方可以跳转到不同的网页,这也是做商城项目一般要用到的技术。
这个时候不是<a>标签元素了,而是<area>元素。
<area>元素的属性有两个shape,cords属性。
<area>
的坐标系,原点为图片的左上角,x轴正方向向右,y轴正方向向下
我画个图哈,反映<area>
的坐标系:
图像热区链接的使用,<map>标签定义一个image-map,可以含一个以上的热区<area>,每个热区都有独立的链接。
要为<map>标签赋予name属性。
将<img>标签的usemap属性与<map>标签的name属性相关联。
为了证明我学会了,我写一个html页面。
map -> name="image_link"
img -> usemap="#image_link"
1
点击跳转:imgmap.html
e-mail链接
e-mail链接主要是看到有很多官方网页需要做的一个打开一封新的电子邮件。
点击下方链接即可看到效果:
联系我们
代码:
<a href="mailto:xxxxxx@qq.com">联系我们</a>
列表元素
整合列表html网页,点击跳转:ul-ol.html
无序列表,<ul>定义无序列表,<li>定义列表项。
<ul>的type属性值:disc点,square方块,circle圆,none无.
有序列表,<ol>定义有序列表,<li>定义列表项。
<ol>的type属性值:数字,大写字母,大写罗马数字,小写字母,小写罗马数字。
start属性定义序号的开始位置。
定义列表<dl>,定义列表内部可以有多个列表项标题,每个列表项标题用<dt>标签定义,列表项标题内部又可以有多个列表项描述,用<dd>标签定义。
表格
整合表格html网页,点击跳转:table.html
<table>定义表格
<caption>定义表格标题
<tr>定义若干行
<td>定义若干单元格
<th>定义表头
表格分头部,主体,底部:<thead>,<tbody>,<tfoot>三个标签。
<td>
的两个属性:colspan
用于定义单元格跨行,rowspan
用于定义单元格跨列<tbody>,<thead>,<tfoot>
标签通常用于对表格内容进行分组。<form>
标签定义,action
属性定义了表单提交的地址,method
属性定义表单提交的方式。
<input type="text"> <input type="password"> <input type="radio"> <input type="checkbox"> <input type="submit"> <input type="reset"> <input type="button"> <input type="image"> <input type="file"> <input type="hidden">
<textarea>
元素
<textarea>
标签具有name,cols,rows
3个属性。
name
用于提交参数value
用于输入文本内容cols
和rows
分别用于文本框的列数和行数,宽度和高度。效果:
自我评价:
代码:
<form action="web" method="post"> 自我评价:<br/> <textarea rows="10" cols="50" name="introduce"> </textarea> <br/> <input type="submit" id="" name=""> </form>
<frameset>
定义一个框架集,用于组织多个窗口,每个框架存有独立的html文档<frameset>
不能与<body>
共同使用,除非有<noframe>
元素<frame>
用于定义<frameset>
中一个特定的窗口。空元素<frame/>
: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>frameset</title> </head> <frameset cols="25%,50%,25%"> <frame src="https://blog.csdn.net/qq_36232611" scrolling="no" noresize="noresize"></frame> <frame src="https://juejin.im/user/5e477d7ce51d4526c550a27d" ></frame> <frame src="https://www.jianshu.com/u/c785ece603d1" ></frame> </frameset> <noframes> <body>您的浏览器无法处理框架,请更换浏览器打开</body> </noframes> </html> 1
显示结果 描述 实体名称 实体编号
空格  
< 小于号 < <
> 大于号 > >
& 和号 & &
" 引号 " "
' 撇号 ' (IE不支持) '
¢ 分(cent) ¢ ¢
£ 镑(pound) £ £
¥ 元(yen) ¥ ¥
€ 欧元(euro) € €
§ 小节 § §
© 版权(copyright) © ©
® 注册商标 ® ®
™ 商标 ™ ™
× 乘号 × ×
÷ 除号 ÷ ÷
————————————————
版权声明:本文为CSDN博主「达达前端」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_36232611/article/details/105109467
用户体验地图(Customer Journey Map)是什么?
用户体验地图是从用户的视角出发,去理解用户、产品或者服务交互的一个重要的设计工具。
也可以说是以可视化的形式,来表现一个用户使用产品或者接受服务的体验情况,从体验的过程中来发现用户在整个体验过程中的问题点与情绪点,以此来从中提取出产品的优化点,方便对产品进行迭代,从而保证良好的用户体验。
经典案例
Chris Risdon绘制的欧洲铁路购票的体验地图
上图中是欧洲铁路公司整个体验地图的一部分。欧洲铁路公司是一家美国经销商,为北美旅客提供一个独立预订火车票去欧洲各地的平台,而无需用户去网站预定。他们已经拥有了一个良好体验的网站和一个屡获殊荣的咨询中心,但他们希望通过所有接触点来优化用户使用过程,这样可以让他们更全面地了解,他们应该专注的投资,设计和技术资源。整体的“诊断”评价系统,包含一系列的重点举措,体验地图只是其中派生的一部分。体验地图帮助建立同理心图,来理解随着时间和空间的推移,用户与欧洲铁路公司服务系统交互时接触点的变化。
在这张体验地图中采用了五个关键组成一个体验地图,一个体验地图可以直观的表示用户操作流、期望、特定的目标、用户情绪状态和整体的体验点,做到整体把控和评估产品体验。
作用 :
用户体验地图能帮助我们创造出一个有大局观的用户体验,更好的帮助我们理解用户的痛点和需求,帮助Team达成共识,非常有利于跨团队合作。
用户体验地图包含的内容 :
其中包括,人群(产品的用户是哪一类人)、 用户的需求(用户想得到什么)、 路径(在某特定的场景下体验的整体过程) 、接触点 (产品与人或人与服务接触的关键点)、行为(用户的行为是什么样的?)、情绪 (体验过程中的感受心情) 、机会点 (过程中可以突破的点,可以成为特色的地方)、 解决方案 (解决用户在体验过程的痛点)、 问题 (解决用户在体验过程的痛点)。
用户画像 :
在准备开始绘制用户体验地图的时候,我们应该要确立用户群体 / 确定产品目标 / 了解用户目标,并作出用户画像。
视觉设计师怎么使用
举例(一):
那我们看看作为一名视觉设计师应该关注哪部分的流程。
视觉设计师的用户体验地图 :
我们的聚焦点应在上图的这几个部分。
所以当绘制完用户体验地图后,应该再绘制一份视觉设计师看的版本,我们设计师主要关注的视觉的触点。
定量方法(产品方向):
我们在行为和情绪上一般会使用问卷法、后台数据分析法;而在需求和问题上一般会使用焦点小组、访谈法、观察法、日志法和田野调查,下面就为大家来解释下这些方法。
焦点小组:是指从研究产品中所确定的全部用户群(总体)中抽取一定数量的用户来组成样本,根据样本信息推断用户群总体特征的一种调查方法。
访谈法:访谈,就是以口头形式向用户进行询问,根据被询用户的答复搜集客观的、不带偏见的事实信息,以准确地说明样本所要代表的总体的一种方式。
观察法:观察法是指研究者根据一定的研究目的、研究提纲或观察表,用自己的感官和辅助工具去直接观察用户,从而获得资料的一种方法。
日志法:是由用研人员按时间顺序,详细记录自己在一段时间内使用产品的过程,经过归纳、分析,达到分析产品目的的一种工作分析方法。
田野调查:在日常生活中,在一个有一个严格定义的空间和时间的范围内,体验特定用户群的日常生活与思想境界,通过记录自己的生活的方方面面,来展示不同阶段用户群的基本需求。
注意事项(5要点)
1. 在制作地图前,应理清楚产品的前期规划和需求,并且与同事达成共识。
2. 避免以自己的经验或者认知来确定用户体验地图中的接触点,应当真正的从用户的行为中去提取。
3. 不要将一些落后的信息加入到用户体验地图中。
4. 最好先在Team内部脑暴一份地图,再去与所制作的地图进行对比。
5. 用户体验地图不会涉及到实现方案和现实机制,只涉及用户的体验。
团队人员的合理搭配 :
将公司或者团队的PM、RD、运营、Leader等过来,详细的描述这一份用户体验地图,聆听他们的反馈。
在分析用户问题上 :
分为四个等级:ABCD,在对优先级进行排列的同时应该,考虑到产品在每个阶段的侧重点,根据不同的进度和情况,来对优先级进行排列,帮助我们整理问题和提炼最核心的一些体验问题,区分问题还能帮助我们更好的把握产品的优化方向。
视觉设计师应该关注的点 :
视觉设计师的任务是什么?是有效的传达出产品的信息、简洁并且优雅的传达、通过视觉设计制造出愉悦的用户体验。用户在很多的场景下都可能接触到企业的产品或者是服务,这个服务接触带给用户的感受更多是偏向于视觉感知方面的。所以我们需要尽可能的列举出企业的产品或者服务与用户可能产生接触的场景、服务触点,再根据服务触点延伸出相关的“视觉触点”,用来梳理出我们需要输出的视觉产物,做出相对应的查漏补缺和优化,输出指导企业的品牌建设工作。而用户体验地图就很适合作为这样的工具。
“体验地图”对于优化视觉体验的意义 :
整体性:系统性地规划品牌的视觉统一化工作,提升品牌建设工作的全面性和完整度。也可以避免未来工作中不同的品牌 / UI / 运营设计师对于品牌概念的理解不同而带来的设计出入。
品牌设计,是用户对于公司产品的直接印象,所以在品牌设计的要求就是:建立特征、保持特征、推广特征、美化特征、对于以上的要求,来提供完整且匹配的设计方案。
运营设计,运营设计的目标就是让用户尽可能的感知到产品的好,把产品的特点通过设计包装传递给用户,一个好的运营设计,应该是在用户看到你的设计作品后,会产生足够好的兴趣和好感,并愿意去关注你的产品。
UI设计,这是产品与用户接触过程中,频率最高、最直观的部分,目的是为了让用户认识到产品的相貌和气质,UI设计需要注意界面视觉层次的强弱、信息划分、用户的视线轨迹、色彩的表达、质感、舒适度等,来让用户觉得这个产品设计真好。
例如 :
OFO,以年轻人为主的共享骑行产品,无论是在品牌/运营/UI的设计上,都能让人感觉时尚、年轻、阳光、且有亲和力。
品牌设计 :
UI设计 :
运营设计 :
UI设计 :
运营设计 :
设计师的进阶 :
在一开始的初级设计师阶段(也就是1.0阶段),我们需要从交互设计师手中接过交互设计稿,来对它进行气质进行改造,做出独特的视觉设计,也就是将其翻译为高保真稿,然后再与开发同学进行对接,也要保持视觉走查,以防实际效果与预期效果的不符;在这个1.0阶段我们的表现力和创造力,是最为主要的,如何去做出差异化?这是这个阶段的设计师需要考虑的,在这个APP设计趋同的大浪潮下,你如果能够做出不一样的设计,那么你则可以一鸣惊人,从众多水平相当的设计师中脱颖而出,这时你便可以考虑进入下一个阶段,也就是2.0。
在高级设计阶段(即2.0阶段),这时候你就需要拥有更好的产品思维和逻辑能力,不仅仅只是从交互设计师拿到交互设计稿,直接上手开做,在这之前,你需要开始了解产品的业务定位、用户人群、产品目标、当前的问题、未来的迭代等,需求方这时候就成你的主要对接对象,需要你具备拆解需求、采集用户的需求、扩展业务、能进行设计验证的能力,能将产品的气质和品牌贯穿于整个产品(UI/运营/品牌),设计是怎么推导的,现在就不是仅仅只在停留在好看的层面上了,毕竟设计师不是画师,而是解决问题的,我们在做了某个设计后,就要去关注它的变化了,看看用户的反馈、商业转化率等等,这都是为你的下一次设计迭代做的参考。
从
分享到脉脉
转自:脉脉
原文链接:https://maimai.cn/article/detail?fid=988630001&efid=N-uHKNnf7vXGBmaFd3lZHA&use_rn=1
本文讲述,在使用VUE的移动端实现类似于iPhone的悬浮窗的效果。
相关知识点
touchstart 当在屏幕上按下手指时触发
touchmove 当在屏幕上移动手指时触发
touchend 当在屏幕上抬起手指时触发
mousedown mousemove mouseup对应的是PC端的事件
touchcancel 当一些更高级别的事件发生的时候(如电话接入或者弹出信息)会取消当前的touch操作,即触发touchcancel。一般会在touchcancel时暂停游戏、存档等操作。
效果图
实现步骤
1.html
总结了一下评论,好像发现大家都碰到了滑动的问题。就在这里提醒一下吧。可将该悬浮 DIV 同你的 scroller web 同级。 —- (log: 2018-08-21)
html结构: <template> <div>你的web页面</div> <div>悬浮DIV</div> </template>
<template> <div id="webId"> ... <div>你的web页面</div> <!-- 如果碰到滑动问题,1.1 请检查这里是否属于同一点。 --> <!-- 悬浮的HTML --> <div v-if="!isShow" class="xuanfu" id="moveDiv" @mousedown="down" @touchstart="down" @mousemove="move" @touchmove="move" @mouseup="end" @touchend="end" > <div class="yuanqiu"> {{pageInfo.totalPage}} </div> </div> ... </div> </template>
2.JS
<script> data() { return { flags: false, position: { x: 0, y: 0 }, nx: '', ny: '', dx: '', dy: '', xPum: '', yPum: '', } } methods: { // 实现移动端拖拽 down(){ this.flags = true; var touch; if(event.touches){ touch = event.touches[0]; }else { touch = event; } this.position.x = touch.clientX; this.position.y = touch.clientY; this.dx = moveDiv.offsetLeft; this.dy = moveDiv.offsetTop; }, move(){ if(this.flags){ var touch ; if(event.touches){ touch = event.touches[0]; }else { touch = event; } this.nx = touch.clientX - this.position.x; this.ny = touch.clientY - this.position.y; this.xPum = this.dx+this.nx; this.yPum = this.dy+this.ny; moveDiv.style.left = this.xPum+"px"; moveDiv.style.top = this.yPum +"px"; //阻止页面的滑动默认事件;如果碰到滑动问题,1.2 请注意是否获取到 touchmove document.addEventListener("touchmove",function(){ event.preventDefault(); },false); } }, //鼠标释放时候的函数 end(){ this.flags = false; }, } </script>
3.CSS
<style> .xuanfu { height: 4.5rem; width: 4.5rem; /* 如果碰到滑动问题,1.3 请检查 z-index。z-index需比web大一级*/ z-index: 999; position: fixed; top: 4.2rem; right: 3.2rem; border-radius: 0.8rem; background-color: rgba(0, 0, 0, 0.55); } .yuanqiu { height: 2.7rem; width: 2.7rem; border: 0.3rem solid rgba(140, 136, 136, 0.5); margin: 0.65rem auto; color: #000000; font-size: 1.6rem; line-height: 2.7rem; text-align: center; border-radius: 100%; background-color: #ffffff; } </style>
实现好JS逻辑,基本上,问题不大。
本文链接 http://www.luyixian.cn/javascript_show_166242.aspx
再加一点
css之display:inline-block布局
1.解释一下display的几个常用的属性值,inline , block, inline-block
两个图可以看出,display:inline-block后块级元素能够在同一行显示,有人这说不就像浮动一样吗。没错,display:inline-block的效果几乎和浮动一样,但也有不同,接下来讲一下inline-block和浮动的比较。
2.inline-block布局 vs 浮动布局
a.不同之处:对元素设置display:inline-block ,元素不会脱离文本流,而float就会使得元素脱离文本流,且还有父元素高度坍塌的效果
b.相同之处:能在某程度上达到一样的效果
我们先来看看这两种布局:
图一:display:inline-block
图二:
对两个孩子使用float:left,我在上一篇浮动布局讲过,这是父元素会高度坍塌,所以要闭合浮动,对box使用overflow:hidden,效果如下:
>>乍一看两个都能做到几乎相同的效果,(仔细看看display:inline-block中有间隙问题,这个留到下面再讲)
c.浮动布局不太好的地方:参差不齐的现象,我们看一个效果:
图三:
图四:
>>从图3,4可以看出浮动的局限性在于,若要元素排满一行,换行后还要整齐排列,就要子元素的高度一致才行,不然就会出现图三的效果,而inline-block就不会。
3.inline-block存在的小问题:
a.上面可以看到用了display:inline-block后,存在间隙问题,间隙为4像素,这个问题产生的原因是换行引起的,因为我们写标签时通常会在标签结束符后顺手打个回车,而回车会产生回车符,回车符相当于空白符,通常情况下,多个连续的空白符会合并成一个空白符,而产生“空白间隙”的真正原因就是这个让我们并不怎么注意的空白符。
b.去除空隙的方法:
1.对父元素添加,{font-size:0},即将字体大小设为0,那么那个空白符也变成0px,从而消除空隙
现在这种方法已经可以兼容各种浏览器,以前chrome浏览器是不兼容的
图一:
c.浏览器兼容性:ie6/7是不兼容 display:inline-block的所以要额外处理一下:
在ie6/7下:
对于行内元素直接使用{dislplay:inline-block;}
对于块级元素:需添加{display:inline;zoom:1;}
4.总结:
display:inline-block的布局方式和浮动的布局方式,究竟使用哪个,我觉得应该根据实际情况来决定的:
a.对于横向排列东西来说,我更倾向与使用inline-block来布局,因为这样清晰,也不用再像浮动那样清除浮动,害怕布局混乱等等。
b.对于浮动布局就用于需要文字环绕的时候,毕竟这才是浮动真正的用武之地,水平排列的是就交给inline-block了。
想要学会这个漂亮的烟花吗?快来跟着学习吧~
<div class="container"></div>
我们只需要一个盒子表示烟花爆炸范围就可以了
fire是烟花 注意添加绝对定位
<style> .container{ margin: 0 auto; height: 500px; width: 1200px; background: black; position: relative; overflow: hidden; } .fire{ width: 10px; background: white; height: 10px; /* border-radius: 50%; */ position: absolute; bottom: 0; } </style>
需要用到一个鼠标点击的位置,一个div选择器,一个爆炸样式
function Firework(x,y,selector,type){ //此处获取对象的方式为单例的思想,避免重复获取相同的元素 if(Firework.box && selector === Firework.box.selector){ this.box = Firework.box.ele; }else{ Firework.box = { ele:document.querySelector(selector), selector:selector } this.box = Firework.box.ele; } this.type = type; this.init(x,y) }
function animation(ele,attroptions,callback){ for(var attr in attroptions){ attroptions[attr] ={ target:attroptions[attr], inow:parseInt(getComputedStyle(ele)[attr]) } } clearInterval(ele.timer); ele.timer = setInterval(function(){ for(var attr in attroptions ){ var item = attroptions[attr] var target = item.target; var inow = item.inow; var speed = (target - inow)/10; speed = speed>0?Math.ceil(speed):Math.floor(speed); if(Math.abs(target - inow) <= Math.abs(speed)){ ele.style[attr] = target+"px"; delete attroptions[attr]; for(var num in attroptions){ return false; } clearTimeout(ele.timer); if(typeof callback === "function")callback(); }else{ attroptions[attr].inow += speed; ele.style[attr] = attroptions[attr].inow+"px"; } } },30) }
Firework.prototype = { constructor:Firework, //初始化 init:function(x,y){ //创建一个烟花 this.ele = this.createFirework(); //xy为鼠标落点 this.x = x ; this.y = y; //maxXy为最大运动范围 this.maxX = this.box.offsetWidth - this.ele.offsetWidth; this.maxY = this.box.offsetHeight - this.ele.offsetHeight; //初始化结束后 烟花随机颜色 this.randomColor(this.ele); //烟花升空 this.fireworkUp(this.ele); }, //创造烟花 createFirework:function(){ var ele = document.createElement("div"); ele.className = "fire"; this.box.appendChild(ele); return ele; }, //烟花升空 fireworkUp:function(ele){ ele.style.left = this.x + "px"; //此处用到刚刚封装的运动方法 animation(ele,{top:this.y},function(){ ele.remove(); this.fireworkBlast() }.bind(this)); }, //烟花爆炸 fireworkBlast:function(){ for(var i = 0 ; i < 20; i++){ var ele = document.createElement("div"); ele.className = "fire"; ele.style.left = this.x + "px"; ele.style.top = this.y + "px"; this.box.appendChild(ele); ele.style.borderRadius = "50%"; this.randomColor(ele); //判定一下输入的爆炸方式是原型烟花 还是散落烟花 由此更改获取的烟花位置 animation(ele,this.type === "circle"?this.circleBlast(i,20): this.randomPosition(),function(cale){ cale.remove(); }.bind(this,ele)) } }, //圆形爆炸位置 circleBlast:function(i,total){ var r = 200; var reg = 360 / total *i; var deg = Math.PI / 180 *reg; return { left:r * Math.cos(deg) + this.x , top:r * Math.sin(deg) + this.y } }, //随机颜色 randomPosition:function(){ return { left : Math.random()*this.maxX, top : Math.random()*this.maxY } }, randomColor:function(ele){ var color = "#" + parseInt(parseInt("ffffff",16)*Math.random()).toString(16).padStart(6,0); return ele.style.backgroundColor = color; } }
document.querySelector(".container").addEventListener("click",function(evt){ var e = evt||event; new Firework(e.offsetX,e.offsetY,".container","circle") new Firework(e.offsetX,e.offsetY,".container") })
全部代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> .container{ margin: 0 auto; height: 500px; width: 1200px; background: black; position: relative; overflow: hidden; } .fire{ width: 10px; background: white; height: 10px; /* border-radius: 50%; */ position: absolute; bottom: 0; } </style> </head> <body> <div class="container"></div> <script src="./utils.js"></script> <script> function animation(ele,attroptions,callback){ for(var attr in attroptions){ attroptions[attr] ={ target:attroptions[attr], inow:parseInt(getComputedStyle(ele)[attr]) } } clearInterval(ele.timer); ele.timer = setInterval(function(){ for(var attr in attroptions ){ var item = attroptions[attr] var target = item.target; var inow = item.inow; var speed = (target - inow)/10; speed = speed>0?Math.ceil(speed):Math.floor(speed); if(Math.abs(target - inow) <= Math.abs(speed)){ ele.style[attr] = target+"px"; delete attroptions[attr]; for(var num in attroptions){ return false; } clearTimeout(ele.timer); if(typeof callback === "function")callback(); }else{ attroptions[attr].inow += speed; ele.style[attr] = attroptions[attr].inow+"px"; } } },30) } function Firework(x,y,selector,type){ if(Firework.box && selector === Firework.box.selector){ this.box = Firework.box.ele; }else{ Firework.box = { ele:document.querySelector(selector), selector:selector } this.box = Firework.box.ele; } this.type = type; this.init(x,y) } Firework.prototype = { constructor:Firework, //初始化 init:function(x,y){ this.ele = this.createFirework(); this.x = x ; this.y = y; this.maxX = this.box.offsetWidth - this.ele.offsetWidth; this.maxY = this.box.offsetHeight - this.ele.offsetHeight; this.randomColor(this.ele); this.fireworkUp(this.ele); }, //创造烟花 createFirework:function(){ var ele = document.createElement("div"); ele.className = "fire"; this.box.appendChild(ele); return ele; }, fireworkUp:function(ele){ ele.style.left = this.x + "px"; animation(ele,{top:this.y},function(){ ele.remove(); this.fireworkBlast() }.bind(this)); }, //烟花爆炸 fireworkBlast:function(){ for(var i = 0 ; i < 20; i++){ var ele = document.createElement("div"); ele.className = "fire"; ele.style.left = this.x + "px"; ele.style.top = this.y + "px"; this.box.appendChild(ele); ele.style.borderRadius = "50%"; this.randomColor(ele); animation(ele,this.type === "circle"?this.circleBlast(i,20): this.randomPosition(),function(cale){ cale.remove(); }.bind(this,ele)) } }, circleBlast:function(i,total){ var r = 200; var reg = 360 / total *i; var deg = Math.PI / 180 *reg; return { left:r * Math.cos(deg) + this.x , top:r * Math.sin(deg) + this.y } }, randomPosition:function(){ return { left : Math.random()*this.maxX, top : Math.random()*this.maxY } }, randomColor:function(ele){ var color = "#" + parseInt(parseInt("ffffff",16)*Math.random()).toString(16).padStart(6,0); return ele.style.backgroundColor = color; } } document.querySelector(".container").addEventListener("click",function(evt){ var e = evt||event; new Firework(e.offsetX,e.offsetY,".container","circle") new Firework(e.offsetX,e.offsetY,".container") }) </script> </body> </html>
———————————————— 版权声明:本文为CSDN博主「SpongeBooob」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_41383900/article/details/105026768
这篇文章从一个初学者的角度,复习一波JSP。
一.概念
Java Server Pages: java服务器端页面
可以理解为:一个特殊的页面,其中既可以指定定义html标签,又可以定义java代码
用于简化书写!!!
二.原理
本质是一个Servlet
三.脚本
定义:Jsp定义java代码的方式
<% 代码 %>:定义的java代码,在service方法中。service方法中可以定义什么,该脚本中就可以定义什么。
<%! 代码 %>:定义的java代码,在jsp转换后的java类的成员位置。
<%= 代码 %>:定义的java代码,会输出到页面上。输出语句中可以定义什么,该脚本中就可以定义什么。
四.内置对象
对象名 实现接口或继承类 作用
PageContext 当前页面共享数据,还可以获取其他八个内置对象
request HttpServletRequest 一次请求访问的多个资源(转发)
session HttpSession 一次会话的多个请求间
application ServletContext 所有用户间共享数据
response HttpServletResponse 响应对象
page Object 当前页面(Servlet)的对象 this
out JspWriter 输出对象,数据输出到页面上
config ServletConfig Servlet的配置对象
expection Throwable 异常对象
五.注释
1.html注释
<!-- -->:只能注释html代码片段
2.jsp注释
<%-- --%>:可以注释所有
六.编译指令
作用
用于配置JSP页面,导入资源文件
格式
<%@ 指令名称 属性名1=属性值1 属性名2=属性值2 ... %>
分类
1.page
配置JSP页面的
1. contentType:等同于response.setContentType()
*设置响应体的mime类型以及字符集
* 设置当前jsp页面的编码(只能是高级的IDE才能生效,如果使用低级工具,则需要设置pageEncoding属性设置当前页面的字符集)
2.import:导包
3. errorPage:当前页面发生异常后,会自动跳转到指定的错误页面
4.isErrorPage:标识当前也是是否是错误页面。
* true:是,可以使用内置对象exception
* false:否。默认值。不可以使用内置对象exception
2.include
页面包含的。导入页面的资源文件
<%@include file="top.jsp"%>
3.导入资源
导入资源
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
prefix:前缀,自定义的
1
七.动作指令
作用
动作指令与编译指令不间,编译指令是通知 Servlet 引擎的处理消息,而动作指令只是运行时的脚本动作。编译指令在将JSP 编译成 Servlet 时起作用:处理指令通常可替换成 Java脚本,是 JSP脚本的标准化写法。
分类
指令 作用
jsp:forward 执行页面转向,将请求的处理转发到下一个页面。
jsp:param 用于传递参数,必须与其他支持参数曲标签一起使用。
jsp:include 用于动态引入一个 JSP 页面。
jsp:plugin 用于下载 JavaBean 或 Applet 到客户端执行。
jsp:useBean 使用 JavaBean。
jsp:setProperty 修改 JavaBean 实例的属性值。
jsp:getProperty 获取 JavaBean 实例的属性值。
具体细节:
jsp:forward:
动作把请求转到另外的页面。可以转发静态的HTML页面,也可以转发动态的JSP页面,或者转发到容器中的servlet jsp:forward标记只有一个属性page。 page属性包含的是一个相对URL。 page的值既可以直接给出,也可以在请求的时候动态计算。
jsp:param
用于设定参数值,这个指令不能单独使用 可以与以下三个指令结合使用:
jsp:include :用于将参数值出入被导入页面
jsp:forword : 用于将参数值传入被转向页面
jsp:plugin : 用于将参数值传入页面中javaBean的实例
jsp:include
(拿目标页面插入原有页面)该动作是一个动态的include指令,也用于带入某个页面,他不会导入被include页面的编译指令,仅仅导入页面的body内容插入到本页面
该动作把指定文件插入正在生成的页面。其语法如下: flush:用于指定输出缓存是否转移到被导入的文件中, true:包含在被导入的文件中 false:包含在源文件中
前面已经介绍过include指令,它是在JSP文件被转换成Servlet的时候引入文件,而这里的jsp:include动作不同,插入文件的时间是在页面被请求的时候。j
sp:include动作的文件引入时间决定了它的效率要稍微差一点,而且被引用文件不能包含某些JSP代码(例如不能设置HTTP头),但它的灵活性却要好得多。
jsp:plugin
用于下载服务器端的javaBean或applet到客户端)
jsp:plugin动作用来根据浏览器的类型,插入通过Java插件运行Java Applet所必需的OBJECT或EMBED元素。
<jsp:plugin type="bean | applet" : 被执行的java程序的类型 code="classFileName" :被执行的文件名,必须以 .class 结尾 codebase="classFileDirectoryName" :被执行文件的所在目录 [ name="instanceName" ] :给程序起一个名字用来标识该程序 [ archive="URIToArchive, ..." ] :指向一些要预先载入的将要使用到的类 [ align="bottom | top | middle | left | right" ] : [ height="displayPixels" ] [ width="displayPixels" ] [ hspace="leftRightPixels" ] [ vspace="topBottomPixels" ] [ jreversion="JREVersionNumber | 1.1" ] :能正确运行改程序必须的JRE的版本 [ nsplug inurl="URLToPlugin" ] [ iepluginurl="URLToPlugin" ] > [ <jsp:params> [ <jsp:param name="parameterName" value="{parameterValue | <%= expression %>}" /> ]+ </jsp:params> ] [ <jsp:fallback> text message for user </jsp:fallback> ] :当不能正确显示该Applet时,显示该指令中的文本提示 <jsp:plugin>
jsp:useBean
useBean:用于在jsp页面中初始化一个java实例(如果多个jsp中需要重复使用某段代码,可以把这段代码定义成java类在页面中引用)
jsp:useBean动作用来装载一个将在JSP页面中使用的JavaBean。这个功能非常有用,因为它使得我们既可以发挥Java组件重用的优势,同时也避免了损失JSP区别于Servlet的方便性。
jsp:useBean动作最简单的语法为:<jsp:useBean id=“JavaBean的名称” class=“package.class"包名.类名” scope=“有效范围”/>
这行代码的含义是:“创建一个由class属性指定的类的实例,然后把它绑定到其名字由id属性给出的变量上”。不过,就象我们接下来会看到的,定义一个scope属性可以让Bean关联到更多的页面,它可接受四个值:request、session、page、application。此时,jsp:useBean动作只有在不存在同样id和scope的Bean时才创建新的对象实例,同时,获得现有Bean的引用就变得很有必要。
获得Bean实例之后,要修改Bean的属性既可以通过jsp:setProperty动作进行,也可以在Scriptlet中利用id属性所命名的对象变量,通过调用该对象的方法显式地修改其属性。这使我们想起,当我们说“某个Bean有一个类型为X的属性foo”时,就意味着“这个类有一个返回值类型为X的getFoo方法,还有一个setFoo方法以X类型的值为参数”。 有关jsp:setProperty动作的详细情况在后面讨论。但现在必须了解的是,我们既可以通过jsp:setProperty动作的value属性直接提供一个值,也可以通过param属性声明Bean的属性值来自指定的请求参数,还可以列出Bean属性表明它的值应该来自请求参数中的同名变量。
在JSP表达式或Scriptlet中读取Bean属性通过调用相应的getXXX方法实现,或者更一般地,使用jsp:getProperty动作。
注意,包含Bean的类文件应该放到服务器正式存放Java类的目录下,而不是保留给修改后能够自动装载的类的目录。例如,对于Java Web
Server来说,Bean和所有Bean用到的类都应该放入classes目录,或者封装进jar文件后放入lib目录,但不应该放到servlets下。
id:javaBean的实例名 class: javaBean的实现类 scope:指定javaBean实例的生存范围
page:javaBean仅在该页面有效 request:javaBean在本次请求中有效 session:
javaBean在本次session内有效 application:
javaBean在本应用内一直有效 下面是一个很简单的例子,它的功能是装载一个Bean,然后设置/读取它的message属性。
关于jsp:useBean的进一步说明 使用Bean最简单的方法是先用下面的代码装载Bean: <jsp:useBean id=“name” class=“package.class” />
然后通过jsp:setProperty和jsp:getProperty修改和提取Bean的属性。 不过有两点必须注意。 第一,我们还可以用下面这种格式实例化Bean: <jsp:useBean …> Body </jsp:useBean>
它的意思是,只有当第一次实例化Bean时才执行Body部分,如果是利用现有的Bean实例则不执行Body部分。正如下面将要介绍的,jsp:useBean并非总是意味着创建一个新的Bean实例。
第二,除了id和class外,jsp:useBean还有其他三个属性,即:scope、type、beanName。
id:命名引用该Bean的变量。如果能够找到id和scope相同的Bean实例,jsp:useBean动作将使用已有的Bean实例而不是创建新的实例。
class:指定Bean的完整包名。
scope:指定Bean在哪种上下文内可用,可以取下面的四个值之一:page、request、session和application。 默认值是page,表示该Bean只在当前页面内可用(保存在当前页面的PageContext内)。
request表示该Bean在当前的客户请求内有效(保存在ServletRequest对象内)。
session表示该Bean对当前HttpSession内的所有页面都有效。
最后,如果取值application,则表示该Bean对所有具有相同ServletContext的页面都有效。
scope之所以很重要,是因为jsp:useBean只有在不存在具有相同id和scope的对象时才会实例化新的对象;
如果已有id和scope都相同的对象则直接使用已有的对象,此时jsp:useBean开始标记和结束标记之间的任何内容都将被忽略。
type:指定引用该对象的变量的类型,它必须是Bean类的名字、超类名字、该类所实现的接口名字之一。请记住变量的名字是由id属性指定的。
beanName:指定Bean的名字。如果提供了type属性和beanName属性,允许省略class属性。
jsp:setProperty
jsp:setProperty用来设置已经实例化的Bean对象的属性,有两种用法。
首先,你可以在jsp:useBean元素的外面(后面)使用jsp:setProperty, …
第二种用法是把jsp:setProperty放入jsp:useBean元素的内部, …
jsp:setProperty动作有下面四个属性:name:表示要设置属性的是哪个Bean。 property:表示要设置哪个属性。有一个特殊用法:如果property的值是"",表示所有名字和Bean属性名字匹配的请求参数都将被传递给相应的属性set方法。 value:value属性是可选的。该属性用来指定Bean属性的值。字符串数据会在目标类中通过标准的valueOf方法自动转换成数字、boolean、Boolean、byte、Byte、char、Character。例如,boolean和Boolean类型的属性值(比如“true”)通过Boolean.valueOf转换,int和Integer类型的属性值(比如"42")通过Integer.valueOf转换。 value和param不能同时使用,但可以使用其中任意一个。 Param:param是可选的。它指定用哪个请求参数作为Bean属性的值。如果当前请求没有参数,则什么事情也不做,系统不会把null传递给Bean属性的set方法。因此,你可以让Bean自己提供默认属性值,只有当请求参数明确指定了新值时才修改默认属性值。 例如,下面的代码片断表示:如果存在numItems请求参数的话,把numberOfItems属性的值设置为请求参数numItems的值;否则什么也不做。 如果同时省略value和param,其效果相当于提供一个param且其值等于property的值。进一步利用这种借助请求参数和属性名字相同进行自动赋值的思想,你还可以在property(Bean属性的名字)中指定“”,然后省略value和param。此时,服务器会查看所有的Bean属性和请求参数,如果两者名字相同则自动赋值。 下面是一个利用JavaBean计算素数的例子。如果请求中有一个numDigits参数,则该值被传递给Bean的numDigits属性;numPrimes也类似。 JspPrimes.jsp
jsp:getProperty
jsp:getProperty动作提取指定Bean属性的值,转换成字符串,然后输出。
jsp:getProperty有两个必需的属性,即:name,表示Bean的名字;property,表示要提取哪个属性的值。
END!!!有什么意见可以提出来!
长路漫漫,JAVA为伴!!!
————————————————
版权声明:本文为CSDN博主「福尔摩东」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_43688587/article/details/105017469
label默认为内联元素,元素前后没有换行符,并且不可以设置宽度。
如果要为label设置宽度,则需要改变label的display属性,使其变为一个块级元素。
方法如下:
1.增加inline-block属性值,将label标签变为行内块元素(css2.1新增)
{
display
:inline-
block
;}
label{
width
:
100px
;
display
:inline-
block
;}
3.添加好后页面上所有的label标签会变为100pxv
JavaScript中的混淆器
随着 AJAX 和富界面技术的发展,Javascript 在 Web 应用上的重要性越来越高,Javascript 代码的复杂性、功能和技术含量也越来越高,对Javascript 代码保护的需要也越来越迫切。
压缩 compress: 去掉空格,换行,注释等,格式紧凑,节约存储空间。
混淆 obfuscate/garble:替换变量名或方法名,让js不容易看懂。也做到了压缩的效果。
加密 encrypt:一般用eval方法加密,效果与混淆相似。也做到了压缩的效果。
我们可以通过工具进行混淆,通过工具也是目前最好的方式。推荐一个很好的混淆工具: JSObfuscator By Unest
————————————————
版权声明:本文为CSDN博主「刘亦枫」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/liuyifeng0000/article/details/105004732
以蚂蚁森林和蚂蚁庄园为典型代表,而淘宝里的“野生小伙伴”、天猫里的“童话镇”也是此类题材。这类游戏更多是通过公益捐献的形式赋予用户更多的使命感,吸引用户参与,但是带来的用户商业价值不高。目前“野生小伙伴”已经下架,“童话镇”在天猫平台的露出并不明显,用户的感知较弱。
四、总结
爱玩是人类的天性。因此游戏以及游戏化的产品,天然具有高用户粘度和用户活跃度的特质。但是市场上有无数的游戏化产品,为什么有的异常火爆,有的无人问津呢?
在产品设计时需要注意以下几点:
1、游戏化产品之所以受到用户的喜爱,利益点仅仅是表层驱动,游戏的玩法才是产品真正的核心。因此需要通过建立完善的游戏化体系,提升产品的竞争力;
2、游戏化产品竞争激烈,需要不断的进行玩法创新,才能带给用户差异化体验。例如拼多多系列产品,通过实物领取和兑换,带给了用户全新的体验感受,对用户的吸引力也更强;
3、游戏化产品需要赋能商业目标,在实现了用户活跃的基础上,还需要提升用户转化;
作者:子牧先生
转自 :子牧设计笔谈
/Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent);
<script type="text/javascript"> var Sys = {}; var ua = navigator.userAgent.toLowerCase(); var s; (s = ua.match(/msie ([\d.]+)/)) ? Sys.ie = s[1] : (s = ua.match(/firefox\/([\d.]+)/)) ? Sys.firefox = s[1] : (s = ua.match(/chrome\/([\d.]+)/)) ? Sys.chrome = s[1] : (s = ua.match(/opera.([\d.]+)/)) ? Sys.opera = s[1] : (s = ua.match(/version\/([\d.]+).*safari/)) ? Sys.safari = s[1] : 0; //以下进行测试 if (Sys.ie) document.write('IE: ' + Sys.ie); if (Sys.firefox) document.write('Firefox: ' + Sys.firefox); if (Sys.chrome) document.write('Chrome: ' + Sys.chrome); if (Sys.opera) document.write('Opera: ' + Sys.opera); if (Sys.safari) document.write('Safari: ' + Sys.safari); </script>
PC端只有Chrome有Safari字段吗?为什么不需要判断其他浏览器?
其实360,QQ等浏览器的userAgent字段也会带有Safari字段,但是由于他们基于Chrome二次开发的,所有也会携带有Chrome字段。
所以「匹配规则:拥有Safari字段,并且没有Chrome字段」就可以了。
接下来是修改元素样式
<html> <head> <style> #a{ width:700px; height:300px; font-size:50px; color:red; background-color:grey; z-index:2; position:absolute; top:1300px; left:200px; display:none; } </style> </head> <body> <div id="a"></div> </body> <script type="text/javascript"> //假设想修改display为block function modify(){ //1.原生Js法 var a= document.getElementById("a"); a.style.display="block"; //2.用JQuery的css方法 var a =$("#a"); a.css("display","block"); //3.用JQuery的attr方法 var a =$("#a"); a.attr("style","display:block"); } </script> </html>
这样就可以根据不同浏览器写出不同的样式适配啦
密码强度验证
需求
首先我们需要知道需求是什么? 这很重要!
要知道 我们写的一切逻辑都是建立在需求之上
当输入框聚焦时提示密码要求
当密码符合要求时 隐藏提示 并给予反馈
密码等级低时 提示密码等级为低
密码等级一般时 提示密码等级为中
密码等级高时 提示密码等级为高
当密码不符合要求时 重新打开提示
思考如何构建函数
通过上面的需求 你能想到的函数时什么?你能想到的逻辑又是什么?
首先 提示的显示隐藏我们可以用事件绑定或者事件监听来做
其次 我们需要利用正则来判断密码等级
当密码等级为低时 显示红色
当密码等级为中时 显示黄色
当密码等级为高时 显示绿色
最后 根据密码等级来渲染页面 也就是反馈给用户的样式
建议 :
在这里 尽量把每个函数的功能区分好 构思好
不仅要让自己能看懂 还要让别人能看懂
这样的代码才是好的代码 可读性更好 可维护性更高
在提示盒子的内部写3个div 不同等级给予不同颜色不同数量的提示
密码 : <input type="text" id="ipt"> <p id="p">请输入6-20位的带有数字字母或者特殊符号的密码</p> <div class="box"> <span></span> <div></div> <div></div> <div></div> </div>
不管样式行为再怎么花里胡哨 也一定要先把结构里要出现的元素写出来
由于考虑到等级分为三种 所以给提示盒子分3中不同的class类名
每一个类名对应的子元素的样式也不同
到js部分我们只需要操作class类名
就可以了
<style> *{ margin : 0 ; padding : 0 ; } //提示盒子 .box{ position : absolute; top : 2px; left : 200px; } .box div, .box span{ margin-right : 5px; width : 20px; height : 20px; float : left; } //低等级 .box.low :nth-child(2){ background : red; } //中等级 .box.middle div{ background : yellow; } .box.middle :last-child{ background: #fff; } //高等级 .box.high div{ background : green; } //提示文字默认隐藏 p{ display : none; } </style>
<script> //获取需要操作的元素 let ipt = document.getElementById('ipt'); let p = document.getElementById('p'); let div = document.getElementsByClassName('box')[0]; var tip = false; //聚焦显示提示的开关 //添加聚焦事件 ipt.addEventListener('focus' , () => { //由于存在用户输入正确的密码失焦再操作的可能 所以需要验证开关 if(!tip) { p.style.display = 'block'; } //默认选中文字 提升用户体验 ipt.select(); }) //添加输入时的事件 ipt.addEventListener('input' , () => { //拿到用户输入的密码字符串 let str = ipt.value; //当密码不符合要求时 要及时给予反馈 及时清除样式 if(str.length < 6 ||str.length > 20 || /[^(\da-zA-Z\_\#\@\$\^\%\*\&\!\~\+\-)]/.test(str) || str === "") { p.style.display = 'block'; removeClass(div); div.children[0].innerHTML = ""; tip = true; //如果不符合要求 就没必要判断等级了 直接结束判断 return false; }else{ p.style.display = 'none'; } //判断密码等级 let res = level(str); //根据等级添加样式 randerLevel(res); }) //判断密码等级函数 function level (str) { let level = 0; //当用户输入的字符串符合一定规则 让等级+1 if(/\d+/.test(str)) { level ++; } if(/[a-zA-Z]+/.test(str)) { level ++; } if(/[\_\#\@\$\^\%\*\&\!\~\+\-]+/.test(str)) { level ++; } return level; } //添加样式函数 function randerLevel (level) { //在添加样式前先清空样式 removeClass(div); div.children[0].innerHTML = ""; //根据等级添加对应的类名 switch (level) { case 1 : div.children[0].innerHTML = '低'; //元素存在不止一个类名 用 += 更好 div.className += ' low'; break; case 2 : div.children[0].innerHTML = '中'; div.className += ' middle'; break; case 3 : div.children[0].innerHTML = '高'; div.className += ' high'; break; } } //去等级类名函数 function removeClass(ele){ let reg = /low|middle|high/g; if(reg.test(ele.className)) { //不要忘记把值赋回去 replace返回的是新字符串 ele.className = ele.className.replace(reg , ""); } } </script>
当密码等级为低时 给予红色反馈
————————————————
版权声明:本文为CSDN博主「豆浆不好喝」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_45178648/article/details/104885417
蓝蓝设计的小编 http://www.lanlanwork.com