jQuery Tools - Vertical Scroller One Item Too Long - javascript

I asked this over at the jQuery Tools official forum last week, but it's definitely not as active as stackoverflow, so thought I would ask over here as well.
On our project detail pages, we're dynamically loading content in that uses a vertical scroller to navigate through. Problem is that the height of the vertical scroller always seems to be one item too tall. I cannot find any way to affect this programmatically.
If I set it circular to true, it seems to have the correct height, but we don't want it to be continuous/circular.
Example here:
http://www.centerline.net/projects/detail/?p=21
Unminified JS is here:
http://www.centerline.net/lib/js/site-unmin.js
Any ideas?
Here's the view of what it should look like when scrolled to the last item (down arrow disappears, and does not allow a blank area below the last thumbnail.

The solution above looked like it would have worked, but also found a solution here:
http://www.jasoncarr.com/technology/jquery-tools-scrollable-stop-scrolling-past-the-end
Actual code for my site was as such:
$(function() {
// Initialize the Scrollable control
$(".scroll").scrollable({vertical:true, mousewheel:true, keyboard:true });
// Get the Scrollable control
var scrollable = jQuery(".scroll").data("scrollable");
// Set to the number of visible items
var size = 2;
// Handle the Scrollable control's onSeek event
scrollable.onSeek(function(event, index) {
// Check to see if we're at the end
if (this.getIndex() >= this.getSize() - size) {
// Disable the Next link
jQuery("a.next").addClass("disabled");
}
});
// Handle the Scrollable control's onBeforeSeek event
scrollable.onBeforeSeek(function(event, index) {
// Check to see if we're at the end
if (this.getIndex() >= this.getSize() - size) {
// Check to see if we're trying to move forward
if (index > this.getIndex()) {
// Cancel navigation
return false;
}
}
});
});

Unfortunately the number of divs in the .items container should be divisible by the number of items you want to show at a time. So you have 3 divs but you are showing 2 items at a time. That is why the scrollable plugin malfunctions.
You can either open the nonminified source and change it a little bit which shoudn't be very difficult.
Or much simpler solution would be to either add a new div and make it 4 to 2.
Or Drop the number of items you show at a time to 1 and increase the height of your divs.
Using another plugin may work too.
Hope it helps

The problem is that jQuery tools srolls all images. And after the last images there just is some empty space.
Try to add this to the scrollable constructor
$('.scroll').scrollable({
onBeforeSeek: function(e, index) {
if (index == $('.items').size()) {
return false;
}
},
onSeek: function(e, index) {
if (index == $('.items').size()-1) {
$('.next').hide(0);
} else {
if ($('.next').is(':hidden')) {
$('.next').show();
}
}
}
});
OR
api = $('.scroll').scrollable({
//your setup code
});
api.onBeforeSeek: function(e, index) {
if (index == this.getSize()) {
return false;
}
}
api.onSeek: function(e, index) {
if (index == this.getSize()-1) {
$('.next').hide(0);
} else {
if ($('.next').is(':hidden')) {
$('.next').show();
}
}
}
Disclaimer: Im no expert. I have not tested this. Your code is minified, can't see it clearly. I hardly use jQuery tools. But I think this would be the way to go.

Related

AddThis Layers in Full Screen mode

