记一次 JS 模拟 CSS active 效果的过程
来源:互联网 发布:淘宝供应链金融 编辑:程序博客网 时间:2024/06/06 14:09
所谓的界面触控效果,就是用户点下去的时候,界面立刻产生变化以反馈给用户知道:“ok,你点击的吩咐,我已晓得罗~”,也有人说“点击高亮的效果”。——毋庸置疑,这是人机交互中非常重要沟通手段,使用得也非常常见的。当时我要实现这效果的时候,自己还满认为,不就是网页上为链接加个 a:hover 效果嘛~链接不行的加个“图片翻转”不就可以了。——孰料,在移动终端上,花费的时间远超想像。首先,我倾向于采用纯样式的方法,大体思路是:普通状态写一种样式;用户点击后归为另外一种状态,写出其状态对应样式。这样,我立刻想到的时“元素:hover”。经测试 PC 上无问题,但手机上尤其列表控件显得过于灵敏,有时与滚动事件冲突,有时出现奇怪的 bug,于是想想,不应使用 hover,应是采用“元素:active”才对(active 意即“击中”那一下,hover 仅仅“移上”意思)。改用 active 后,上述问题立即迎刃而解。简单说,active 效果与 hover 效果相比,就是 active 点击后会撤销手指松开的样式。
/* 普通效果 */.x_list li { padding: 3px; width: 100%; list-style: none; background-color: #999;/*普通效果的背景色*/ border-bottom: 1px solid #333; border-top: 1px solid white; clear: both; display: inline-table; position: relative;}/* 点击效果 */.x_list li:active{ background-color:red;}
看来,hover 与 active 意思虽相近,但细作起来还是明显差别。以往讨论桌面的时候,大多用 hover 即可,而现如今在手机上却把两者的区别给凸显出来了。我想,这是什么缘故呢,——为什么以往桌面的做法行得通,而手机上却把问题暴露出来呢。我觉得,执行“事件的媒介”也是重要的原因,因为桌面上输入事件的乃鼠标器居多,而且手机上则围绕手指触控的居多。两者的分野,导致所处于的经验与法则也不尽相同。可以说,承接下来的那个 bug,都有同样的缘故在作祟。
可是,即使使用 active,又遇到浏览器支持的问题:——Android 2.x 仍不支持元素:active,新版的 Android 4.x 和 iOS 则顺利通过。于是我安排 iOS 与 Android 4 就用 CSS 的写法,而 Android 另一边厢安排 js 方法实现之。
既然用 js 方法实现之,我第一时间想到的用 setTimeout() 定时器实现之。点击后添加一样式,timeout 之后撤销样式。
// 用户按下之后,为元素加入高亮样式,然后立刻消褪,——这就是所谓的 active 样式。// 请注意,这个方法属于“反面教材”function onActive(el, fn){el.addCls('active');setTimeout(function(){fn && fn();el.removeCls('active');}, 300);}
这个貌似可行的办法实则不正确!因为经过领导演示,人家 Sencha Touch 的选中高亮是可以跟随滚动的,我的在首页上的点击高亮是可以但不会响应点击滚动,有反常理!甚幸,恰恰有正确的案例在前,让我可以参照,可以纠正。后来结果通过 touchstart/touchend 事件实现这个界面触控效果。代码如下:
HTMLElement.prototype.onActive = (function () {/** * this 应为 CSS Selector * @param {Event} e */function highlight(e){var targetEl = e.target;if(targetEl && targetEl.tagName == this.toUpperCase()){targetEl.toggleCls('active');}else if(targetEl){arguments.callee.call(this, {target : targetEl.parentNode});}} // 是否支持触摸事件 var isSupportTouch = 'ontouchstart' in window || "ontouchend" in window.document;// 支持触摸式使用相应的事件替代var hightEvent_in = isSupportTouch ? 'touchstart': 'mouseover',hightEvent_out = isSupportTouch ? 'touchend' : 'mouseout'; /** * @param {String} highlightCfg */ return function(el_cssSelector){ // ONLY FOR Moblie? if (!window.navigator.isAndroid_2) { return false; } var eventHandler = highlight.bind(el_cssSelector || 'LI'); // 默认 li 修改样式 // $$.addListener 为跨浏览器的事件添加器$$.addListener(this, hightEvent_in, eventHandler);$$.addListener(this, hightEvent_out, eventHandler);//$$.addListener(this, 'touchcancel',eventHandler, isUseCapture); /*@todo考察该事件,比较特殊*/ return this; // 方便链式调用}})();上述代码扩展的浏览器原生对象 HTMLElment 原型,因此在任一元素身上都有 onActive 方法,另外 toggleCls(className) 也是通过扩展元素原型来提供的。相应地,样式不经过伪类来实现,而是定义一个 .active 的样式类:
/* 点击效果 */.x_list li.active{ /* 注意这里冒号被改为点号*/ background-color:red;}
函数 highlight 中,因为登记事件时不能触发 userCapture,所以没有使用“事件冒泡”的方式而是递归上报的方式。
2013-4-7 重新整理一下这个函数,请注意这是没有版本检测,你应该自己加一个,因为只针对 android 2.x。
/** * 模拟 el:active * @param {Element} ul 参数为元素 */function onActive(ul){// ONLY FOR Android 2.x? Yes!// 检测是否 android 2.x 的属性,你可以依赖你自己的方案,我的就不贴了,比较简单的。// if (!window.navigator.isAndroid_2) {// return ul; //尽管该函数不工作,也要返回 this,以方便链式调用// }// add Highlightul.addEventListener('touchstart', function (e){var targetEl = e.target;while(targetEl && targetEl.tagName != 'LI'){// 默认为 li 修改样式targetEl = targetEl.parentNode; // 找到要操作的目标元素为止}// do sth……console.log(targetEl.tagName);targetEl.addCls('active');});// remove Highlightul.addEventListener('touchend', function (e){var targetEl = e.target;while(targetEl && targetEl.tagName != "LI"){targetEl = targetEl.parentNode; // 找到要操作的目标元素为止}// do sth……console.log(targetEl.tagName);targetEl.removeCls('active');}); return ul; // 方便链式调用}
CSS 样式如下:
/* 点击效果 */ul.x_list li:active, ul.x_list li.active { background-image: -webkit-gradient(linear, center top, center bottom, from(lightGrey), to(white));}
2013-04-18 把问题重新整理了一下,给出如下“药方”:
<style type="text/css">p:active, p.active{background-color:red;}</style><body><p>Welcome to JdropJdrop provides a place to store JSON data in the cloud. The initial application is for storing performance data gathered from mobile devices. It's hard to analyze large amounts of information (HTTP waterfall charts, HTTP headers, document source, etc.) on a mobile device. Jdrop lets you gather this data on the mobile device but analyze it remotely on a larger screen. </p></body><script type="text/javascript">document.addEventListener('touchstart', function (e) {e.target.className = 'active';}, false);document.addEventListener('touchend', function (e) {e.target.className = '';}, false);</script>使用了事件委托比较合理。
- 记一次 JS 模拟 CSS active 效果的过程
- 记一次 JS 模拟 CSS active 效果的过程
- JS+CSS 模拟alert效果
- [JS]JS模拟Alert弹出框效果--自定义CSS样式
- 【飞秋】记一次“偷盗”别人的CSS和Js
- 记一次JS执行顺序引起的问题排查过程
- js+CSS实现模拟华丽的select控件下拉菜单效果
- 用CSS模拟不同的拐角效果
- 纯CSS样式模拟js写手风琴效果
- Odoo8的一次js前端调试过程
- css模拟表格效果
- 模拟Flash放大镜的动态JS效果
- js 模拟qq对话框的拖动效果
- js 模拟淘宝商品广告的效果
- 效果不错的JS+CSS菜单
- Js|---CSS滤镜实现的各种效果
- css+js的选项卡效果
- JS设置css的float效果
- bollean
- vs2008发布失败完美解决方案
- 嵌入式Linux操作系统学习规划
- システム関連の完了コード
- hdu1506-动态规划
- 记一次 JS 模拟 CSS active 效果的过程
- ASP.NET高级开发之三层架构
- mongoDB windows 32bit 安装
- デーモン起動時の終了ステータス
- 多线程简介
- [V811双核] 最新昂达V811最新2.0固件ROOT方法
- __init __initdata __exit __exitdata解析
- Java Socket编程中对于run的使用方法介绍
- flv文件格式分析FlvParse.exe