Javascript/ jQuery plugin - javascript

It is not a real jQuery plugin, but for my problem i didn't know what title was appropriate.
This is the "Plugin" --> http://jsfiddle.net/djrikyx/GuumY/9/
There are 3 Youtube player, with the possibility of Pop out them into draggable DIVs and also minimize them to the right.
I can't explain my problem only with words, you have to see it to better understand.
First, popout all 3 players, then minimize them, they will go on the right, each one below the previous.
Then if you try to Close, or Maximize the one in the middle or the last, you will see that all will go up for 30px.
I know that now is doing that, because i wrote to do that in the function maximizePlayer() and popinPlayer() using
var countMP = $('.uiVideoHandleMin').length;
uVC.removeClass('uiVideoContainerMin');
if(countMP > 0){
$('.uiVideoHandleMin').each(function(){
var top = parseInt($(this).css('top'), 10);
top = top-30;
$(this).css({top:top});
});
}
I don't want that. I want so the first one must be always at 50px from top, and the other just below. So if i close the middle one, the first will stay in position, and the last will go up, and if i close the last, nothing happen.
But i really don't know how i can do what i want, so i'm here asking for a tip/solution.

I changed it to this http://jsfiddle.net/Klors/GuumY/11/ which seems to work?
There is a line in your function popinPlayer(elem) { that reduces the css top by 30, but doesn't check to see if it's 0 (or below the removed handle) first.
So I changed top = top-30; to top = top > thisTop ? top-30: top; and added in var thisTop = parseInt($uVH.css("top"), 10); before you reset top on $uVH, which seems to work.

you can do:
function SortByTop(a, b){
var aTop = parseInt($(a).css('top'), 10);
var bTop = parseInt($(b).css('top'), 10);
return ((aTop < bTop) ? -1 : ((aTop > bTop) ? 1 : 0));
}
on maximizePlayer() to sort all $('.uiVideoHandleMin') and then just do:
$.each(minarray,function(i,n){
$(this).css({top:(i*30)});
});
jsfiddle

Related

What's the most accurate way of measuring scroll?

I'm making a slide scrolling page, and I'm trying to have it scroll like you're pulling a notecard up and with the next one right behind it.
To do this, I'm making them all fixed, and then moving their "top" position based off of scroll. But then I also need to make the body the size of the panel.
It's hard to describe what I'm doing, so here's the demo: https://codepen.io/NotDan/pen/vzraJE
Here's the particular piece of code that's causing my problem:
//what's going on here?
$(window).scroll(function(){
var panelNum = parseInt($(window).scrollTop()/$(window).height());//detemines panel number
var pixelMovement = ($(window).scrollTop())-(panelNum*$(".panel").height()); determines how many pixels to move the panel by
$('body').find(".panel:eq("+panelNum+")").css("top", -1*pixelMovement);
});
The problem is when the user scrolls quickly, the top position is not set accurately and there's some overhang. Again, hard to explain, but if you jump to the demo and scroll quickly you'll see what I mean.
Is there a more precise way of measuring scroll? Or is there a better way to do what I'm trying to? I've tried scrollmagic, and its "section wipe" feature is really close, but they bring the previous one up rather than move the current one up.
I tried making a condition to determine the panel number and everything started working.
var panelNum = 0;
var pixelMovement = 0;
$(window).scroll(function () {
pixelMovement = $(window).scrollTop() - panelNum * $(".panel").height(); // determines how many pixels to move the panel by
$("body")
.find(".panel:eq(" + panelNum + ")")
.css("top", -1 * pixelMovement);
if (Math.abs(pixelMovement) >= $(window).height()) {
panelNum++;
} else if (pixelMovement <= 0) {
panelNum--;
}
});
Here's the working demo: https://codepen.io/NotDan/pen/RYJeZq

Sticky Bootstrap column should end with parent/content

I have seen various forms of this problem but nothing really helped me to solve the partial sticky sidebar/Bootstrap column behaviour. Let me start with the problem itself.
There is a big image close to the top of my page. Because of the page complexity, I am using Bootstrap column grid. The image spans over, let's say, 10 columns and I have left 2, belonging to the same row, on the left side to store a sidebar. This also allows me to vertically align the sidebar next to the image.
Now, the sidebar, what is now a Bootstrap column, should go sticky and should stay vertically aligned to the viewport once the scrollbar passes by. You can see in the fiddle that it kind of "jumps" instead of transitioning smoothly.
The other problem is that the sticky element/column should only remain sticky as long as its parent/container is visible. Which means that it should transition/be relative to the end of that container. Right now I have only managed to keep it sticky till the end of the page. It should stop above the red line (depicted in the fiddle).
Here is my jQuery logic so far.
$(document).ready(function(){
$(window).scroll(function(){
var elem = $("#refScroller").offset().top - ($("#refScroller").height() / 2);
var windowvalue = $(window).scrollTop();
if (elem <= windowvalue) {
$("#wannabeSticky").addClass("sticky");
}
else {
$("#wannabeSticky").removeClass("sticky");
}
});
});
I would really appreciate some ideas and hints as this has been bothering me for two days. I would love to keep the Bootstrap grid structure if possible, but feel free to give any suggestions, even those who depict the sidebar as a pure absolute div, as long as the sticky-ness works.
Thanks in advance!
EDIT: I know there is a similar problem already here, but it seems I can't make the JS logic work for my case.
So, having spent another day on it, it seems I reached a decent jQuery version that gets the job done. There is my updated fiddle.
$(document).ready(function(){
var passedMobileNavi = false;
function stickySocialNavi(reference, valueExtracted) {
var refTop = $(reference).offset().top - valueExtracted;
var scrollTop = $(window).scrollTop();
return (refTop <= scrollTop);
}
$(window).scroll(function() {
if (stickySocialNavi($("#refScroller"), $("#refScroller").height())) {
if (!passedMobileNavi) {
passedMobileNavi = true;
$("#wannabeSticky").addClass("sticky");
}
}
else {
passedMobileNavi = false;
$("#wannabeSticky").removeClass("sticky");
}
if (stickySocialNavi($("#end"), $(window).height())) {
var var1 = $(window).scrollTop(),
var2 = $("#end").offset().top,
var3 = $(window).height();
var calculateOffset = (var2 - var3) - var1;
$("#wannabeSticky").css("top", "calc(50% + " + calculateOffset + "px)");
}
else {
$("#wannabeSticky").css("top", "50%");
}
});
});
For the sticky-ness to start, I took the reference point (which is the non-moving element right next to it) and its height. The sticky element gets a fixed position as long as the scrollbar goes past the reference point's center.
As the stick element is centered, it gets additional top offset values when the end of its container is reached. It is still fixed, but its top property's value takes the scroll difference, thus slowly depicting it towards the end of the container.
I don't know if this is the most elegant, straightforward, or easy to implement/understand solution, but it worked for me.

Javascript animation left

First I want to thank anybody who will help me. Now let's get started.
I made a kind of a slide menu (at least that's what it is for me). So for me it is almost complete. I have this jsfiddle
The only thing I'm having problem with is:
Normally I set it to go -100% to the left if the left button is pressed and stop if the div (class*-100). For example, if I have 3 divs with class "google" then it would be 3*-100= -300%.
This all is ok, it takes the right values.
But the only thing is that it only goes until -200% and then stops and does not go to -300%. Normally, since it's if left < -300% it should at least reach -300%. Also manually put it to -500% (the left value) in the if condition and still it did not work. Only if i set it to -1000% but then it goes too far over.
Can you look at the JSFiddle and help me find a solution please?
Normally how the JSFiddle is setup now it should go 3 times to the left but it does not work. To the right it works just fine.
So i found a workaround.
Here is the
JSFiddle
var totalProject = $('.trape-move-left .proiect-numbering').length;
var projectViews = Math.round($('.trape-move-left').width() / $('.trape-move-left .proiect-numbering').width());
var current_proiect = 0;
$('.left-proiecte-arrowz').click(function() {
if (projectViews + (current_proiect + 1) <= totalProject) {
$('.trape-move-left').animate({
'marginLeft': "-=100%" //moves left
});
current_proiect++;
};
});
$('.right-proiecte-arrowz').click(function() {
if (current_proiect > 0) {
$('.trape-move-left').animate({
'marginLeft': "+=100%" //moves left
});
current_proiect--;
};
});

Jquery change div based on another div's position

Let me start of by saying, I'm just now learning JS and Jquery, so my knowledge is very limited.
I've been looking around for 2 days now, and tried all sorts of combinations. But I just can't get this to work.
Below is an example of the layout
I'm looking for a way to trigger an event when div 1 is X px from the top of the screen. Or when div 1 collides with div 2.
What I'm trying to accomplish is to change the css of div 2 (the fixed menu) when div 1 is (in this case) 100px from the top of screen (browser window). Alternatively, when div1 passes div2 (I'm using responsive design, so the fixed height from top might become a problem on smaller screens right? Seeing as the header for example won't be there on a hand held.). So maybe collision detection is better here? Would really appreciate some thoughts and input on this matter.
Another issue is, div2 has to revert back to is previous css once div1 passes it (going back (beyond the 100px)).
This is what I have but it has no effect
$(document).ready(function() {
var content = $('#div1');
var top = $('#div2');
$(window).on('scroll', function() {
if(content.offset().top <= 100) {
top.css({'opacity': 0.8});
}else{
top.css({'opacity': 1});
}
});
});
I am not sure of the reason but $("#content").offset().top was giving a constant value on console. So I added window.scrollTOp() to check its distance from top, here is how it works,
$(document).ready(function() {
var top = $("#menu");
$(window).on('scroll', function(){
if(($('#content').offset().top - $(window).scrollTop()) <= 100){
top.css({'opacity': 0.4});
}else{
top.css({'opacity': 1});
}
});
});
And DEMO JSFIDDLE....

advice on how to fix the prev and next buttons of content slider

I'm trying to add in previous and next buttons to my content slider but seem to be having problems, what I would really like to do is move the $slideCtn left or right by the width slideWidth each time the previous or next button is clicked but i'm unsure how to increment each click by the value of slideWidth. I've tried ++ and -- etc but with no results, would anyone be able to show me the best way to do something like this? Also any other advice very welcome!
Or should I create a global index variable that gets set at 0, then as the pagination x's are clicked or the prev/next arrows are clicked update this global variable?
JS Snippet
//Add previous + next arrows
$dirArrows.on('click', function(e){
var arrDir = $(this).data('dir');
$slideCtn.css('left', ( arrDir === 'prev' ) ? -(slideWidth) : +(slideWidth));
e.preventDefault();
});
JS Fiddle
http://jsfiddle.net/SG5ad/10/
At the moment, you're telling it to move to an absolute position - either -200px or +200px (never 0px, 400px, 600px, etc).
You'll need to take into account its current position as well as how much you want to adjust it: http://jsfiddle.net/SG5ad/12/
var arrDir = $(this).data('dir')
iLeft = parseInt( $slideCtn.css('left') );
$slideCtn.css('left', ( arrDir === 'prev' ) ? iLeft - slideWidth : iLeft + slideWidth);
A bug you'll want to fix as well is that the Next/Prev buttons do nothing until you've already jumped to a specific slide with the "x" navigation.
As an entirely separate issue, about 6 months ago I wrote something like this as part of a project at work (it had a few more bells and whistles, but nothing drastically different), and there's one important thing I'd say is worth changing.
In order to go from slide a to slide d at the moment, you animate slides a,b,c and d, which means that
a) 4 slides are animating instead of 1 (plus all their child elements)
b) you have to pass through slides b and c even though they're not relevant
I'd have a look at changing the base position of all your slides to be stacked on top of each other using z-index, then simply animating the top slide off to one side to reveal the one underneath it. It requires a bit of code to track which slides are where ($.data() may help there) but gives you a much more performant slider at the end of it.
You've gotta do it with .animate()
$dirArrows.on('click', function(e){
var arrDir = $(this).data('dir');
if (arrdir == left){
$slideCtn.animate({
left: "+=250"
});
}
});

Categories