I'm making a slideshow with full screen functionality (FancyBox 3), it's using the RequestFullScreen method on the container div, which means any other element in the body is not accessible in full screen mode. (correct me if i'm wrong)
I would like to include an AddThis Expanding Share button in the slideshow, but because it's created dynamically by the AddThis js, it appends the Smart Layers before the end of the body, not at the end of the slideshow container div therefore it's not included in the full screen slideshow.
I couldn't find any info on Smart Layers DOM placement in the AddThis API.
What I've tried is seems like a bad idea, to manually appendTo the necessary divs to the slideshow container after the divs are created by AddThis, I managed to "cut and paste" the '.at-expanding-share-button' and it's working so far, but I can't "catch" the '#at-expanded-menu-host' (which is the layer created by AddThis for more sharing options, with the dark background), and I'm not even sure if this method will work properly...
Any help would be appreciated.
I figured it out! :) I thought I share my experience/solution, if anyone has similar difficulties.
What won't work and why:
First I've tried to communicate with the AddThis API to tell it to put its layers to a premade container, which looks like impossible and the AddThis team also told me that there is no solution for manual layer DOM placement, it's always appending those to the end of the body (at least for now, maybe they will implement this option into their API).
Then I've tried to manually append those layers to the Fancy-Box container, which was a dead end because when the slideshow closes, it removes its container from the markup, so the AddThis layers disappeared and I couldn't reinit it (maybe others have some solution for that, but I just couldn't figure it out).
By the way, the "More Sharing Options" layer is created when the share + button is clicked.
My solution:
Instead of appending the layers to the dynamic slideshow container, I've created a static div at the end of the body, appended the layers to it when they are created, and set the Fancy-Box parent div to my container (note that Fancy-Box full screen functionality makes its own div into full screen, so I had to use my own full screen function for the container with the layers and the slideshow).
I've used sindresorhus's screenfull for easier/cross-browser full screen functions.
var FullScreenContainer = $('#container');
// Check if AddThis Layers are ready
var checkLayers = setInterval(function() { appendLayers(); }, 1000);
// Append the layers to FullScreenContainer
function appendLayers() {
var layers = $('.at-expanding-share-button, #_atssh');
if(layers.length > 0){
addthis.layers.refresh();
layers.appendTo(FullScreenContainer);
clearInterval(checkLayers);
console.log('layers added');
}
else {
console.log('not found')
}
}
// Check for more layers when the share icon clicked
$(document).on('click', ".at-expanding-share-button-toggle", function() {
var checkMoreLayers = setInterval(function() { catchLayers(); }, 1000);
function catchLayers() {
var morelayers = $('#at-expanded-menu-host');
if(morelayers.length > 0){
morelayers.appendTo(FullScreenContainer);
clearInterval(checkMoreLayers);
console.log('more layers added');
}
else {
console.log('did not found more')
}
}
});
// Don't forget to disable the full screen function in Fancy-Box,
// then call them when necessary (onInit, clickSlide, clickOutside
// and the close button)
function enterFullscreen() {
screenfull.request($('#container')[0]);
}
function exitFullscreen() {
if (screenfull.isFullscreen) {
screenfull.exit();
$.fancybox.getInstance().close();
}
if (!screenfull.isFullscreen) {
$.fancybox.getInstance().close();
}
}
And you are good to go. I hope this helps for anybody else! :)

jQuery draggable / sortable on dynamically-created elements

