Hello guys, I hope you can clarify something for me please.
I was looking into carousels, found an excellent one and replicated in my code (for reference this is the one I looked at, it’s really good and easy to understand https://tutsplus.com/lesson/the-obligatory-slider/).
Anyway, I have implemented that and I thought I’d do my own controllers, so I grabbed a few images and positioned them absolutely inside the container with the pictures (screenshot attached for reference).
Let’s have a look at some code.
This is the HTML structure. the carouselWrapper
div contains the images and the controllers
<body>
<!-- carousel -->
<div class="carouselWrapper">
<ul>
<li><img src="image1.jpg"></li>
<li><img src="image2.jpg"></li>
<li><img src="image3.jpg"></li>
<li><img src="image4.jpg"></li>
</ul>
<div class="sliderNav">
<button data-dir="prev" class="left transparent"></button>
<button data-dir="next" class="right transparent"></button>
</div>
</div>
<!-- end of carousel -->
</body>
Here is the relevant CSS:
Nothing too involved, the carouselWrapper
has default position:static
.
.carouselWrapper{
width:500px; /*size of the pix*/
/* height:375px; */
overflow:hidden;
margin:0 auto;
}
.carouselWrapper ul{
list-style-type: none;
width:10000px;
}
.sliderNav button.right{
background:url("controllersRight.jpg") no-repeat 0 0;
width:48px;
height:39px;
}
.sliderNav button.left{
background:url(controllersLeft.jpg) no-repeat 0 0;
width:48px;
height:39px;
}
.sliderNav button.left, .sliderNav button.right{
position:absolute;
border:0;
}
And here is the relevant part of the script that positions the two controllers. Again, nothing fancy: I get all the widths and heights I need and then update the top and left value of both the controllers.
/*positioning the controllers*/
var containerWidth = $(".carouselWrapper").width();//get width of
var containerHeight = $(".carouselWrapper").height();
var controllerWidth = $(".sliderNav button").width();
var controllerHeight = $(".sliderNav button").height();
var $controllerPrev = $("button.left");
var $controllerNext = $("button.right");
var imageContainerPosLeft = $(".carouselWrapper").offset().left;
var imageContainerPosTop = $(".carouselWrapper").position().top;
var controllersTop = (containerHeight / 2) - controllerHeight;
var controller1Left = imageContainerPosLeft;
var controller2Left = (imageContainerPosLeft + containerWidth ) - controllerWidth ;
//set the position of the two controller dynamically
$controllerPrev.css({
"top":controllersTop,
"left":controller1Left
});
$controllerNext.css({
"top":controllersTop,
"left":controller2Left
});
console.log("width of picture container is " + containerWidth + " controller width " + controllerWidth + " left pos is "+ imageContainerPosLeft + " top pos is " + imageContainerPosTop + " container height " + containerHeight + " new controller top position: " + controllersTop + " controller1 left pos is " + controller1Left + "second controller left pos is " + controller2Left + " controller height is " + controllerHeight);
I would like to draw your attention to this line:var imageContainerPosLeft = $(".carouselWrapper").offset().left;
Here I am using offset()
and it works fine in every browser, but my first choice was position().left
instead. When I used position()
I noticed that only Firefox, IE7 and 8 and opera worked ok. Safari, Chrome, IE9 and 10 made a mess, the controllers were shifted to the left of the page. I run a few console logs and found out that the culprit was actually that position().left
which was returning a value of 0 and I was expecting something like 710px. So I replaced it with offset().left
and now it is all fine in every browser. Now, I looked at the API for both methods and it says that
The .position() method allows us to retrieve the current position of an element relative to the offset parent.
Funnily enough the parent of carouselWrapper
is the body tag which has no explicit position declared. SO my questions are:
1)Is that the reason why the position method failed?
2)If so why did it fail only in certain browsers and not in others? I mean even IE7 and 8 got it right!
3)As an alternative, rather than fixing the problem using offset().left
, would it be fair to say that I could have fixed it by adding position:relative
to the body tag?