/**
* 20140505 14.33 ycx
*
scrollspy.js中存在的bug!!!---为什么ui.tabs必须在scrollspy.js中的window.onload之前执行,也就是必须在scrollspy初始化之前执行
*
1
scrollspy中的process函数中的scrollTop数值在tabs组件之后的都存在计算错误,是因为scrollspy初始化后,已经计算好整个页面的scrollTop等数组(offsets),而这时候ui.tabs进行初始化,
*
就会把tab页的其他暂时不显示出来的内容都隐藏起来,就会导致整个页面的scrollTop等方面的数值改变了,所以在tab之后的组件都会在scrollspy中存在偏差!!
*
针对这种情况,临时的解决方法是:
* 方法一:
将ui.tabs()在scrollspy初始化之前执行--如将ui.tabs()放到document.ready回调函数中执行(因为scrollspy是在window.onload回调函数执行的)
* 方法二: 将scrollspy初始化的函数拿出来,在ui.tabs()执行之后再开始初始化。
*
* 2 也就是说,如果其他组件或者js脚本会改变页面的scrollTop等方面的内容,那么估计都要采用上述两种方法来解决。
*/
1 ui.js---是我自己写的组件库
2 scrollspy.js可在bootstrap官网下载单独的源文件
scrollspy.js代码,具体如下所示:
1 /* ======================================================================== 2 * Bootstrap: scrollspy.js v3.0.3 3 * http://getbootstrap.com/javascript/#scrollspy 4 * ======================================================================== 5 * Copyright 2013 Twitter, Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * ======================================================================== */ 19 + function($) {"use strict"; 20 21 // SCROLLSPY CLASS DEFINITION 22 // ========================== 23 24 function ScrollSpy(element, options) { 25 var href 26 var process = $.proxy(this.process, this) 27 28 this.$element = $(element).is(‘body‘) ? $(window) : $(element) 29 this.$body = $(‘body‘) 30 this.$scrollElement = this.$element.on(‘scroll.bs.scroll-spy.data-api‘, process) 31 //console.log(this.$scrollElement); 32 this.options = $.extend({}, ScrollSpy.DEFAULTS, options) 33 this.selector = (this.options.target || (( href = $(element).attr(‘href‘)) && href.replace(/.*(?=#[^\s]+$)/, ‘‘))//strip for ie7 34 || ‘‘) + ‘ .nav li > a‘ 35 //console.log(this.selector); 36 this.offsets = $([]) 37 this.targets = $([]) 38 this.activeTarget = null 39 40 this.refresh() 41 this.process() 42 } 43 44 45 ScrollSpy.DEFAULTS = { 46 offset : 10 47 } 48 49 ScrollSpy.prototype.refresh = function() { 50 var offsetMethod = this.$element[0] == window ? ‘offset‘ : ‘position‘ 51 //console.log(offsetMethod,11); 52 53 this.offsets = $([]) 54 this.targets = $([]) 55 56 var self = this 57 var $targets = this.$body.find(this.selector).map(function() { 58 var $el = $(this) 59 var href = $el.data(‘target‘) || $el.attr(‘href‘) 60 var $href = /^#\w/.test(href) && $(href) 61 //console.log($el,"--",href,"--",$href); 62 console.log($href[offsetMethod]().top, "-------", $href[0].offsetTop, $href[0].id); 63 //console.log($href,$href["offset"]().top,"-----------"); 64 65 return ($href && $href.length && [[$href[offsetMethod]().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href]]) || null 66 }).sort(function(a, b) { 67 return a[0] - b[0] 68 }).each(function() { 69 //console.log(this); 70 self.offsets.push(this[0]) 71 self.targets.push(this[1]) 72 }) 73 } 74 75 ScrollSpy.prototype.process = function() { 76 //这里存在问题--scrollTop 77 var scrollTop = this.$scrollElement.scrollTop() + this.options.offset 78 console.log("scrollTop--->>>" + scrollTop); 79 var scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight 80 var maxScroll = scrollHeight - this.$scrollElement.height() 81 var offsets = this.offsets 82 //console.log(offsets); 83 var targets = this.targets 84 var activeTarget = this.activeTarget 85 var i 86 87 if (scrollTop >= maxScroll) { 88 return activeTarget != ( i = targets.last()[0]) && this.activate(i) 89 } 90 91 //console.log(scrollTop,offsets,) 92 93 for ( i = offsets.length; i--; ) { 94 //activeTarget != targets[i] && scrollTop >= offsets[i] && (!offsets[i + 1] || scrollTop <= offsets[i + 1]) && this.activate(targets[i]) 95 96 //activeTarget != targets[i] && scrollTop >= offsets[i] && (!offsets[i + 1] || scrollTop <= offsets[i + 1]) && this.activate(targets[i+1]) 97 activeTarget != targets[i] && scrollTop >= offsets[i] && (!offsets[i + 1] || scrollTop <= offsets[i + 1]) && this.activate(targets[i]) 98 } 99 } 100 101 ScrollSpy.prototype.activate = function(target) { 102 console.log("target===>>>", target); 103 this.activeTarget = target; 104 105 $(this.selector).parents(‘.active‘).removeClass(‘active‘) 106 107 var selector = this.selector + ‘[data-target="‘ + target + ‘"],‘ + this.selector + ‘[href="‘ + target + ‘"]‘ 108 109 var active = $(selector).parents(‘li‘).addClass(‘active‘) 110 111 if (active.parent(‘.dropdown-menu‘).length) { 112 active = active.closest(‘li.dropdown‘).addClass(‘active‘) 113 } 114 115 active.trigger(‘activate.bs.scrollspy‘) 116 } 117 // SCROLLSPY PLUGIN DEFINITION 118 // =========================== 119 120 var old = $.fn.scrollspy; 121 122 $.fn.scrollspy = function(option) { 123 return this.each(function() { 124 var $this = $(this) 125 var data = $this.data(‘bs.scrollspy‘) 126 var options = typeof option == ‘object‘ && option 127 128 if (!data) 129 $this.data(‘bs.scrollspy‘, ( data = new ScrollSpy(this, options))) 130 if ( typeof option == ‘string‘) 131 data[option]() 132 }) 133 } 134 135 $.fn.scrollspy.Constructor = ScrollSpy; 136 137 // SCROLLSPY NO CONFLICT 138 // ===================== 139 140 $.fn.scrollspy.noConflict = function() { 141 $.fn.scrollspy = old; 142 return this; 143 } 144 // SCROLLSPY DATA-API 145 // ================== 146 147 $(window).on(‘load‘, function() { 148 $(‘[data-spy="scroll"]‘).each(function() { 149 var $spy = $(this); 150 $spy.scrollspy($spy.data()); 151 }) 152 }) 153 }(jQuery);