我想我已经成功创建了一个滑块(请说出您对它的评论),并且能够在我的项目中实现它。问题是,当我尝试嵌套滑块时。
嵌套的滑块无法完全显示。显示的唯一部分是选项卡。内容不显示。当我检查控制台时,它表明嵌套的simSliderOuterWrapper's
宽度为0。
我在做什么错,如何使它完全发挥作用?
Working one:JSFiddle
function simSlider(parentElem, config) {
/* ----------------------------------- */
/* -------- Variable Creation -------- */
/* ----------------------------------- */
var currentThis = this,
personalID = parentElem.id,
outerWrapper = document.createElement('div'),
innerWrapper = document.createElement('div'),
labelWrapper = document.createElement('div'),
tabUnderliner = document.createElement('div'),
content = parentElem.children,
radiosArray = [],
contentsHeight = [],
contentWidth = parentElem.offsetWidth,
selectedIndex = prevIndex = 0;
/* ---------------------------------- */
/* ------- Configure Settings ------- */
/* ---------------------------------- */
if (config === undefined) config = {};
currentThis.config = {
// Class Names
outerWrapperClassName: config.outerWrapperClassName,
innerWrapperClassName: config.innerWrapperClassName,
labelWrapperClassName: config.labelWrapperClassName,
labelsClassName: config.labelsClassName,
tabUnderlinerClassName: config.tabUnderlinerClassName,
// CSS Styles
background: config.background || 'blue',
tabUnderlinerColor: config.tabUnderlinerColor || 'orange',
tabTitles: config.tabTitles,
animation: config.animation || '0.7s cubic-bezier(0.45, 0.05, 0.55, 0.95)',
// Callbacks
beforeInit: config.beforeInit || emptyFunction,
endInit: config.endInit || emptyFunction,
beforeSlide: config.beforeSlide || emptyFunction,
slide: config.slide || emptyFunction,
endSlide: config.endSlide || emptyFunction
};
function emptyFunction() {}
/* ------------------------------------------ */
/* ----- Handle Slider Change/Animation ----- */
/* ------------------------------------------ */
function changeFunction(e) {
selectedIndex = radiosArray.indexOf(e.target);
currentThis.config.beforeSlide(selectedIndex, content[selectedIndex]);
var amount = '-' + contentWidth + 'px';
content[selectedIndex].style.width = contentWidth + 'px';
if (selectedIndex < prevIndex) {
innerWrapper.style.transform = 'translateX(' + amount + ')';
amount = '0';
}
setTimeout(function() {
innerWrapper.style.transition = 'transform ' + currentThis.config.animation;
innerWrapper.style.transform = 'translateX(' + amount + ')';
outerWrapper.style.height = contentsHeight[selectedIndex] + 'px';
tabUnderliner.style.transform = 'translateX(' + (selectedIndex * 100) + '%)';
currentThis.config.slide(selectedIndex, content[selectedIndex]);
});
}
function transitionCallback(e) {
// http://stackoverflow.com/q/36274519/4861207
if (e.target !== innerWrapper) return;
innerWrapper.style.transition = 'none';
innerWrapper.style.transform = 'translateX(0)';
content[prevIndex].style.width = 0;
prevIndex = selectedIndex;
currentThis.config.endSlide(selectedIndex, content[selectedIndex]);
}
/* ---------------------------------- */
/* ------ Initialize simSlider ------ */
/* ---------------------------------- */
function initSimSlider() {
// beforeInit Callback
currentThis.config.beforeInit;
// Move contents (slides) to 'innerWrapper'
while (content.length) {
contentsHeight.push(content[0].offsetHeight);
content[0].style.width = 0;
innerWrapper.appendChild(content[0]);
}
content = innerWrapper.children;
// Create and Style Tabs
for (var i = 0; i < content.length; i++) {
var radio = document.createElement('input'),
label = document.createElement('label');
manipulateAttributes(radio, {
type: 'radio',
checked: i === 0,
name: 'simSlider' + personalID,
id: 'simSlider' + personalID + i,
class: 'simSliderTab',
style: {
display: 'none'
}
});
manipulateAttributes(label, {
htmlFor: 'simSlider' + personalID + i,
html: currentThis.config.tabTitles ? currentThis.config.tabTitles[i] : i,
style: {
display: 'inline-block',
width: 'calc(100% / ' + content.length + ')'
}
});
if (currentThis.config.labelsClassName) label.className = currentThis.config.labelsClassName;
radio.addEventListener('change', changeFunction);
radiosArray.push(radio);
labelWrapper.appendChild(label);
parentElem.appendChild(radio);
}
// Add eventListener
if ('transition' in document.documentElement.style) innerWrapper.addEventListener('transitionend', transitionCallback);
// Add CSS Style
content[selectedIndex].style.width = contentWidth + 'px';
tabUnderliner.style.transition = 'transform ' + currentThis.config.animation;
manipulateAttributes(outerWrapper, {
className: 'simSliderOuterWrapper',
style: {
width: contentWidth + 'px',
height: contentsHeight[selectedIndex] + 'px',
transition: 'height ' + currentThis.config.animation,
background: currentThis.config.background,
overflow: 'hidden'
}
});
manipulateAttributes(innerWrapper, {
className: 'simSliderInnerWrapper',
style: {
width: (contentWidth * 2) + 'px',
display: 'flex'
}
});
manipulateAttributes(labelWrapper, {
className: 'simSliderLabelWrapper',
style: {
background: 'brown'
}
});
manipulateAttributes(tabUnderliner, {
className: 'simSliderTabUnderliner',
style: {
background: currentThis.config.tabUnderlinerColor,
height: '3px',
width: 'calc(100% / ' + content.length + ')'
}
});
// Add Class Names
if (currentThis.config.outerWrapperClassName) outerWrapper.className += ' ' + currentThis.config.outerWrapperClassName;
if (currentThis.config.innerWrapperClassName) innerWrapper.className += ' ' + currentThis.config.innerWrapperClassName;
if (currentThis.config.labelWrapperClassName) labelWrapper.className += ' ' + currentThis.config.labelWrapperClassName;
if (currentThis.config.tabUnderlinerClassName) tabUnderliner.className += ' ' + currentThis.config.tabUnderlinerClassName;
// Append Elements
outerWrapper.appendChild(innerWrapper);
parentElem.appendChild(labelWrapper);
parentElem.appendChild(tabUnderliner);
parentElem.appendChild(outerWrapper);
// endInit Callback
currentThis.config.endInit;
}
/* ---------------------------------- */
/* -------- Inital Rendering -------- */
/* ---------------------------------- */
initSimSlider();
function manipulateAttributes(element, attr) {
function recursiveSet(at, set) {
for (var prop in at) {
/* check if object and not a dom node or array */
if (typeof at[prop] == 'object' && at[prop].dataset == null && at[prop][0] == null) {
recursiveSet(at[prop], set [prop]);
} else if (prop == 'html') {
element.innerHTML = at[prop];
} else {
set [prop] = at[prop];
}
}
}
recursiveSet(attr, element);
}
function hasClass(ele, cls) {
return ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
}
function addClass(ele, cls) {
if (!hasClass(ele, cls)) ele.className += " " + cls;
}
}
var mySlider = document.getElementById('mySlider'),
slider = new simSlider(mySlider);
.tabGroup {
width: 500px;
}
.menu {
background-color: brown;
}
.content {} #rad1:checked ~ #outerWrapper > #innerWrapper > #first,
#rad2:checked ~ #outerWrapper > #innerWrapper > #second,
#rad3:checked ~ #outerWrapper > #innerWrapper > #third {} .simSliderTabUnderliner {} .simSliderOuterWrapper {
background-color: blue;
}
#first {
width: 500px;
height: 386px;
}
#second {
width: 300px;
height: 600px;
background-color: lightgreen;
}
#third {
width: 500px;
height: 500px;
}
img {
max-width: 100%;
max-height: 100%;
}
<div class="tabGroup">
<div id="mySlider">
<div class="content" id="first">
<img src="http://www.hdwallpapery.com/static/images/creativity_water_spray_drops_flower_rose_desktop_images_TVIdSpG.jpg" />
</div>
<div class="content" id="second">
<img src="http://www.hdwallpapery.com/static/images/images_1_JbTP6rz.jpg" />
</div>
<div class="content" id="third">
<img src="https://www.planwallpaper.com/static/images/Winter-Tiger-Wild-Cat-Images.jpg" />
</div>
</div>
</div>
Not working one:Nested Slider JSFiddle
function simSlider(parentElem, config) {
/* ----------------------------------- */
/* -------- Variable Creation -------- */
/* ----------------------------------- */
var currentThis = this,
personalID = parentElem.id,
outerWrapper = document.createElement('div'),
innerWrapper = document.createElement('div'),
labelWrapper = document.createElement('div'),
tabUnderliner = document.createElement('div'),
content = parentElem.children,
radiosArray = [],
contentsHeight = [],
contentWidth = parentElem.offsetWidth,
selectedIndex = prevIndex = 0;
/* ---------------------------------- */
/* ------- Configure Settings ------- */
/* ---------------------------------- */
if (config === undefined) config = {};
currentThis.config = {
// Class Names
outerWrapperClassName: config.outerWrapperClassName,
innerWrapperClassName: config.innerWrapperClassName,
labelWrapperClassName: config.labelWrapperClassName,
labelsClassName: config.labelsClassName,
tabUnderlinerClassName: config.tabUnderlinerClassName,
// CSS Styles
background: config.background || 'blue',
tabUnderlinerColor: config.tabUnderlinerColor || 'orange',
tabTitles: config.tabTitles,
animation: config.animation || '0.7s cubic-bezier(0.45, 0.05, 0.55, 0.95)',
// Callbacks
beforeInit: config.beforeInit || emptyFunction,
endInit: config.endInit || emptyFunction,
beforeSlide: config.beforeSlide || emptyFunction,
slide: config.slide || emptyFunction,
endSlide: config.endSlide || emptyFunction
};
function emptyFunction() {}
/* ------------------------------------------ */
/* ----- Handle Slider Change/Animation ----- */
/* ------------------------------------------ */
function changeFunction(e) {
selectedIndex = radiosArray.indexOf(e.target);
currentThis.config.beforeSlide(selectedIndex, content[selectedIndex]);
var amount = '-' + contentWidth + 'px';
content[selectedIndex].style.width = contentWidth + 'px';
if (selectedIndex < prevIndex) {
innerWrapper.style.transform = 'translateX(' + amount + ')';
amount = '0';
}
setTimeout(function() {
innerWrapper.style.transition = 'transform ' + currentThis.config.animation;
innerWrapper.style.transform = 'translateX(' + amount + ')';
outerWrapper.style.height = contentsHeight[selectedIndex] + 'px';
tabUnderliner.style.transform = 'translateX(' + (selectedIndex * 100) + '%)';
currentThis.config.slide(selectedIndex, content[selectedIndex]);
});
}
function transitionCallback(e) {
// http://stackoverflow.com/q/36274519/4861207
if (e.target !== innerWrapper) return;
innerWrapper.style.transition = 'none';
innerWrapper.style.transform = 'translateX(0)';
content[prevIndex].style.width = 0;
prevIndex = selectedIndex;
currentThis.config.endSlide(selectedIndex, content[selectedIndex]);
}
/* ---------------------------------- */
/* ------ Initialize simSlider ------ */
/* ---------------------------------- */
function initSimSlider() {
// beforeInit Callback
currentThis.config.beforeInit;
// Move contents (slides) to 'innerWrapper'
while (content.length) {
contentsHeight.push(content[0].offsetHeight);
content[0].style.width = 0;
innerWrapper.appendChild(content[0]);
}
content = innerWrapper.children;
// Create and Style Tabs
for (var i = 0; i < content.length; i++) {
var radio = document.createElement('input'),
label = document.createElement('label');
manipulateAttributes(radio, {
type: 'radio',
checked: i === 0,
name: 'simSlider' + personalID,
id: 'simSlider' + personalID + i,
class: 'simSliderTab',
style: {
display: 'none'
}
});
manipulateAttributes(label, {
htmlFor: 'simSlider' + personalID + i,
html: currentThis.config.tabTitles ? currentThis.config.tabTitles[i] : i,
style: {
display: 'inline-block',
width: 'calc(100% / ' + content.length + ')'
}
});
if (currentThis.config.labelsClassName) label.className = currentThis.config.labelsClassName;
radio.addEventListener('change', changeFunction);
radiosArray.push(radio);
labelWrapper.appendChild(label);
parentElem.appendChild(radio);
}
// Add eventListener
if ('transition' in document.documentElement.style) innerWrapper.addEventListener('transitionend', transitionCallback);
// Add CSS Style
content[selectedIndex].style.width = contentWidth + 'px';
tabUnderliner.style.transition = 'transform ' + currentThis.config.animation;
manipulateAttributes(outerWrapper, {
className: 'simSliderOuterWrapper',
style: {
width: contentWidth + 'px',
height: contentsHeight[selectedIndex] + 'px',
transition: 'height ' + currentThis.config.animation,
background: currentThis.config.background,
overflow: 'hidden'
}
});
manipulateAttributes(innerWrapper, {
className: 'simSliderInnerWrapper',
style: {
width: (contentWidth * 2) + 'px',
display: 'flex'
}
});
manipulateAttributes(labelWrapper, {
className: 'simSliderLabelWrapper',
style: {
background: 'brown'
}
});
manipulateAttributes(tabUnderliner, {
className: 'simSliderTabUnderliner',
style: {
background: currentThis.config.tabUnderlinerColor,
height: '3px',
width: 'calc(100% / ' + content.length + ')'
}
});
// Add Class Names
if (currentThis.config.outerWrapperClassName) outerWrapper.className += ' ' + currentThis.config.outerWrapperClassName;
if (currentThis.config.innerWrapperClassName) innerWrapper.className += ' ' + currentThis.config.innerWrapperClassName;
if (currentThis.config.labelWrapperClassName) labelWrapper.className += ' ' + currentThis.config.labelWrapperClassName;
if (currentThis.config.tabUnderlinerClassName) tabUnderliner.className += ' ' + currentThis.config.tabUnderlinerClassName;
// Append Elements
outerWrapper.appendChild(innerWrapper);
parentElem.appendChild(labelWrapper);
parentElem.appendChild(tabUnderliner);
parentElem.appendChild(outerWrapper);
// endInit Callback
currentThis.config.endInit;
}
/* ---------------------------------- */
/* -------- Inital Rendering -------- */
/* ---------------------------------- */
initSimSlider();
function manipulateAttributes(element, attr) {
function recursiveSet(at, set) {
for (var prop in at) {
/* check if object and not a dom node or array */
if (typeof at[prop] == 'object' && at[prop].dataset == null && at[prop][0] == null) {
recursiveSet(at[prop], set [prop]);
} else if (prop == 'html') {
element.innerHTML = at[prop];
} else {
set [prop] = at[prop];
}
}
}
recursiveSet(attr, element);
}
function hasClass(ele, cls) {
return ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
}
function addClass(ele, cls) {
if (!hasClass(ele, cls)) ele.className += " " + cls;
}
}
var mySlider = document.getElementById('mySlider'),
slider = new simSlider(mySlider);
var mySlider2 = document.getElementById('second'),
slider2 = new simSlider(mySlider2);
#mySlider {
width: 500px;
}
.menu {
background-color: brown;
}
.simSliderOuterWrapper {
background-color: blue;
}
#first {
width: 500px;
height: 386px;
}
#second {
width: 500px;
height: 600px;
background-color: lightgreen;
}
#third {
width: 500px;
height: 500px;
}
#first2 {
width: 500px;
height: 500px;
}
#second2 {
width: 500px;
height: 600px;
background-color: lightgreen;
}
#third2 {
width: 500px;
height: 700px;
}
img {
max-width: 100%;
max-height: 100%;
}
<div id="mySlider">
<div class="content" id="first">
<img src="http://www.hdwallpapery.com/static/images/creativity_water_spray_drops_flower_rose_desktop_images_TVIdSpG.jpg" />
</div>
<div class="content" id="second">
<div id="first2">
<img src="https://rfranksblog.files.wordpress.com/2013/02/keep-calm-and-find-the-syntax-error-copy.jpg" />
</div>
<div id="second2">
<img src="http://aquinashub.co.uk/wp-content/uploads/2015/04/shutterstock_computer_programming.jpg" />
</div>
<div id="third2">
<img src="http://datavizion.biz/wp-content/uploads/2011/04/23689689.jpg" />
</div>
</div>
<div class="content" id="third">
<img src="https://www.planwallpaper.com/static/images/Winter-Tiger-Wild-Cat-Images.jpg" />
</div>
</div>
最佳答案
第二个滑块的宽度为0的原因是,第一个滑块使所有子级(恰好是嵌套的滑块)的宽度为0。
然后,内部滑块的子宽度(如上所述)为0。因此,第二个滑块中的所有内容的宽度均为0。
一种解决方法(这不是总的解决方法,因为它会产生另一个问题,但确实回答了字面上的问题),是先初始化第二个滑块,然后初始化外部滑块。像这样:
var mySlider2 = document.getElementById('second'),
slider2 = new simSlider(mySlider2);
var mySlider = document.getElementById('mySlider'),
slider = new simSlider(mySlider);
关于javascript - 元素的宽度变为0,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36298350/