我最终拼凑了一个 jquery 解决方案,该解决方案将引导网格结构的 HTML 转换为根据当前显示大小工作的布局。
为方便起见,我还编写了一个类函数,它提供了一个 dz 对象(displaySize),它不仅确定当前引导显示尺寸中的哪个是活动的(xs、sm、md 或 lg),而且还提供了一种执行自定义函数引用的方法如果重新加载后显示大小发生变化(窗口调整大小事件使用下划线去抖动),则向类注册。
这是我最终使用的代码,如果您知道如何仅使用引导网格结构和类来实现这一点,那么请发布答案,因为我宁愿这样做。
对 HTML 的唯一更改是在父 .row 元素 (.custom-layout .custom-layout-2col) 中添加了两个类名。无论您是从单列布局还是 2 列布局开始,都取决于您。只需更改第二个类名以匹配您开始的布局。从哪一个开始并不重要,因为如果需要,代码会将其更改为另一个,但您应该从与大多数用户的显示尺寸相匹配的布局开始。
下面显示了为两列布局添加的类:
<div class="row custom-layout custom-layout-2col">
<div class="col-xs-12 col-md-6">
<div class="row">
<div class="col-xs-12"> 1 </div>
<div class="col-xs-12"> 3 </div>
<div class="col-xs-12"> 5 </div>
</div>
</div>
<div class="col-xs-12 col-md-6">
<div class="row">
<div class="col-xs-12"> 2 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc quis interdum diam, in tempor est. Pellentesque nulla mi, egestas et rhoncus non, rhoncus bibendum velit. Nulla facilisi. Aenean faucibus nulla rutrum elementum cursus. Nam vel varius libero, eu porttitor tortor. In et ultricies nunc. Duis volutpat posuere urna, id faucibus ante lobortis sit amet. Maecenas urna nisl, tristique eget sem vel, semper tincidunt nisi. </div>
<div class="col-xs-12"> 4 </div>
<div class="col-xs-12"> 6 </div>
</div>
</div>
</div>
的JavaScript:
// This is the dz class. Load this after jquery.
// Note that it instantiates itself, just load it on your page.
// Requires the underscore library (or just the _.restArguments, _.delay,
// and _.debounce functions from the library if you want to copy them out
// separately. )
; (function () {
var Def = function () { return constructor.apply(this, arguments); }
var attr = Def.prototype;
//attributes
attr.currentSize = '?';
attr.previousSize = '?';
attr.changeHandler = [];
//constructor
function constructor() {
var self = this;
$(document).ready(function () {
$('.wrapper-content').append('<div class="device-xs hidden-xs"></div><div class="device-sm hidden-sm"></div><div class="device-md hidden-md"></div><div class="device-lg hidden-lg"></div>');
$(window).resize(_.debounce(function () {
self._determineDeviceSize();
}.bind(self), 200));
self._determineDeviceSize();
}.bind(self));
}
//methods
attr.getCurrentSize = function () {
return this.currentSize;
}
attr.getPreviousSize = function () {
return this.previousSize;
}
attr.addChangehandler = function (f) {
if (typeof f === 'function') { this.changeHandler.push(f); }
}
attr._determineDeviceSize = function () {
var c = this.currentSize;
this.currentSize = $('.device-lg').is(':hidden') ? 'lg' : ($('.device-md').is(':hidden') ? 'md' : ($('.device-sm').is(':hidden') ? 'sm' : 'xs'));
if (c !== this.currentSize) {
this.previousSize = c;
// execute any registered size change handler functions
for (i = 0; i < this.changeHandler.length; ++i) {
this.changeHandler[i](this.currentSize, this.previousSize);
}
}
}
//unleash the class (if it hasn't already been)
if (typeof window.dz === 'undefined') {
window.dz = new Def();
}
})();
// Register our function with dz for the work that needs to be done
// if the bootstrap display size changes
dz.addChangehandler(function (csz, psz) {
$('.custom-layout').each(function () {
var parentRow = $(this);
// Change from 1 col to 2 col ?
if (parentRow.is('.custom-layout-1col') && (csz == 'md' || csz == 'lg')) {
var allDivs = parentRow.children('div');
var mCt = allDivs.length;
if (mCt > 0) {
// create the new row/col structure that we will move all the existing .col-* div's into
var id = 'custom' + (new Date).getTime();
var id2 = id + '2';
parentRow.after('<div class="row custom-layout custom-layout-2col"><div class="col-md-6"><div id="' + id + '" class="row"></div></div><div class="col-md-6"><div id="' + id2 + '" class="row"></div></div></div>');
var newOddParent = $('#' + id);
var newEvenParent = $('#' + id2);
var idx = 0;
while (idx < mCt) {
if (idx === 0 || idx % 2 === 0) {
// odd
newOddParent.append($(allDivs[idx]));
} else {
// even
newEvenParent.append($(allDivs[idx]));
}
idx++;
}
// remove the old parent from the DOM
parentRow.remove();
} else {
console.log('Unable to change custom-layout -- Unable to locate any div (col-*) elements in parent: ', parentRow);
}
}
// Change from 2 col to 1 col ?
if (parentRow.is('.custom-layout-2col') && (csz == 'xs' || csz == 'sm')) {
var childRows = parentRow.children('div').children('.row');
if (childRows.length == 2) {
// create the new .row div that we will move all the .col-* div's into
var id = 'custom' + (new Date).getTime();
parentRow.after('<div id="' + id + '" class="row custom-layout custom-layout-1col"></div>');
var newParent = $('#' + id);
// locate all of the col-* div's that we will be moving
var oddRowDivs = $(childRows[0]).children('div');
var evenRowDivs = $(childRows[1]).children('div');
childRows = '';
var oCt = oddRowDivs.length;
var eCt = evenRowDivs.length;
var mCt = Math.max(oCt, eCt);
var idx = 0;
// move the div's directly into the parentDiv in a staggered order
// starting with the odd (left side) div #1, then even (right side) div #2, etc..
while (idx < mCt) {
if (idx < oCt) {
newParent.append($(oddRowDivs[idx]));
}
if (idx < eCt) {
newParent.append($(evenRowDivs[idx]));
}
idx++;
}
// remove the old parent from the DOM
parentRow.remove();
} else {
console.log('Unable to change custom-layout -- Unable to locate the 2 child .row elements in parent: ', parentRow);
}
}
});
});
如果有人感兴趣,dz 类的用法如下:
- dz.getCurrentSize() - 返回的值将是客户端设备的当前引导显示大小:xs、sm、md 或 lg
- dz.getPreviousSize() - 返回的值将是以前的引导显示大小或“?” 如果页面初始化后大小没有改变
- dz.addChangehandler(functionRef) - 允许您添加自己的显示大小更改处理函数,该函数将在页面加载时以及之后显示大小更改时执行。
示例用法:
// if all you need is the current display size then use the dzCurrentSize variable
// just make sure your accessing it after jquery's $(document).ready
$(document).ready(function () {
console.log('page size: ' + dz.getCurrentSize());
});
// using a change handler function
dz.addChangehandler(function (currentSize, previousSize) {
// example usage scenarios:
// always do stuff (on page initialization and when the size changes anytime afterwards)
alert("The bootstrap display size is: " + currentSize);
// do stuff ONLY if the size changed after page initialization
if (previousSize !== '?') {
console.log('The size has changed after initialization from: ' + previousSize + ' to: ' + currentSize);
}
// do stuff ONLY on page initialization
if (previousSize === '?') {
console.log('The page has just initialized with a size of: ' + currentSize);
}
});