为什么大发彩票源码下载 Q1446595067 论坛: haozbbs.com 说能使用 html/CSS 解决的问题就不要使用 JS 呢? 两个字, 因为简单. 简单就意味着更快的开发速度, 更小的维护成本, 同时往往具有更好的体验, 下面介绍几个实例.
1, 导航高亮
导航高亮是一种很常见的问题, 包括当前页面的导航在菜单里面高亮和 hover 时高亮. 你可以用 js 控制, 但是用一点 CSS 技巧就可以达到这个目的, 不需要使用 JS.
- 640?wx_fmt=png&wxfrom=5&wx_lazy=1
- 640?wx_fmt=png&wxfrom=5&wx_lazy=1
在正常态时, 每个导航的默认样式为:
- nav li{ opacity: 0.5;
- }
当前页面的导航透明度为 1. 为了实现这个目的:
首先通过 body 给不同的页面添加不同的类, 用来标志不同的页面
- <!-- home.html -->
- <body class="home">
- </body>
- <!-- buy.html -->
- <body class="buy"></body>
所有的 li 也用 class 标志, 为了有一个一一对应的关系:
- <li class="home">home</li>
- <li class="buy">buy</li>
然后就可以设置当前页面的样式, 覆盖掉默认的样式:
- body.home nav li.home,body.buy nav li.buy
- {
- opacity: 1;
- }
这样子, 如果当前页面是 home, 则 body.home na li.home 这条规则生效, home 的导航将高亮.
这个技艺在精通 CSS这种书里面有提及. 如果你用 js 控制, 那么在脚本加载好之前, 当前页面是不会高亮的, 而脚本加载好之后突然就高亮了. 所以用 js 吃力不讨好.
hover 时的高亮, 可以用 css 的: hover 选择器:
- nav li:hover
- {
- opaciy: 1;
- }
加上: hover 选择器的优先级将会高于原本的, 鼠标 hover 的时候将会覆盖默认样式, 即高亮.
你也可以用 mouse 事件, mouseover 的时候添加一个类, mouseleave 的时候移除掉这个类, 这样就变复杂了, 用 CSS 甚至可以兼容不支持 JS 的浏览器, 用户可能把浏览器的 js 禁掉了. 我一个纯展示的静态页面, 为啥要写 js 呢, 是吧.
注意这个 hover 选择器特别好用, 几乎适用于所有需要用鼠标悬浮时显示的场景.
2, 鼠标悬浮时显示
鼠标悬浮的场景十分常见, 例如导航的菜单:
640?wx_fmt=png
以及在Google 地图开发总结一文提到的, marker 详情框的显示:
640?wx_fmt=png
一般要把隐藏的东西如菜单作为 hover 目标的子元素或者相邻元素, 才方便用 css 控制, 例如上面的菜单, 是把 menu 当作导航的一个相邻元素:
- <li class="user"> 用户 </li>
- <li class="menu">
- <ul>
- <li > 账户设置 </li>
- <li > 登出 </li>
- </ul></li>
menu 在正常态下是隐藏的:
- .menu{ display: none;
- }
而当导航 hover 时显示:
- .user:hover + .menu
- {
- display: list-item;
- }
注意这里使用了一个相邻选择器, 这也是上面说的为什么要写成相邻的元素. menu 的位置可以用 absolute 定位.
同时 menu 自已本身 hover 的时候也要显示, 否则鼠标一离开导航的时候, 菜单就消失了:
- .menu:hover
- {
- display: list-item;
- }
这里会有一个小问题, 即 menu 和导航需要挨着一起, 否则中间有空隙的话, 上面添加的菜单 hover 就不能发挥作用了, 但是实际情况下从美观的角度, 两者是要有点距离的. 这个其实也好解决, 只要在 menu 上面再画一个透明的区域就好了, 如下蓝色的方块:
640?wx_fmt=png
可以用 before/after 伪类用 absoute 定位实现:
- ul.menu:before{
- content: "";
- position: absolute;
- left: 0;
- top: -20px;
- width: 100%;
- height: 20px;
- /*background-color: rgba(0,0,0,0.2);*/}
如果我既写了 css 的 hover, 又监听了 mouse 事件, 用 mouse 控制显示隐藏, 双重效果会有什么情况发生, 如果按正常套路, 在 mouse 事件里面 hover 的时候, 添加了一个 display: block 的 style, 会覆盖掉 CSS 的设置.
也就是说, 只要 hover 一次, css 的代码就不管用了, 因为内联样式的优先级会高于外链的.
但是实际情况下会有意外发生, 那就是在移动端 iphone 上面, 触摸会触发 CSS 的 hover, 并且这个的触发会很高概率地先于 touchstart 事件, 在这个事件里面会判断当前是显示还是隐藏的状态, 由于 css 的 hover 发挥了作用, 所以判断为显示, 然后又把它隐藏了.
也就是说, 点一次不出来, 要点两次. 所以最好别两个同时写.
第二种场景, 使用子元素, 这个更简单. 把 hover 的目标和隐藏的对象当作同一个父容器的子元素, 然后 hover 写在这个父容器上面就可以了, 不用像上面那样, 隐藏元素也要写个 hover:
- .marker-container .detail-info
- {
- display: none
- }
- .marker-container:hover .detail-info
- {
- display: block
- }
3, 自定义 radio/checkbox 的样式
我们知道, 使用原生的 radio/checkbox 是不可以改变它的样式的, 得自己用 div/span 去画, 然后再去监听点击事件. 但是这样需要自己去写逻辑控制, 例如 radio 只能选一个的功能, 另一个是没有办法使用 change 事件. 就是没有用原生的方便.
但是实际上可以用一点 CSS3 的技巧实现自定义的目的, 如下, 就是用原生实现的 radio:
640?wx_fmt=gif
这个主要是借助了 CSS3 提供的一个伪类: checkd, 只要 radio/checkbox 是选中状态, 这个伪类就会生效, 因此可以利用选中和非选中的这两种状态, 去切换不同的样式. 如下把一个 checkbox 和一个用来自定义样式的 span 写在一个 label 里面, checkbox 始终隐藏:
- <style>input[type=checkbox]
- {
- display: none;
- }
- /* 未选中的 checkbox 的样式 */
- .checkbox{
- }
- </style>
- <label>
- <input type="checkbox">
- <span class="checkbox"></span>
- </label>
写在 label 里面是为了能够点击 span 的时候改变 checkbox 的状态, 然后再改一下选中态的样式即可:
- input[type=checkbox]:checked + .checkbox{
- }
关键在于这一步, 添加一个打勾的背景图也好, 使用图标字体也好.
:checked 兼容性还是比较好的, 只要你不用兼容 IE8 就可以使用, 或者说只要你可以用 nth-of-type, 就可以用: checked.
4, 多列等高
多列等高的问题是这样的, 排成一行的几列由于内容长短不一致, 导致容器的高度不一致:
640?wx_fmt=png
你可以用 js 算一下, 以最高的一列的高度去设置所有列的高度, 然而这个会造成页面闪动, 刚开始打开页面的时候高度不一致, 然后发现突然又对齐了. 这个解决办法主要有两种:
第一种是每列来一个很大的 padding, 再来一个很大的负的 margin 值矫正回去, 就对齐了, 如下:
- <style>.wrapper> div{
- float: left;
- padding-bottom: 900px;
- margin-bottom: -880px;
- background-color: #ececec;
- border: 1px solid #ccc;
- }
- </style>
- <div class="wrapper">
- <div>column 1</div>
- <div>column 2</div>
- <div>column 3</div>
- <div>column 4</div>
- </div>
效果如下:
640?wx_fmt=png
你会发现, 这个对齐是对齐了, 但是底部的 border 没有了, 设置的圆角也不起作用了, 究其原因, 是因为设置了一个很大的 padding 值, 导致它的高度变得很大, 如上图所示. 所以如果你想在底部 absolute 定位放一个链接 "更多 >>" 也是实现不了了.
第二种办法是借助 table 的自适应特性 , 每个 div 都是一个 td,td 肯定是等高的, html 结构不变, CSS 改一下:
- .wrapper{
- display: table;
- border-spacing: 20px;
- /* td 间的间距 */
- }
- .wrapper> div {
- display: table-cell;
- width: 1000px;
- /* 设置很大的宽度, table 自动平分宽度 */border-radius: 5px;
- /* 这里设置圆角就正常了 */
- }
对齐效果如下:
640?wx_fmt=png
这样还有一个好处, 就是在响应式开发的时候, 可以借助媒体查询动态地改变 display 的属性, 从而改它排列的方式. 例如在小于 500px 时, 每一列占满一行, 那么只要把 display: table-cell 覆盖掉就好了:
- @media (max-width: 500px){
- .wrapper{
- display: block;
- }
- .wrapper> div{
- display: block;
- width: 100%;
- }
- }
效果如下所示:
640?wx_fmt=png
如果在 pad 1024px 的设备上, 希望一行显示 2 个, 那应该怎么办呢? 由于上面用的 td, 必定会排在同一行. 其实可以在第二个和第三个中间加一个 tr, 让它换行:
- <div class="wrapper">
- <div>column 1</div>
- <div>column 2</div>
- <span class="tr"></span>
- <div>column 3</div>
- <div>column 4</div></div>
在大屏和小屏时, tr 是不显示的, 而在中屏时, tr 显示:
- .tr{
- display: none;
- }
- @media (max-width: 1024px)
- and (min-width: 501px){
- .tr{
- display: table-row;
- }
- }
就能够实现在小屏时一行排两列了, 只是这个有个小问题, 就是在中屏拉到大屏的时候 tr 的 dipslay: none 已经没有什么作用, 因为 table 的布局已经计算好. 但是一般应该不用考虑这种拉伸范围很大的情况, 正常刷新页面是可以的, 如果真要解决那得借助下 js.
5, 需要根据个数显示不同样式
例如说可能有 1~3 个 item 显示在同一行, 而 item 的个数不一定, 如果 1 个, 那这个 item 占宽 100%,2 个时每一个 50%,3 个时每一个 33%, 这个你也可以用 js 计算一下, 但是用 CSS3 就可以解决这个问题:
- <style>
- li{
- width: 100%;
- }
- li:first-child:nth-last-child(2),
- li:first-child:nth-last-child(2) ~ li{
- width: 50%;
- }
- li:first-child:nth-last-child(3),
- li:first-child:nth-last-child(3) ~ li{
- width: 33%;
- }
- </style><ul>
- <li>1</li>
- <li>2</li>
- <li>3</li></ul>
第 5 行的意思就是选择 li 的第一个元素, 并且它是倒数第二个元素, 第 6 行的意思是选择前面有是第一个且是倒数第二个 li 的所有 li, 第一行是选择了第一个, 第二行选择除第一个外的其它所有元素. 有三个元素的类似.
6, 使用表单提交
提交请求有两种方式, 一种是 ajax, 另外一种是表单提交. 很多人都知道 ajax, 但往往忽略了还有个 form 提交.
假设在首页有一个搜索的表单, 点击 search 的时候就跳到列表页
640?wx_fmt=png
你可以一个个去获取所有的 input 的值, 然后把它拼到网址参数重定向一下, 但是其实可以不用这样, 用一个表单提交就好了:
- <form id="search-form" action="/search">
- <input type="search" name="keyword">
- <input type="number" name="price">
- </form>
将所有字段的名字写在 input 的 name 里面, 然后 form 的 action 为搜索页的链接. 这样子不用一行 js 代码就能够搜索跳转.
如果你需要做表单验证, 那就监听 submit 事件, 然后做验证, 验证通过则调一下原生的 submit 就可以提交了, 也是不需要手动去获取 form 的值.
7, 自动监听回车事件
这个的场景是希望按回车的时候能够触发请求, 像第 6 点, 按回车实现跳转, 或者是像下面的, 按下回车就送一条聊天消息:
640?wx_fmt=png
通常的做法是监听下 keypress 事件, 然后检查一下 keycode 是不是回车, 如果是则发请求.
但是其实有个特别简单的办法, 也是不需要一行 JS, 那就是把表单写在一个 form 里面, 按回车会自动触发 submit 事件. 读者可以自己试试. 这个就启示我们要用语义的 html 组织, 而不是全部都用 div. 如果用相应的 html 标签, 浏览器会自动做一些优化, 特别是表单提交的 input.
JS 是万能的, 几乎可以做任何事情, 但是有时候会显得十分笨拙, 在 js/html/css 三者间灵活地切换, 往往会极大地简化开发, 没有谁是最好的语言, 只有适不适合. 只要用得好, 不管黑猫白猫, 都是好猫.
来源: http://www.bubuko.com/infodetail-2664123.html