[转载]jQuery boxy弹出层对话框插件扩展应用--弹出层选择器

mikel阅读(980)

[转载]jQuery boxy弹出层对话框插件扩展应用–弹出层选择器 – 挫折中成长 – 博客园.

当大家进行复杂功能设计的时候,在对多级联选择进行设计,为了获得更好的用户体验和节省页面空间,往往会使用弹出层的方法。我们使用热门的JQuery进行设计,同时我们选择效果比较优秀的boxy弹出插件进行扩展(关于boxy的相关资料,请参照张鑫旭博客http://www.zhangxinxu.com/wordpress/?p=318)。下面介绍boxy作为选择器框架的应用。

对于选择器,相信用过招聘网站的人都不会陌生(就是那个点击就弹出的,选择行业、职位和地区的东西),选择器难点就在于样式调试,主要针对的是IE6。这里介绍行业、职位和地区选择器,下载的Demo包含这三个选择器。

行业选择器:无关联,调用语句为Boxy.industry(value, callback, options),参数value为已选定值编号集合(字符串类型,编号间以逗号分割),callback为可定义回调函数,传入callback的值为 行业选择器选中项的编号集合(字符串类型,编号间以逗号分割),options为boxy插件可选参数。

调用例子:选择编号为1和2的行业,并且定义选择器标题为”行业类别选择器”

1 $(#industry).click(function() {
2 Boxy.industry(1,2, function(val) {
3 alert(你选择的是: + val);
4 }, { title: 行业类别选择器 });
5 return false;
6 });

职位选择器:二级联,调用语句为Boxy.job(value, shown, callback, options),参数value为已选定值编号集合(字符串类型,编号间以逗号分割,以b开头表示选择职位大类,以s开头表示选择职位小类),参数 shown表示展示的职位大类的编号,参数callback为可定义回调函数,传入callback的值为职位选择器选中项的编号集合(字符串类型,编号 间以逗号分割),options为boxy插件可选参数。

调用例子:选择编号为1的职位小类,编号为2的职位大类,定义选择器的名称为职位类别选择器

1 $(#job).click(function() {
2 Boxy.job(s1,b2, 2, function(val) {
3 alert(你选择的是: + val);
4 }, { title: 职位类别选择器 });
5 return false;
6 });

职位选择器:三级联,调用语句为Boxy.area(value, shown, callback, options),参数value为已选定值编号集合(字符串类型,编号间以逗号分割,以p开头表示选择省份,以c开头表示选择城市,以d开头表示选择县 区),参数shown表示展示的地区的编号,参数callback为可定义回调函数,传入callback的值为地区选择器选中项的编号集合(字符串类 型,编号间以逗号分割),options为boxy插件可选参数。

调用例子:选择编号为1和2的县或区,定义选择器的名称为工作地区选择器

1 $(#city).click(function() {
2 Boxy.area(d1,c7, 1,724, function(val) {
3 alert(你选择的是: + val);
4 }, { title: 工作地区选择器 });
5 return false;
6 });

存在Bug:

1.IE6 checkbox的margin设置会走样,IE6的checkbox边框清空是无效的,但对其它浏览器是有效的,而且很多人喜欢全局设定input的margin/padding为零,为了统一样式,唯有不管IE6了。

2.IE8 环境下,css设置选项<a>的hover效果迟钝甚至没反应,其它浏览器不存在这个问题(包括IE6),js代码解决也不是可取之道,代码hover反应还是有点慢。实在搞不懂IE8为什么会出现这种问题,知道的那位告诉我吧。

3.IE6下超长的选中项,显示的区域不够,在父标签中不会自动换行,而是在显示的选中项自身内部换行输出文字,造成样式走样。这个问题我也不知道怎么解决,谁知道告诉我吧。

4.暂时还没发现(可能大家会说IE6下确定按钮的hover效果,这个也不是什么bug,只是无关紧要的我懒得改,把标签该<a>就行了,不过实在不喜欢<a>,整天为IE6做无用功)。

优点:

1.当然是漂亮呗!

2.三个选择器分别表示三种级联关系的选择器,大家可以直接修改Demo中的数据源,及主体框架中的文字,即可变作其它的选择器。

3.还有改进的空间,谁去把demo的css样式整合一下,发上来吧。

悄悄告诉大家,选择器的外框圆角效果是使用png图片实现的,如果想更改透明程度,唯有重做图片了,如果愿意撇开IE6的话,可以使用另一种常 用的圆角方法(不用图片只用css样式),方法已经写进boxy插件当中了(被我注释掉,包括样式文件),还有一种圆角方法在demo的round- corner.html文件中也介绍了,ExtendedBoxy.html为选择器的demo文件。其它的两个关于Boxy的html文件可是张鑫旭同 学写的哦,张同学博客http://www.zhangxinxu.com/php/上可是有很多好东西的,大家有空上去看看吧。

Demo下载地址:/Files/butongren/jquery-plugin-ExtendedBoxy.rar

[转载]打造自己的JQUERY柱状图插件JQUBar

mikel阅读(1043)

[转载]打造自己的JQUERY柱状图插件【JQUBar】 – RyanDing – 博客园.

一、JQUBAR(V1.0)JQuery插件简介

1.支持.net、java、php等平台。

2.用户可以通过鼠标拖拽柱状图从而改变每根柱子的高度,最终达到通过鼠标拖拽图形界面来修改服务器数据的目的。

3.支持柱状图缩放。

4.目前支持浏览器:IE7、 IE8、 Firefox、Chrome。

二、HTML

1<div id="con"><%--JQUBAR容器--%> 2 </div> 3<input type="checkbox" id="cbZoom" checked="checked" /> 4 <label for="cbZoom">缩放</label> 5<input type="checkbox" id="cbDragable" checked="checked" /> 6<label for="cbDragable">拖拽</label> 7 <br /> 8姓名模糊查询:<input type="text" id="txtName" /> 9<br /> 10<input type="button" id="btnReloadBar" value="重新加载" />

截图如下:

三、JavaScript及CSS 文件引入

1 <script src="<%=Url.Content("~/Scripts/jquery-1.4.1.js")%>" type="text/javascript"charset="utf-8"></script> 2  <script src="<%=Url.Content("~/Scripts/JQUBar/wz_jsgraphics.js")%>" type="text/javascript"></script> 3 <script src="<%=Url.Content("~/Scripts/JQUBar/jquery-ui.min.js")%>" type="text/javascript"></script> 4  <script src="<%=Url.Content("~/Scripts/JQUBar/JQUBar.js")%>" type="text/javascript"></script> 5 <link href="<%=Url.Content("~/Scripts/JQUBar/JQUBar.css")%>" rel="stylesheet" type="text/css" />

