最近使用bootstrap这个前端框架其中的模态对话框效果,我们知道国外的东西用在国内项目上最头疼的就是传值乱码问题,这里先介绍下模态对话框传值的介绍(不是直接访问静态html或者直接打开写在当前界面的一个层里而是打开一个后台,将所需要的值处理好再传值前台的模态对话框).首先看下英文介绍:诸如
<a data-toggle="modal"href="remote.html"data-target="#modal">click me</a> 这样的例子,当然还需要个目的显示层。废话不多说,下面贴出笔者自己修改的模态对话框部分的代码,使用者可以自行覆盖bootstrap.js的相关模块,这里如果不商用应该不涉及版权问题。下面代码的重点是将远程url的参数分解,即以"?"划分请求正文部分和参数部分。这里url对应的对象是this.options.remote,我们只要对这个对象处理就好了,读者可以打印下这个对象,它本身只是个url字符串,我们所遇到的乱码问题也是源自此。jquery的load()函数最全的属性设置如下"
$("#feeds").load("feeds.php", {limit: 25}, function(){
alert("The last 25 entries in the feed have been loaded");
});
"(该例子引自jquery1.7.2的文档)。bootstrap源码this.options.remote && this.$element.find('.modal-body').load( this.options.remote);(为下面代码修改后的line24)似乎并没有考虑中文参数的问题,所以才出现这种情况因此我们要做的只是变更它的方法样式就可以实现中文乱码的解决方案了。另外笔者这里还解决了如果重复点击模态下拉的按钮会卡并且重复显示相同数据的问题(这里的原因是对数据进行了缓存)这里就不做介绍了。
1 /* MODAL CLASS DEFINITION
2 * ====================== */
3
4 var Modal = function (element, options) {
5 this.options = options
6 this.$element = $(element)
7 .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
8 this.options.remote && this.$element.find('.modal-body').empty();
9 var str=this.options.remote;
10 var sendok=str.substr(0,str.lastIndexOf("?"));
11 str=str.substr(str.lastIndexOf("?")+1,str.length);
12 if(str!=""){
13 var params=str.split("&");
14 var sendpara="{";
15 for(var i=0;i<params.length;i++){
16 if(params!=""){
17 var paramsd=params.split("=");
18 sendpara+=("\""+paramsd[0]+"\""+":"+"\""+paramsd[1]+"\"")+",";
19 }
20 }
21 }
22 sendpara=sendpara.substring(0,sendpara.lastIndexOf(","))+"}";
23 sendpara= eval("("+sendpara+")");
24 this.options.remote && this.$element.find('.modal-body').load(sendok,sendpara);
25 }
26
27 Modal.prototype = {
28
29 constructor: Modal
30
31 , toggle: function () {
32 // return this[!this.isShown ? 'show' : 'hide']()
33 }
34
35 , show: function () {
36 var that = this
37 , e = $.Event('show')
38 this.$element.trigger(e)
39 if (this.isShown || e.isDefaultPrevented()) return
40 this.isShown = true
41 this.escape()
42 this.backdrop(function () {
43 var transition = $.support.transition && that.$element.hasClass('fade')
44
45 if (!that.$element.parent().length) {
46 that.$element.appendTo(document.body) //don't move modals dom position
47 }
48 that.$element.show()
49 if (transition) {
50 that.$element[0].offsetWidth // force reflow
51 }
52 that.$element
53 .addClass('in')
54 .attr('aria-hidden', false)
55 that.enforceFocus()
56 transition ?
57 that.$element.one($.support.transition.end, function () { that.$element.focus().trigger('shown') }) :
58 that.$element.focus().trigger('shown')
59
60 })
61 }
62
63 , hide: function (e) {
64 e && e.preventDefault()
65
66 var that = this
67
68 e = $.Event('hide')
69
70 this.$element.trigger(e)
71
72 if (!this.isShown || e.isDefaultPrevented()) return
73
74 this.isShown = false
75
76 this.escape()
77
78 $(document).off('focusin.modal')
79
80 this.$element
81 .removeClass('in')
82 .attr('aria-hidden', true)
83 $.support.transition && this.$element.hasClass('fade') ?
84 this.hideWithTransition() :
85 this.hideModal()
86 $(".showall").each(function(index) {
87 $(this).remove();
88 })
89 }
90
91 , enforceFocus: function () {
92 var that = this
93 $(document).on('focusin.modal', function (e) {
94 if (that.$element[0] !== e.target && !that.$element.has(e.target).length) {
95 that.$element.focus()
96 }
97 })
98 }
99
100 , escape: function () {
101 var that = this
102 if (this.isShown && this.options.keyboard) {
103 this.$element.on('keyup.dismiss.modal', function ( e ) {
104 e.which == 27 && that.hide()
105 })
106 } else if (!this.isShown) {
107 this.$element.off('keyup.dismiss.modal')
108 }
109 }
110
111 , hideWithTransition: function () {
112 var that = this
113 , timeout = setTimeout(function () {
114 that.$element.off($.support.transition.end)
115 that.hideModal()
116 }, 500)
117
118 this.$element.one($.support.transition.end, function () {
119 clearTimeout(timeout)
120 that.hideModal()
121 })
122 }
123
124 , hideModal: function () {
125 var that = this
126 this.$element.hide()
127 this.backdrop(function () {
128 that.removeBackdrop()
129 that.$element.trigger('hidden')
130 })
131 }
132
133 , removeBackdrop: function () {
134 this.$backdrop && this.$backdrop.remove()
135 this.$backdrop = null
136 }
137
138 , backdrop: function (callback) {
139 var that = this
140 ,
141 animate = this.$element.hasClass('fade') ? 'fade' : ''
142 if (this.isShown && this.options.backdrop) {
143 var doAnimate = $.support.transition && animate
144 $(".showall").each(function(index) {
145 $(this).remove();
146 })
147 this.$backdrop = $('<div class="modal-backdrop ' + animate + ' showall " />')
148 .appendTo(document.body)
149 this.$backdrop.click(
150 )
151 if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
152
153 this.$backdrop.addClass('in')
154 if (!callback) return
155 doAnimate ?
156 this.$backdrop.one($.support.transition.end, callback) :
157 callback()
158
159 } else if (!this.isShown && this.$backdrop) {
160 this.$backdrop.removeClass('in')
161
162 $.support.transition && this.$element.hasClass('fade')?
163 this.$backdrop.one($.support.transition.end, callback) :
164 callback()
165
166 } else if (callback) {
167 callback()
168 }
169 }
170 }
当然这只是一部分,剩下的靠读者自己研究。至于url转化为this.options.remote对象的相关代码如下
1 $(document).on('click.modal.data-api', '[data-toggle="modal"]', function (e) {
2 var $this = $(this)
3 , href = $this.attr('href')
4 , $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7
5 , option = $target.data('modal') ? 'toggle' : $.extend({ remote:!/#/.test(href) && href }, $target.data(), $this.data())
6
7 e.preventDefault()
8
9 $target
10 .modal(option)
11 .one('hide', function () {
12 $this.focus()
13 })
14 })
15
16 }(window.jQuery);
这段代码在bs的1037行(- -这里是我的行数,我是直接在它的bs上改的,你的应该再往上一点点)顺便说下!function($){}(window.jQuery)这种写法是一种匿名函数的写法具体可以参见http://www.jb51.net/article/21948.htm;然后大家看这代码的第一行就是定义点击带有[data-toggle]=‘modal’]这样的参数的组件响应函数,第二行是将传递的当前对象封装为jquey,第三行是获得当前的超链接内容然后看第五行是设置参数option ,这里判断$target.data('modal')的值最初为undefined所以要用扩展的方式增加,扩展的第一个参数又使用了正则判断得到的href是不是#,不是则传递href的值也就能得到我们的url,剩下的就是拿到这个url后先以?分离utl正文和参数,然后将参数封装为json字符创,网上给出的用封装好的js对象将字符串处理为json貌似不对于是自己写,具体内容相信了解简单字符串处理的读者能看懂,不了解的就需要自己补补了。其实这样处理仅仅是为了兼容ie的效果,想ff这类的浏览器是不用做任何处理就可以使用bs的,天杀的ie你究竟要折磨多少开发者才满意。
|