After some blood, sweat and luckily no tears I've managed to create a drag and drop system which fits my needs.
There are only 2 things that are almost triggering my tears...
Here's the jsfiddle
The problem is in these lines of code, but can't find it:
if (dropped === original) {
$("#dropzone").append('<li class="placeholder" data-id="" data-order="" data-content=""></li>');
init();
}
$(".remove").click(function() {
var removable = $(this).parent();
if (dropped > original) {
removable.remove();
removable.removeClass("dropped");
removable.removeClass("ui-droppable-disabled");
} else {
removable.empty();
removable.removeClass("dropped");
removable.removeClass("ui-droppable-disabled");
}
init();
});
So now the explanation and my goal:
There are 5 days and on default the placeholders will dynamicly increase with the number of days. If the max limit of placeholders is filled, another one will be appended. Now, after the not-default placeholder is appended and I delete a previous filled placeholder, I can't allow it to be droppable again.
Difficult to explain, but see the demo above ^
Extra: I would like to be able to drag items between those placeholders. But can't find a way either.
Thanks for the help!
You don't seem to reactivate the droppable on delete. And also, destroy them on drop might make you need to recreate them. You could use disable on drop and enable when deleting. Like this:
drop: function (event, ui) {
var dragging = ui.draggable.clone().find("img").remove();
$(this).append(dragging).addClass("dropped");
$(this).droppable('disable');
And later:
if (dropped > original) {
$(this).parent().droppable('enable')
removable.remove();
removable.removeClass("dropped");
removable.removeClass("ui-droppable-disabled");
} else {
$(this).parent().droppable('enable');
removable.empty();
removable.removeClass("dropped");
removable.removeClass("ui-droppable-disabled");
}
http://jsfiddle.net/opmd46t2/3/

jQuery inview only add class to first item in view

I'm working on a blog theme that uses the inview plugin to use J & K scrolling, and also to apply a class to an article that's in view. The only problem is, since I have a mac with a large resolution, there are more than 1 articles in view at a time, so the following script adds the class "inview" to (usually for me, 3 articles) several articles at a time. Is there a way to modify this so it only adds the class "inview" to the FIRST article on the users screen? This may not be the first article on the page, technically, just the first one out of the few in view. Any help is appreciated.
$('article').each(function(){
$(this).bind('inview', function (event, visible) {
if (visible == true) {
$(this).addClass("inview");
}
else {
$(this).removeClass("inview");
}
});
});
If I understood your question correctly, I think you can add an index argument to your .each function. Like this:
$('article').each(function(index){
if( index == 0 )
{
$(this).bind('inview', function (event, visible) {
if (visible == true) {
$(this).addClass("inview");
}
else {
$(this).removeClass("inview");
}
});
}
});
This will add class the class "inview" to the first article.
You can always go to jquery.inview.js line 97 where it says
$element.data('inview', visiblePartsMerged).trigger('inview', [true, visiblePartX, visiblePartY]);
Right before this, add
if ($element.prev(".inview").length < 1)
So that it checks whether there is an element with class 'inview' before the one for which it wants to trigger the event 'inview' with visible = true.

Issue on steriotab system

I have playing around with a steriotab system with the prototype.js library, everything works fine except the next DIV under the container of steriotabs is showing like a flash when turning to next tab.. I know its little bit difficult to understand.. here you can see it on their website http://stereointeractive.com/blog/code/prototype-tabs/
You can see that by changing the four tabs(features, setup, configuration, download) continuously three four times. The comment section will show up like a flash just below the navigation tabs(Features, Setup, Configuration, Download).
I think the issue was when it goes to next tab the current one is display:none and ofcourse there is nothing in the meantime(1 or 2 seconds) so the next block of html code is coming to the top just below the navigation..
this javascript may causing the issue..
activate: function(tab) {
var tabName = tab.id.replace(this.options.ids.tab,'');
this.currentPanel = this.options.ids.panel+tabName;
if (this.showPanel == this.currentPanel) {
return false;
}
if (this.showPanel) {
if (this.options.effects) {
new Effect.Fade(this.showPanel, {queue: 'front'});
} else {
$(this.currentPanel).hide();
}
}
if (this.options.effects) {
new Effect.Appear(this.currentPanel, {queue: 'end'});
} else {
$(this.showPanel).show();
}
this.tabs.invoke('removeClassName', this.options.classNames.tabActive);
tab.addClassName(this.options.classNames.tabActive);
this.showPanel = this.currentPanel;
}
you guys have any thought?
You're suspicion is correct, the reason you get the flash is the few milliseconds there is no container there holding back the content below the object. One option you could consider is while fading the container also sliding it up (look into parallel effects in scripty) that way it would not be nearly as jarring with the content disappears.

determine jQuery hover status for menu

I'm working on writing a drop-down menu with jQuery and I have a question. My menu is composed of two part span.menu_head (which is in the menu bar) and a ul.menu_body (which contains the drop-down items). I have the following jQuery code:
$("span.menu_head").hover(function(){
$(this).next().slideDown('medium');
}, function(){
});
$("ul.menu_body").hover(function(){
}, function(){
$(this).slideUp('medium');
});
So, when I hover over the span.menu_head, the ul.menu_body slides down and when I leave the ul.menu_body, it slide up. This is working as expected. However, there's one more piece I'm trying to add: When the mouse leaves the span.menu_head, I want the ul.menu_body to slideUp, UNLESS the mouse is over the ul.menu_body. Is there a way in jQuery to determine if the mouse is over a certain element? Or, is there a better way to acheive this effect?
Thanks,
Paul
I found a solution using hoverIntent (http://cherne.net/brian/resources/jquery.hoverIntent.html).
I set a flag when the mouse hovers over the ul.menu_body, so that I can check this flag before closing the menu.
var overBody = false;
function mnuOpen() {
$(this).next().slideDown('medium');
}
function mnuClose() {
if (!overBody) {
$(this).next().slideUp('medium');
}
}
var headConfig = {
over: mnuOpen,
timeout: 250,
out: mnuClose
}
$("span.menu_head").hoverIntent(config);
$("ul.menu_body").hover(function(){
overBody = true;
}, function(){
overBody = false;
$(this).slideUp('medium');
});
This is producing the desired behavior. There's one more thing I need to consider: if the mouse goes from the sub menu back to the header, we don't want to close and re-open, so this might involve setting another flag to detect this behavior.
Paul

Categories

Resources