注:以上文件请引入至html <head></head>内。

四、加入JavaScript 代码

1 <script type="text/javascript"> 2 $(function () { 3 $("#con").jQUBar({ 4 zoom: true, 5 drag: true, 6 url: '<%=Url.Action("LoadData") %>' 7 }); 8 9 $("#btnReloadBar").click(function () { 10 $("#con").setBarParam({ 11 zoom: $("#cbZoom").attr("checked"), 12 drag: $("#cbDragable").attr("checked"), 13 //提供json数据,方便 .net java php 调用。本例在Asp.net MVC2.0下演示 14   url: '<%=Url.Action("LoadData") %>/?name=' + $("#txtName").val() 15 }).reload(); 16 }); 17 }); 18 </script>

注:以上js脚本同样请加入html <head></head>内。

五、ASP.NET MVC2.0 服务端代码

1 private decimal[] GetPricesByEmployeeId(int employeeId) 2 { 3 decimal[] result = null; 4 result = _Context.Orders.Where(o => o.EmployeeID == employeeId) 5 .Take(5) 6 .Select(oo => (decimal)oo.ShipVia).ToArray(); 7 return result; 8 } 9 10  public JsonResult LoadData(string name) 11 { 12 13 var data = (from e in _Context.Employees.Take(10).ToList() 14 select new 15 { 16 EmployeeID = e.EmployeeID, 17 Orders = GetPricesByEmployeeId(e.EmployeeID), 18 Name = e.FirstName, 19 }).Distinct(); 20 21 if (!string.IsNullOrEmpty(name)) 22 { 23 data = data.Where(d => d.Name.IndexOf(name) >= 0); 24 } 25 26 return Json(new { Success = true, Msg = data }, JsonRequestBehavior.AllowGet); 27 }

注:为方便阅读使用NORTHWIND 数据库。

六、程序运行截图

缩放:

移动:

最后:由于时间仓促未能对JQUBAR1.0插件系统测试,如果您感兴趣可以在这里下载JQUBAR1.0插件。

衷心的感谢各位园友对该插件提出您的宝贵意见,根据大家的意见我将抽出时间对JQUBAR1.0插件进行升级。

同时也希望本篇文章可以帮您解决开发中碰到的问题。

[转载]泛型 List 和 Dictionary 类的互相转换

mikel阅读(1352)

[转载]泛型 List 和 Dictionary 类的互相转换 – snapping – 博客园.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace testcs
{
    class Program
    {
        static void Main(string[] args)
        {
            ListAndDictionary();

        }

        /// <summary>
        /// 泛型 List 和 Dictionary 类的互相转换
        /// </summary>
        private static void ListAndDictionary()
        {
            // dict -> list 
            // 转换为 List<T>,T 的类型是 KeyValuePair<TKey, TValue>
            Dictionary<string, int> d = new Dictionary<string, int>();
            var l = d.ToList();

            List<KeyValuePair<string, int>> l2 = new List<KeyValuePair<string, int>>{
                new KeyValuePair<string,int>("a", 1),
                new KeyValuePair<string,int>("b", 2)
            };


            // list -> dict 两种转换方式

            // 1. 可指定 keySelector 和 valueSelector;完全自定义字典 key, value 的类型            
            Dictionary<string, int> d2 = l2.ToDictionary(entry => entry.Key, entry => entry.Value);
            // 2. 也可只指定 keySelector, value 为 entry 的值。
            Dictionary<float, KeyValuePair<string, int>> d3 = l2.ToDictionary(
                entry => (float)entry.Value);
        }
    }
}

[转载]文档在线预览:总体思路

mikel阅读(1144)

[转载]文档在线预览:总体思路 – I can being – 博客园.

近两年出现了许多以“经验交易”为核心的文档平台,如豆丁网、百度文库、星期八等网站。这些网站将文档(知识)存放在网站(平台)上,供用 户浏览、讨论、下载,配以良好的积分体系和金钱激励(运营),完美的协调好知识分享与知识传播之间的微妙关系。这样即有Web2.0的用户互动,也有 Web3.0的价值分配,对社会也是非常好的资源重用,是非常棒的一种运营模式。
从技术层面 讲,这类网站的创新主要有文档预览、知识商城和SNS三个块。今年初公司也决定在公司内部引入这种模式,以实现公司内部文档特别是售前方案的分享,很荣 幸,我被安排为此项目的技术经理,也专门研究了文档在线预览的技术。如今项目已经上线将近百天,也是时候整理一下思路,这篇博客主要就是分析一些文档在线 预览的技术细节,其实网上已经有很多类似的文章,但大多没有说得很清楚,也比较零乱,所以我想整理一个完整的文章来。文章内容将会涉及:总体思路、预览实现细节、缩略图实现、百度阅读器使用等。
文档预览即文档以flash的形式在网页上展示,所以要解决两个问题:以什么格式展示flash、文档如何转化为符合格式的flash
展示flash有两种方式,一种是直接生成好一个完整的flash展示出来,一种是用一个播放器来播放另外一个文档flash。第一种方式可以用 SWFTools的工具直接将pdf转化成一个整体的flash展示,但这种方式的flash较大,且不容易控制,故用得较少。第二种方式是重点,首先需 要了解的是一个开源的flexpaper播放器,它可以播放一帧一页的flash;在flexpaper的基础上,如果遇到大文档则会出现速度和性能的问题,这个时候需要像百度文库、豆丁一样修改flexpaper,让它支持一次仅读取指定页数的flash;如果文档安全级别较高,不允许下载查看,则需要给flexpaper加上加密解密算法;如果需要登录用户才能查看,则要让flexpaper有登录UI
转化文档为flash的思路有一条,但有多种实现方式。一般文档需要先转化为pdf,再从pdf转化为flash。转化为pdf的方法有很多,例如使用虚拟打印机、使用MicrosoftOffice的API、使用OpenOffice转化等,不过转化的过程中,可能由于文档有误、损坏、加密等原因造成转化失败。从pdf转化为flash就简单了许多,直接使用SWFTools的pdf2swf即可实现多种方式的转化。
下图是文档转化到swf的一个流程,其中type是文档的一个状态标识(0表示未处理过的文档,1表示已生成pdf,2表示已生成flash,-1表示不受支持的文档格式,-2表示转化为pdf失败,-3表示转化为flash失败)

[转载]高性能MMORPG通用服务端引擎设计之->基本概念篇

mikel阅读(890)

[转载]高性能MMORPG通用服务端引擎设计之->基本概念篇 – 懒人居 – Coding for fun – 博客园.

鉴于公司保密协议,本系列文章将不涉及具体的游戏细节以及实现。由于本人也是第一次参与此类引擎的设计,所以难免有所失误,如有异见欢迎业内人士讨论,发表本系列文章的目的不在于说教,重在分享以及讨论。
MMORPG 的服务端引擎是驱动整个游戏的总要部件,而且对于现在外挂满天飞的年代,服务端的地位变得愈发重要,很多游戏都将很多原来由客户端处理的逻辑交给了服务端 来处理,以避免各类外挂对游戏公平性造成的影响。要设计一款通用的且高性能的MMORPG服务引擎是一个非常艰巨的工作,总的来说,一款网游能够承载多少 人,能够实现什么功能,能够开展什么运营活动,都是跟有一款够不够强悍的服务端引擎有密切的关系,可以说服务端引擎就是游戏的心脏,如果设计不好,就会 “心率不齐”,“心肌梗塞”,然后不能支撑足够的在线人数,操作“卡”,最后死掉翘辫子。设计精良的引擎,比如WOW,EVE Online等,则给运营和策划留下来大量的空间,这样游戏的成功也就不存在“技术问题”了。
一般来说,当然是想一个游戏装的用户越多越好,当然 这里有很多现实上的制约,第一是运营上,游戏里总是老玩家等级更高、实力更强,由于游戏的竞争性,玩家都喜欢进新服,所以一组服务器总是在开服的时候开始 在线人数持续攀升,然后在某个点后就会下降并趋于稳定。其二是因为游戏中的场景不是无限大的,有固有的玩家密度限制,如果一个游戏屏幕上到处都塞满人,估 计你也不会觉得好玩。并且根据这两个特点就决定了,MMORPG的服务引擎需要有高性能,这样才能在开服的时候承载尽可能多的用户进入,并且要具备高度的 可伸缩性,在开服用户在线高峰的时候可以用比较多的服务器资源来拉动用户,在平稳运行后能够省出多余的服务器资源来挪给其他的服务器组。
从最简单的来说,MMORPG游戏基本上就是经典的C-S结构的系统,所以最简单的结构就是
Server
|
|

Client

这个时候Server端什么都要处理,就是忒累点,所以承载能力也就不用指望了,扩展能力就更不用想了,不过胜在简单,如果好好设计性能还是有保障 的。有个开源的C#开发的UO的服务引擎实现大家可以借鉴一下,http://www.runuo.com/。其实从本质上来说MMORPG的服务端和企 业应用没有差别,所以我们解决问题的方式也是很相似的,如果性能有问题,一台服务器无法解决问题,就用两台,属于叫分而治之的策略,所以要提高性能,我们 需要从系统的最慢的地方开始。如果有点经验的开发人员都知道,系统中最慢的就是数据库了。所以要提高系统的响应,我们一般是在用户的角色登录的时候直接将 角色的数据读进内存来处理,但是内存的数据不怎么保险,万一服务器当掉或者掉电了怎么办呢,这个问题就需要定时将用户的数据变更发给数据库了,这样就不存 在读写数据库的延迟了,当然掉电的时候在上一次保存后的数据还是会掉,这个时候就叫服务器回档,这种小几率事件一般我们不用特殊处理,一般游戏偶尔出现故 障回档的话基本都是对在线的用户赔点经验装备了事。以后架构还有可能扩张,而为了让你不必将SQL写得满世界都是,我们将数据库操作抽象成数据库服务,为 了多台服务器都可以一视同仁的使用,也也可以单独用一台服务器来作为数据库服务的主机,如下图:

DB-Service
|
Server
|
CLient

这张图看着很眼熟吧,恩,啥三层架构不就是这么画的嘛。囧 这个时候系统的压力就不在数据存储上了,于是压力到了游戏的逻辑上,现在游戏既要同时处 理大量的并发网络请求,且还要对游戏的逻辑进行运算,一边是高IO应用,一边是高CPU运算,都放在一块那就是一半火焰一半海水,不是烧死就是淹死了。高 网络IO并不需要很强的CPU运算性能,比如路由器,一台城域网的核心路由器负担了整个城市的出口网络路由,IO高得吓人,路由器其实也就是一台特殊的电 脑,但是这台核心路由器的CPU其实并不比我们的家用PC的CPU高,甚至有可能低一点。但是游戏的逻辑运算对CPU的消耗就是实打实的消耗了,假设游戏 有1000个玩家在线,这个时候每处理一个事件需要1ms,那么假设每个玩家每秒有4个事件需要处理,那么1000个玩家就把一颗4核CPU或者2颗双核 CPU的计算能力耗尽了,这里还是假设的理想情况,如果再加上NPC,怪物,物品之类的要处理,那就需要非常多的CPU资源,如果所有CPU资源都给了逻 辑运算,网络消息处理所需的CPU能力就不足了,虽然消耗低,但是总是消耗的,所以我们继续采取分而治之的办法来处理,我们把前端服务器和逻辑服务器分 开,前端服务器用来处理大量的用户链接和消息分发,而逻辑服务器用来处理游戏逻辑。由于游戏逻辑更消耗CPU,所以一个前端服务器可以带N台逻辑服务器, 所以结构改成了下图:

Logic-Service   Logic-Service    DB-Service
|                     |                       |
————————————-
|
Front Server
|
Client

我们可以继续将游戏逻辑进行分类,由于MMORPG的每一个玩家从经入游戏开始就是处于一个个的场景当中的,所以逻辑服务器也可以叫场景服务器 (地图服务器),有的游戏即使没有场景切换,其实也是分了很多场景的,只是采用了无缝拼接的技术让你觉得是没有分开的。玩家的逻辑就可以分为连续事件逻辑 和瞬时逻辑。连续事件逻辑是在场景中需要和其他用户发生反映的事件,也可以称之为场景事件,比如我攻击了一个怪,这一个事件需要通知场景里所有的玩家知 道,并且会影响怪接下来的行动。所谓的瞬时事件,就是只会影响玩家自身的状态且不需要通知其他玩家或者说是对场景产生影响的(当然如果对场景产生了影响势 必需要通知场景内其他玩家)。有的事件甚至会跨场景通知系统内所有用户(比如某玩家击杀了某著名BOSS,或者通知师父自己的徒弟在某处遭到了攻击[假如 要实现师徒系统的话])。玩家大部分的逻辑都是在场景内完成的,所以场景逻辑的实现非常的重要。在这个部分的运算涉及到多个对象间的互动,如果想用多线程 来提高并行度来提高性能其实反而会适得其反,因为要保证计算的数据安全避免脏读,在多线程的环境下就需要处理大量的锁,相信在游戏的业务逻辑里还需要处理 锁,防止死锁这里的处理会宁所有的程序员抓狂,对于这种高CPU运算的场景来说,大量的线程也会将宝贵的CPU时间浪费不少在线程切换上,所以一般来说游 戏的逻辑服务器都是单进程单线程的结构,通过一个大循环来驱动整个事件逻辑。那么你可能会问,如果有单进程单线程岂不是只能利用一颗CPU内核了么?当然 一个游戏也不可能只有一个场景嘛,我们可以在一台服务器上跑N个场景服务,处理N个场景的逻辑(根据经验来说,N=CPU内核数量性能最好)。所以你可以 看到为啥上图我不写Logic Server而是写的Logic Service了。
当玩家连接上Front Server后怎么知道要把数据发到那一个Logic Service呢?这里就需要场景管理服务了,根据我的想法,我想在场景管理服务里提供一个用户代理,用户代理知道用户在那个场景中,代理了用户登录场 景,离开场景的行为,以及帮助用户将数据转发到正确的场景服务上,所以结构图继续进化成下图:
Logic-Service   Logic-Service    DB-Service
|                     |                      |
————————————
|
Scene Manager
|

Front Server
|
Client
由 于Front Server的数据都由场景管理服务器转发到场景上,所以我们在前端可以部署多个Front Server,因为一个Front Server只有100M的带宽,当Front Server性能不足或者带宽不足的时候我们可以通过两个来搞定,而Scene Manager只通过用户代理来做包转发,所以承载能力相当的高。再次增强后系统如下图:
Logic-Service   Logic-Service    DB-Service
|                      |                     |
————————————
|
Scene Manager
|
—————-
|                   |
Front Server   Front Server
|                   |
Client         Client

考虑到Front Server有可能会存在CPU剩余的情况,所以也可以将一部分瞬时事件交给Front Server来处理,当然有一个公共的很耗时的瞬时逻辑需要被剥离出来,那就是登录的逻辑,登录的逻辑每一组服务器都一样,所以我们可以将N组服务器的登 录交给一个统一的登录服务器来处理,所以我们再次进化

Logic-Service   Logic-Service    DB-Service
|                     |                     |
———————————–
|
Scene Manager
|
————————————-
|                       |                      |
Front Server   Front Server     Login Server
|                      |
Client             Client

现在看起来大体上已经有点模样了,但是其实还可以根据不同的需求做一些细节上的调整,比如怪物的AI运算,如果仅仅是很简单的逻辑运算,其实就可 以直接在场景服务器的逻辑中处理了(其实有点像把怪物当作了场景的一部分)。如果需要很复杂的AI,就需要将怪物的AI拿到单独的进程里运算了,其实就是 把怪物当成一个特殊的玩家来对待,这种模式比较特殊,由于比较耗资源,一般都对大BOSS采用这种方式。
写了这么多也不知道是不是说明白道清楚 了,不过今天先说到此处打住,下一回我们从细节上来看这每一部分的具体设计,或许还有部分实现。如果在我下一篇写出来前有兴趣和我继续讨论的可以加MSN superpowerlee@hotmail.com或者Gtalk superpowerlee@gmail.com
感谢iiegg的刘洋以及王秋婷同学给我的大力支持,作为一个新人来说得到业界前辈的无私帮助真是非常幸运的事情。

本文为亚历山大同志独立思考之结果,有可能在最终结果可能于某些网络上已有资料不谋而合,皆因为相同产品设计理念相同,非抄袭之过。本文欢迎讨论,欢迎转载,如转载请注明出处,谢谢。

[转载]自定义asp.net mvc的WebFormViewEngine修改默认的目录结构

mikel阅读(976)

[转载]【小技巧】自定义asp.net mvc的WebFormViewEngine修改默认的目录结构 – liulun – 博客园.

先看一下我的解决方案的目录结构吧~~~

一:先把Controller程序提取出来

默认的情况是所有的****Controller.cs文件都会放在Web程序集下的一个叫Controllers的文件夹下

这样感觉有点不爽(你懂的…)

我们决定把所有的Controller程序放到一个自定义的应用程序集中去(上图中的mrlh.Admin.Controllers)

先把web程序集下的Global.asax.cs文件删掉

然后把Global.asax的标记代码改为如下:

<%@ Application Codebehind="mrlh.Admin.Controllers.App.MvcApplication" Inherits="mrlh.Admin.Controllers.App.MvcApplication" Language="C#" %>

这样应用程序启动时就会到我们自定义的应用程序集去执行相关的操作了

mrlh.Admin.Controllers.App.MvcApplication的相关代码如下

namespace mrlh.Admin.Controllers.App
{
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // 路由名称
"{controller}/{action}/{id}", // 带有参数的 URL
new { controller = "XiTong", action = "Index", id = UrlParameter.Optional } // 参数默认值
);
}
protected void Application_Start()
{
//以下两句为启用自定义的WebFormViewEngine
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new MvcViewEngine());
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
}
}
}

这样做之后

所有的Controller程序就不用集中写到web程序集中去了,

就可以写在mrlh.Admin.Controllers这个程序集中了

二:改变View文件夹的目录结构

默认的情况是所有的****.aspx文件都放在web程序集中的Views目录下

这样感觉也有点不爽(你懂的…)

如果想改变aspx文件的目录结构,就必须自定义WebFormViewEngine了

细心的读者会看到在上面的代码中Application_Start方法里前面三句话

//以下两句为启用自定义的WebFormViewEngine
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new MvcViewEngine());

这就是把自定义的 WebFormViewEngine添加到应用程序中去的方法

MvcViewEngine的代码如下

namespace mrlh.Admin.Controllers.App
{
public class MvcViewEngine : VirtualPathProviderViewEngine
{
public MvcViewEngine()
{
MasterLocationFormats = new[] {
"~/{1}View/{0}.master",
"~/SharedView/{0}.master"
};
AreaMasterLocationFormats = new[] {
"~/Areas/{2}/Views/{1}/{0}.master",
"~/Areas/{2}/Views/Shared/{0}.master",
};
ViewLocationFormats = new[] {
"~/{1}View/{0}.aspx",
"~/{1}View/{0}.ascx",
"~/SharedView/{0}.aspx",
"~/SharedView/{0}.ascx"
};
AreaViewLocationFormats = new[] {
"~/Areas/{2}/Views/{1}/{0}.aspx",
"~/Areas/{2}/Views/{1}/{0}.ascx",
"~/Areas/{2}/Views/Shared/{0}.aspx",
"~/Areas/{2}/Views/Shared/{0}.ascx",
};
PartialViewLocationFormats = ViewLocationFormats;
AreaPartialViewLocationFormats = AreaViewLocationFormats;
}
protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
{
return new WebFormView(partialPath, null);
}
protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
{
return new WebFormView(viewPath, masterPath);
}
}
}

这样做之后类似这样的请求

http://localhost:12232/YuanGong/YuanGong

都会在web程序集中找到YuanGongView/YuanGong.aspx

然后再呈现给“观众”

注意:

这里不能试图把每个文件夹名字中后面的”View”字样去掉,

因为ASP.NET MVC如果发现服务器的物理路径上存在相应的文件,将直接输出了

也就是请求是这样的http://localhost:12232/YuanGong/YuanGong

发现服务web目录下对应有此文件YuanGong/YuanGong.aspx

将直接输出

三:自定义目录结构的好处

我之所以这样做一个是为了感官上的舒服,毕竟自己的程序跟自己的媳妇一样

不但要从触觉上考虑,还要从视觉上考虑

另外还可以把多个web程序集的controller程序放在同一个程序集中方便代码的重用

(忽然觉得好像面向服务编程)

其三目录结构改变了,也方便权限的控制

demo:http://files.cnblogs.com/liulun/MRLH.rar

[转载]ASP.NET MVC 框架结构图

mikel阅读(997)

[转载]ASP.NET MVC 框架结构图 – 哲学驱动设计 – 博客园.

最近在学ASP.NET MVC,画了一些图,和大伙分享下:


Routing 组件

image

图1 独立的ASP.NET Routing组件


MVC-Controller

image

图2 Controller结构

image

图3 Controller中可用的ActionResult


MVC-View

image

图4 使用的抽象工厂模式的视图引擎

image

图5 视图模型

[转载]C#调用dephi的dll之详解-完整版_附有可下载Demo

mikel阅读(1152)

[转载]C#调用dephi的dll之详解-完整版_附有可下载Demo – elivn – 博客园.
C#调用Dephi接口方法,有两种解决办法:

一、将Dephi程序编译成一个COM组件,然后在C#里引用COM组件。

二、非托管调用Dephi的DLL文件。

这里我们主要讲解一下第二种方法,讲第二种方法之前首先讲解下DllImport。

DllImport是System.Runtime.InteropServices命名空间下的一个属性类,其功能是提供从非托管DLL导出的函数的必要调用信息。

DllImport属性应用于方法,要求最少要提供包含入口点的dll的名称。
DllImport的定义如下:

代码

1 [AttributeUsage(AttributeTargets.Method)]
2 public class DllImportAttribute: System.Attribute
3 {
4 public DllImportAttribute(string dllName) {…} //定位参数为dllName
5 public CallingConvention CallingConvention; //入口点调用约定
6 public CharSet CharSet; //入口点采用的字符接
7 public string EntryPoint; //入口点名称
8 public bool ExactSpelling; //是否必须与指示的入口点拼写完全一致,默认false
9 public bool PreserveSig; //方法的签名是被保留还是被转换
10 public bool SetLastError; //FindLastError方法的返回值保存在这里
11 public string Value { get {…} }
12 }
13

上面DLL的名字有时需要写上路径的如[DllImport(@”C:\OJ\Bin\Judge.dll”)]这样指定DLL的绝对路径就可以正常装载。

假如没有路径的话,DllImport会按照顺序自动去寻找的地方:
1、exe所在目录
2、System32目录
3、环境变量目录
所以只需要你把引用的DLL 拷贝到这三个目录下, 就可以不用写路径了。

说明:
1、DllImport只能放置在方法声明上。
2、DllImport具有单个定位参数:指定包含被导入方法的 dll 名称的 dllName 参数。
3、DllImport具有五个命名参数:
a、CallingConvention 参数指示入口点的调用约定。如果未指定 CallingConvention,则使用默认值 CallingConvention.Winapi。
b、CharSet 参数指示用在入口点中的字符集。如果未指定 CharSet,则使用默认值 CharSet.Auto。
c、EntryPoint 参数给出 dll 中入口点的名称。如果未指定 EntryPoint,则使用方法本身的名称。
d、ExactSpelling 参数指示 EntryPoint 是否必须与指示的入口点的拼写完全匹配。如果未指定 ExactSpelling,则使用默认值 false。
e、PreserveSig 参数指示方法的签名应当被保留还是被转换。当签名被转换时,它被转换为一个具有 HRESULT返回值和该返回值的一个名为 retval 的附加输出参数的签名。如果未指定 PreserveSig,则使用默认值 true。
f、SetLastError 参数指示方法是否保留 Win32″上一错误”。如果未指定 SetLastError,则使用默认值 false。
4、它是一次性属性类。
5、此外,用 DllImport 属性修饰的方法必须具有 extern 修饰符。

下面讲解下如何调用:

用DllImport来调用的  一般是用非托管的。
具体形式如下:1.[DllImport(“WZFSE.dll”, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]。

其中第一个参数是指要引用DLL的名字, 这个名字应该是个常量(否则会出错)。
要想在自己C#页面中引用,那就得在页面中申明这个函数。

下面紧接着他的申明函数:
2.public static extern void InitDll(IntPtr handle, bool methodAddress);(Dephi里怎么定义的函数在C#这里就要怎么定义:即Dephi的申明函数转换成C#的声明函数)。
–申明一个函数就要引用下他的DLL 如1和2是紧密连在一起的。即再写一个函数就相应的应用起对应的DLL。

下面是参数的引用:即Delphi的类型向C#的转换。

第一个参数类型:IntPtr这个类型可以申明为其他语言的句柄,指针等。
若要实现其他语言类似C++的函数指针形式, 这时我们考虑用C#的委托来实现。

下面说一下:如何将Dephi的窗体显示在自己的页面中(且不能显示dephi窗体的标题栏,实现无缝的结合)。

将dephi的窗体签入到自己的C#系统里 还有一点比较重要,我们是调用dephi的窗体,此时显示在我们C#窗体中会有dephi的窗体,

这时我们怎么办呢,  怎么去除dephi中的窗体呢?  这时我们就需要用API函数了。 因为WINDOWS API是一种比较底层的语言,可以通过它进行操作。

在C#中是这么引用的: [DllImport(“user32.dll”, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern void MoveWindow(IntPtr handler, int x, int y, int width, int height, bool repaint);

下面插入一个类,这里面包含了怎么引用dephi的dll 以及怎么申明:

代码

1 public class CompliancePlatDLL
2 {
3 public static string strPath = “”;
4 /// <summary>
5 /// 初始化
6 /// </summary>
7 /// <param name=”handle”></param>
8 /// <param name=”methodAddress”></param>
9 [DllImport(WZFSE.dll, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
10 public static extern void InitDll(IntPtr handle, bool methodAddress);
11 /// <summary>
12 /// 加载相应的服务
13 /// </summary>
14 /// <param name=”str”></param>
15 /// <param name=”str2″></param>
16 /// <param name=”i”></param>
17 /// <returns></returns>
18 [DllImport(WZFSE.dll, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
19 public static extern IntPtr wzLoadModule(string str, string str2, int i);
20 /// <summary>
21 /// 去除相应的服务
22 /// </summary>
23 /// <param name=”handle”></param>
24 /// <returns></returns>
25 [DllImport(WZFSE.dll, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
26 public static extern bool wzUnloadModule(IntPtr handle);
27
28 #region API函数
29 /// <summary>
30 /// API函数 设置主辅窗体
31 /// </summary>
32 /// <param name=”child”></param>
33 /// <param name=”parent”></param>
34 [DllImport(user32.dll, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
35 public static extern void SetParent(IntPtr child, IntPtr parent);
36 /// <summary>
37 /// API函数 移动窗体
38 /// </summary>
39 /// <param name=”handler”></param>
40 /// <param name=”x”></param>
41 /// <param name=”y”></param>
42 /// <param name=”width”></param>
43 /// <param name=”height”></param>
44 /// <param name=”repaint”></param>
45 [DllImport(user32.dll, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
46 public static extern void MoveWindow(IntPtr handler, int x, int y, int width, int height, bool repaint);
47
48 [DllImport(user32.dll, EntryPoint = GetWindowLong)]
49 public static extern long GetWindowLong(IntPtr hwnd, int nIndex);
50 /// <summary>
51 /// API函数 去除窗体的标题栏
52 /// </summary>
53 /// <param name=”hwnd”></param>
54 /// <param name=”nIndex”></param>
55 /// <param name=”dwNewLong”></param>
56 /// <returns></returns>
57 [DllImport(user32.dll, EntryPoint = SetWindowLong)]
58 public static extern long SetWindowLong(IntPtr hwnd, int nIndex, long dwNewLong);
59 public const int GWL_EXSTYLE = 16;
60 public const int WS_EX_TRANSPARENT = 0x20;
61 public const int WS_EX_LAYERED = 0x80000;
62 public const int LWA_ALPHA = 2;
63 public const int WS_CAPTION = 0xC00000;
64 #endregion
65 }

其中API中的SetWindowLong这个方法是可以实现去除窗体的标题栏的,  具体调用SetWindowLong(common.p, GWL_EXSTYLE, GetWindowLong(handle, GWL_EXSTYLE) & (~WS_CAPTION));

但一般完整利用API函数的调用是这样的

代码

1 decallback de1 = new decallback(iscallback);//利用委托
2 InitDll(this.Handle, de1(this.Handle));//初始化
3 IntPtr p = wzLoadModule(DoRiskSetup, “”, 0);//取得句柄
4 if (p != (IntPtr)0)//判断该句柄不是弹出窗体时
5 {
6 //去除dephi窗体的标题栏
7 SetParent(p, panel1.Handle);
8 SetWindowLong(p, GWL_EXSTYLE, GetWindowLong(p, GWL_EXSTYLE) & (~WS_CAPTION));
9 MoveWindow(p, 0, 0, panel1.ClientSize.Width, panel1.ClientSize.Height, false);
10 }

SetWindowLong(IntPtr handle, int t,long l) 第一个参数为句柄,是你调的dephi窗体的句柄,第二个参数为整型,在dephi用常量GWL_EXSTYLE表示,表示要显示的样式,在C#中翻译过 来的他值为(-16),而第三个函则为长整型和第二个参数一起表示要去除第一个参数句柄窗体的标题栏在dephi中表示 为:GetWindowLong(handle,GWL_EXSTYLE) and (not WS_CAPTION) 在C#中则翻译为:GetWindowLong(handle,-16)&(~0xC00000),handle是指要调用的dephi窗体的句 柄,GetWindowLong这个函数是获得该窗体的相关信息。大体上是这个用法,如有不懂大家可以提出来 共同探讨。

一般类型对应如下:

Dephi–>C#

intger –>int

longint –>long

pchar –>string

THandle –>IntPtr

上图为C#窗体调用的dephi的情况。

注:上面的dll的名称只是个例子 具体还要看你要引用哪个dll  API中的函数在C#中是这样引用的

表达能力有限 希望对你们有帮助··具体不懂可邮箱联系: elivn@vip.qq.com

调Delphi的DLL.rar 一个简单的调用Demo,  希望对大家有用。由于自己使用的地方文件太大就用了同事的一个简单的调用Dephi的Demo。

如有转载 请注明出处!

[转载]简单实用的防止多次提交辅助类

mikel阅读(1117)

[转载]简单实用的防止多次提交辅助类 – 破狼 – 博客园.

一:  开题

这篇只是一个简单的应用技巧,高手请跳过,别拍砖,打击我这个有激情的菜鸟。在我们的web项目中经常会遇见由于网络原为等问题,而导致在页面提高后,服 务器还没有来得及返回的时候,我们的用户可能在此点击按钮使的数据多次的提交。防止这个行为很简单,我们一般经常是在按钮点击后使其禁用 disabled=true。我是一个很懒的人(生活中并不懒,只是写Code比较懒,我的目标是:少写Code,基于配置而不写Code是最好的3]6GJ(EWN[K2P[Z6B`6B`2H)。 所以就有了这个简单的辅助类:我的思路是在page的PreRender时间中注册提交前执行的脚本全部提交按钮的disabled=true(  page.ClientScript.RegisterOnSubmitStatement()。)等待服务器返回时会更具返回浏览器会重绘,所以我们的 设置此时已经无用了。呵呵就这面简单。但是为不少写代码,那些了一个辅助类DoubleSubmitPrevent,提供的几种方式自动按照按钮,或者是 手动添加按钮(取决于IsAutoFind),自动查找的起点默认为page,但是为了效率你可以自己设置BaseContrlForFind,关于需要 禁止的按钮的判断为IsPreventControl你可以自己定义覆盖默认的,默认为:

代码

private System.Predicate<System.Web.UI.Control> isPreventControl = t => (t is System.Web.UI.WebControls.Button) ||
(t
is System.Web.UI.WebControls.LinkButton) ||
(t
is System.Web.UI.WebControls.ImageButton) ||
(t
is System.Web.UI.HtmlControls.HtmlButton) ||
//(t is System.Web.UI.HtmlControls.HtmlLink) ||
(t is System.Web.UI.HtmlControls.HtmlInputButton) ||
(t
is System.Web.UI.HtmlControls.HtmlInputSubmit);

如果你还是觉得效率不好那么,你就可以自己Add或者AddRange,同时包括了Remove,Insert等方法,这一系列方法都支持链式操作 (这是第一次使用JQuery的时候给我的最大触动)。例 如:dsp.Add(Button1).Add(Button2).Add(Button3).Add(LinkButton1).Add(LinkButton2) =dsp.AddRange(Button1,Button2,Button3,LinkButton1,LinkButton2);包括的多个重载;

二: Code部分

说了这么多还是直接上代码:

代码

namespace Wolf.Utils
{
public class DoubleSubmitPrevent
{
private System.Collections.Generic.List<string> _clientIDList = null;
private const string DOUBLE_SUBMIT_PREVENT_STR = B3F6F682-F404-4519-9F30-79876E5A5C9A_WOLF_DOUBLESUBMITPREVENT_391B8D4F-757E-4005-8262-062652D8BAC6;
private bool isAutoFind = false;
#region judje  Prevent Control?
private System.Predicate<System.Web.UI.Control> isPreventControl = t => (t is System.Web.UI.WebControls.Button) ||
(t
is System.Web.UI.WebControls.LinkButton) ||
(t
is System.Web.UI.WebControls.ImageButton) ||
(t
is System.Web.UI.HtmlControls.HtmlButton) ||
//(t is System.Web.UI.HtmlControls.HtmlLink) ||
(t is System.Web.UI.HtmlControls.HtmlInputButton) ||
(t
is System.Web.UI.HtmlControls.HtmlInputSubmit);
#endregion
private System.Web.UI.Control baseContrlForFind = null;

/// <summary>
/// Auto Find will satrt with this Control;Default this Page .
/// </summary>
public System.Web.UI.Control BaseContrlForFind
{
get { return baseContrlForFind; }
set { baseContrlForFind = value; }
}

/// <summary>
/// judje the Contrl that be prevented;
/// </summary>
public System.Predicate<System.Web.UI.Control> IsPreventControl
{
get { return isPreventControl; }
set { isPreventControl = value; }
}
/// <summary>
/// Auto Find the Control that be prevented ?
/// </summary>
public bool IsAutoFind
{
get { return isAutoFind; }
set { isAutoFind = value; }
}

public DoubleSubmitPrevent(System.Web.UI.Page page)
{
_clientIDList
= new System.Collections.Generic.List<string>();
baseContrlForFind
= page;
page.PreRender
+= new System.EventHandler(DoubleSubmitPreventPagePreRenderHick);
}

public DoubleSubmitPrevent Add(string clientID)
{
_clientIDList.Add(clientID);
return this;
}
public DoubleSubmitPrevent Add(System.Web.UI.Control ctr)
{
_clientIDList.Add(ctr.ClientID);
return this;
}

public DoubleSubmitPrevent AddRange(params string[] clientIDs)
{
_clientIDList.AddRange(clientIDs);
return this;
}

public DoubleSubmitPrevent AddRange(params System.Web.UI.Control[] ctrs)
{
foreach (var item in ctrs)
{
Add(item);
}
return this;
}

public DoubleSubmitPrevent Remove(string clientID)
{
_clientIDList.Remove(clientID);
return this;
}

public DoubleSubmitPrevent Remove(System.Web.UI.Control ctr)
{
_clientIDList.Remove(ctr.ClientID);
return this;
}

public bool Exists(string clientID)
{
return _clientIDList.Exists(t => t.Equals(clientID));
}

public bool Exists(System.Web.UI.Control ctr)
{
return _clientIDList.Exists(t => t.Equals(ctr.ClientID));
}

protected virtual void DoubleSubmitPreventPagePreRenderHick(object sender, System.EventArgs e)
{
System.Web.UI.Page page
= sender as System.Web.UI.Page;
if (page != null)
{

if (isAutoFind)
{
#region Find Action
System.Action
<System.Collections.Generic.List<string>, System.Web.UI.Control> action = null;
action
= (list, ctr) =>
{
if (ctr != null)
{
if (isPreventControl(ctr))
{
list.Add(ctr.ClientID);
}
foreach (System.Web.UI.Control item in ctr.Controls)
{
action(list, item);
}
}

};
#endregion
action(_clientIDList, baseContrlForFind);

}

System.Text.StringBuilder sb = new System.Text.StringBuilder();
foreach (var item in _clientIDList)
{
sb.Append(
string.Format( document.getElementById(\{0}\).disabled=true;, item));
}
page.ClientScript.RegisterOnSubmitStatement(
this.GetType(), DOUBLE_SUBMIT_PREVENT_STR, sb.ToString());
}
}
}
}

三: 测试:

为了模拟延时,我在后台加了睡眠:

代码

protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
System.Threading.Thread.Sleep(
1000 * 5);
TextBox1.Text
= DateTime.Now.ToString();
Button3.Enabled
= false;
}
Wolf.Utils.DoubleSubmitPrevent dsp
= new Wolf.Utils.DoubleSubmitPrevent(this) { IsAutoFind = true, BaseContrlForFind = this.form1 };
//dsp.Add(Button1).Add(Button2).Add(Button3).Add(LinkButton1).Add(LinkButton2);

}

前台html(乱托乱扔的,看来是比较懒8{U`QQB5X27@C_FO](KQ(4G):

代码

<form id=form1 runat=server>
<asp:TextBox ID=TextBox1 runat=server></asp:TextBox>
<asp:Button ID=Button1 runat=server Text=Button Enabled=false />
<asp:Button ID=Button2 runat=server Text=Button />
<asp:Button ID=Button3 runat=server Text=Button />
<asp:LinkButton ID=LinkButton1 runat=server>LinkButton</asp:LinkButton><asp:LinkButton
ID
=LinkButton2 runat=server>LinkButton</asp:LinkButton>
</form>

效果:

F]KRP2ZDF95F1FSZ)L57(NN

如果你又更好的方案,也希望能给我分享,请大家多多指教。

[转载]flash wmode="window" 时的遮挡问题

mikel阅读(1049)

[转载]flash wmode=”window” 时的遮挡问题. – Franky – 博客园.

在本文开始前 , 我先引入,摸同学的文档. 来说明一些问题.然后我在此基础上,会做一些扩展说明.

基于以上的认识,我们开始接下来的话题…
我们所要解决的是这样一种需求: 当我们 现在有一个很大滴 flash 在页面上,且wmode 必须为window的前提下…如何使我们的一些元素不被 flash遮挡的呢?

遗憾的是,我所能给出的答案是 . 并不完美.我仍然无法搞定 opera 和 safari 两款浏览器. 那么此文 希望可以起到抛砖引玉的作用吧.
其实答案很简单. 在展示元素下面、flash上面放一个iframe.
一个最佳实现方式是:
<iframe src=”about:blank” width=”300″ height=”200″ frameBorder=”0″ style=”z-index:-1;position:absolute;top:0;left:0;border:0″></iframe>
把这样的一个iframe 按照你喜欢的方式 放入元素中.(应该是该元素直系子节点.)其中 width height 为元素宽高. 重要属性z-index:-1.是我们的救星.
当然,最后别忘了加个透明度 0 ..否则ie下很郁闷.
好吧中心思想就是这个.但是,这个办法并不是所有浏览器都有效. 并且,各个浏览器总会有这样或那样的bug存在:
严重问题:
Safari : 无效.
Opera : 无效.
FireFox 3.6 及 4.0 demo : 无效.
FireFox 3.5 及之前版本 . 元素 position : fixed 以外的值. 无效. (即必须当节点的position:fixed时,才ok )

幸运的是对于FireFox3.6 及4.0 demo 我们已经无需借助iframe来修复.只需要给元素简单设置一个background 非 transparent 的值即可.
要注意的是,如果background 是一个image 那么,如果image 有透明部分,则任然会有问题.
FireFox 3.6 及 4.0 demo : 当使用background 修正时,如果这个修正仅针对元素内部的表格元素的 空td 则无效.(解决办法给td : display:block,或想办法 让td具备一个有效的宽高).

对于 FireFox 3.5 及之前版本,首先我建议放弃修复, 如果非要修复.则只好使用position:fixed,再配合中间的iframe,然后通过一系列js 修补其行为.让他看起来是正常的.

一些小问题:
IE6-IE9demo : 在flash与当前窗口上其他元素 切换焦点时, 元素会被flash遮挡.
IE7: 当 元素为 position:fixed时,滚动条滚动后.元素会被flash遮挡.
搜狗高速浏览器 2.1及之前的版本,webkit内核下: 当元素位置发生改变时. 会保留一个残影.(残影数一般只有一个,由于中间的iframe造成)

以上小问题.都可以通过触发Render Tree 全局 Reflow 修复.  除了QQ
考虑下面的代码:
var border = document.body.style.border ;

document.body.style.border = border == ‘solid 1px #000’  ?  ‘solid 1px #001’ : ‘solid 1px #000’ ;

document.body.offsetWidth; //强制浏览器flush当前的reflow队列.
document.body.style.border = border; //恢复border 原始值.

border 属性和值是随意的.只要你能引起全局的reflow 并且视觉上无影响.如何做都是可以的.. 比如ie下 可以用.body.style.zoom.
你甚至可以不实用offsetWidth,在1、0之间切换 zoom ,就可以直接造成reflow…  读取body.offsetWidth.可以绕过.浏览器对reflow队列的优化.


棘手的小问题:
QQ5  浏览器   webkit 内核下: 当元素位置发生改变时,产生残影造成花屏的现象.
此问题,全局reflow可以改善花屏效果.但连续移动中.视觉上更多的感觉是.元素被flash遮盖住了.直到元素停止移动.

搜狗高速浏览器 2.1及之前的版本,webkit内核下: 当元素所处 平面位置在flash外边时,而此时元素内部某子元素通过定位调整. 与flash 在平面上有交集时,交集部分会被flash遮盖.
此问题.需要修改元素 DOM结构来解决.暂时也无甚好的方法.

所有使用. chromium开源项目的 webkit内核的浏览器如:Chrome全系,maxthon3、搜狗高速浏览器、QQ5浏览器、360高速浏览器.下
使用iframe修复遮盖后. 动态修改 元素.style.clip 时. 由于元素可视区域变化.而造成的 iframe 残留阴影问题(此阴影与flash下面的背景同色).
应避免使用clip属性. 以避免此bug的出现.


好了 到了结束的时候了..

列出毛病最少的几个浏览器 也就是基本不需要使用 reflow的浏览器
chrome  maxthon3 搜狗高速浏览器2.2 FF3.6 +  以及使用比较新的chromium 开源项目所提供内核的浏览器 比如 360 高速浏览器 以及 等等 所谓高速浏览器的 国产山寨货们.

其中比较难搞的浏览器是搜狗2.2 和之前版本的 webkit判断.. 当然userAgent是有区别. 我仍然给出一个基于特性的检测方法:

var win = window,
isWebkit = !!+’\v1′ && !win.XDomainRequest && !navigator.taintEnabled;
if(isWebkit && !!win.external && ‘StartPageCall’ in external && !(‘localdb’ in external)){
//这里是你需要修复的搜狗高速浏览器webkit内核下 版本小于2.2的 浏览器 需要的逻辑.
}

好吧,代码很悲剧.我不得不承认这一点.