bootstrap模态对话框传值乱码解决方案

最近使用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[i]!=""){
 17                  var paramsd=params[i].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你究竟要折磨多少开发者才满意。