-
Notifications
You must be signed in to change notification settings - Fork 736
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Abilities of the 0.3 branch #352
Comments
This
is the same as
So, all fine :) There are no built in item loading related callbacks in 0.3. This has to be done in userland code. A simple loading would be:
|
OK, it works fine ! There is still a problem though : I'd like to load ONLY the images that are visible in the carousel. With the 0.2.8 version, the following code worked : function carousel_comments_itemLoadCallback(carousel, state) {
for (x=carousel.first-1;x<carousel.last;x++) {
// the code to load the image
}
} How could I change "itemLoadCallback()", "carousel.first" and "carousel.last" ? Furthermore, I was using "itemVisibleInCallback" and "carousel.size()" to add an "inactive" class to the external control links : function carousel_editos_itemVisibleInCallback(carousel, item, idx, state) {
if (carousel.first == 1) { $("#editos .jcarousel-prev").css("visibility", "hidden"); } else { $("#editos .jcarousel-prev").css("visibility", "visible"); }
if (carousel.last == carousel.size()) { $("#editos .jcarousel-next").css("visibility", "hidden"); } else { $("#editos .jcarousel-next").css("visibility", "visible"); }
} Which callback could I use instead of it ? How can I replace carousel.size() too ? NB : it can be seen on this page. Thanx for your help, |
There is no itemLoadCallback. You have to do everything by yourself. I will add an example, but for now you're on your own ;) There are some helper methods you can use for that:
|
I'm afraid I won't be able to do this on my own :( I understand there is no built-in callback. But I don't know how to replace them by myself. So I think I'll wait for your example ;) |
I don't see this helper method of list() in 0.3 branch. Am I missing something? var jc = $("#my-carousel").jcarousel(); jc.list();
|
You have to call the method in the carousel object, not the jQuery object.
or
|
I think I could emulate the itemVisibleInCallback and itemLoadCallback, creating my own itemLoadCallback function with this code : $(function() {
$("#my-carousel").jcarousel().load(function() { itemLoadCallback(carousel); });
$("#prev-link").click(function() { itemLoadCallback(carousel); });
$("#next-link").click(function() { itemLoadCallback(carousel); });
});
function itemLoadCallback(carousel) {
// my code goes here;
} The aim is to have a function that would be triggered when the carousel loads for the first time, and, then, each time a new set of items is requested. Is it the right way to achieve this ? |
Nope, read the |
OK, I'm far to be a pro... I guess I'll just wait for your example. |
A few more questions please.
And so the external control link doesn't work.
But since 0.3, it doesn't seem to work anymore (it's the 2nd carousel on the top right of this page, called "Nos prochaines animations"). It only displays one item at a time, instead of 3. Is it because of a change in the jCarousel code ? Or is it just a CSS problem ? Thanx, |
|
Thanx for your plugin ! There is a mistake in your example code here : you have put a "," instead of a ";" in the following line : The images are displayed thanx to your plugin, but it doesn't seem to work as expected : here is my code now : img = new Array(Array);
$(function() {
$("#carousel-comments-container").append('<div class="jcarousel" id="carousel-comments"><ul>\n</ul></div>');
var loadCallback = function(first, last, type, ready) {
$.get('../dotclear-files/themes/biblio/js/dynamic_ajax_php.php', function(data) {
var w = 0;
$(data).find('image').each(function() {
if (!img[w]) img[w] = new Array();
img[w]['url'] = $(this).find('url').text();
img[w]['src'] = $(this).find('src').text();
img[w]['title'] = $(this).find('title').text();
img[w]['width'] = $(this).find('width').text();
img[w]['height'] = $(this).find('height').text();
w++;
});
var items = $('#carousel-comments').jcarousel('items');
for (var i = first; i <= last; i++) {
items.eq(i).find('img').attr('src', img[i]['src']);
};
ready();
}, 'xml');
};
var placeholderCallback = function(index) {
return '<li><img src="../dotclear-files/themes/biblio/img/loading.gif"></li>';
};
$('#carousel-comments')
.jcarousel()
.jcarouselLoader({
load: loadCallback,
placeholder: placeholderCallback
});
$("#pager-button-prev a").click(function() { $("#carousel-comments").jcarousel("scroll", "-=3"); return false; });
$("#pager-button-next a").click(function() { $("#carousel-comments").jcarousel("scroll", "+=3"); return false; });
});
Thanx for your great help ! |
Try this (not tested by me):
|
Thanx again for your help.
|
|
OK, I think I've got it, but I'm not sure : it behaves strangely, but maybe it's just because of the bug you talked about ? My images still don't seem to be loaded only when scrolling though... It still seems that they're all loaded at once when the carousel loads for the first time... I've tried to "apply the logic" as you said : var img = new Array(Array);
$(function() {
var loadCallback = function(first, last, type, ready) {
var plugin = this,
carousel = this.carousel();
if (type !== 'init') { carousel_comments_itemLoad(carousel, first, last); return; }
$.get('../dotclear-files/themes/biblio/js/dynamic_ajax_php.php', function(data) {
plugin.option('size', parseInt($(data).find('total').text(), 10));
$(data).find('image').each(function(index) {
if (!img[index]) img[index] = new Array();
img[index]['url'] = $(this).find('url').text();
img[index]['src'] = $(this).find('src').text();
img[index]['title'] = $(this).find('title').text();
img[index]['width'] = $(this).find('width').text();
img[index]['height'] = $(this).find('height').text();
});
ready();
carousel_comments_itemLoad(carousel, first, last);
}, 'xml');
};
var placeholderCallback = function(index) { return '<li></li>'; };
var carouselComments = $('<div class="jcarousel" id="carousel-comments"><ul>\n</ul></div>')
.appendTo('#carousel-comments-container')
.jcarousel()
.jcarouselLoader({ load: loadCallback, placeholder: placeholderCallback });
$("#pager-button-prev a").click(function() { $("#carousel-comments").jcarousel("scroll", "-=3"); return false; });
$("#pager-button-next a").click(function() { $("#carousel-comments").jcarousel("scroll", "+=3"); return false; });
});
function carousel_comments_itemLoad(carousel, first, last) {
var list = carousel.list(),
items = carousel.items();
for (x=first; x<=last; x++) {
var item = $('<li><a class="black-links" href="' + img[x]['url'] + '#comments" title="' + img[x]['title'] + '"><img src="../dotclear-files/themes/biblio/img/loading.gif" alt="' + img[x]['title'] + '" id="carousel-img-' + x + '" width="' + img[x]['width'] + 'px" height="' + img[x]['height'] + 'px" /></a></li>');
var existing = items.eq(x);
if (existing.size() > 0) { existing.replaceWith(item); } else { list.append(item); }
$('#carousel-img-' + x)
.hide()
.one('load', function() { $(this).fadeIn(); })
.attr('src', img[x]['src'])
.each(function() { if (this.complete) $(this).trigger('load'); });
}
} |
While writing the loader plugin, i realized that it not really adds some value, so i'm going to remove it ;) Here's a reworked version of the code using a core event and including the fade in stuf of the images. Note: The images are loaded all at once on initialization. Is there any reason why you don't want to do that?
|
It's because if you have 100 images, loaded all at once on initialization, it'll be veeeeery long to load ;) So what would be nice is to load the xml code from the PHP file once and for all on initialization, and then only load the images themselves when they need to be displayed... |
Furthermore, if the user doesn't scroll, you'll have loaded 97 images for nothing... I'm a bit baffled here : is it just not possible with the 0.3 branch ? You had done it yourself quite easily in your own example for 0.2.8, using itemLoadCallback (and it worked quite well) : so we would just need an equivalent to this in the 0.3 branch. |
The item loading stuff in 0.2 is flawed. It worked well only in few cases. If you want to load the images only if the become visible, just do this
We simply bind on the |
Thank you soooo much for your great help ! (back from holidays maybe ? ;) I'm not sure the method is yet perfect though (you'll clearly see the problem if you browse without CSS) : with this code (which works just fine, as we can see on the page where I use it), all the images are added at once, but only 3 are indeed visible. So if you browse with a screen reader for example (for people with disabilities etc.), you have useless elements displayed (that is to say : you have a list of loading gifs !)... Furthermore, the width and height attributes of the images should be added only after the images are loaded (because the loading gif is displayed much bigger than it should). By the way, one of my carousel (still on my page, it's the one called "Nos prochaines animations") simply doesn't work with 0.3 : you had advised me (12th comment of this post) to add Any idea anyone ? Thanx ! |
Updated code which only adds required items (without loader plugin), untested as usual ;):
Regarding the not-working carousel, try:
|
Wow ! Thanx a lot ! But unfortunately it doesn't seem to work : I've changed a few typos ("," instead of ";" in the "for" loop, for example, or "src" instead of "data.src" on line 13), and I've put it online : but, as you can see, it does nothing. The images are not displayed (in fact, the items are not added to the DOM, as we can see in the generated source code). Here is the final code I used : $(function() {
$("#carousel-comments-container").prepend('\n<span id="pager-button-prev"><a class="black-links" href="#" title="Documents précédents"><</a></span>\n<span id="pager-button-next"><a class="black-links" href="#" title="Documents suivants">></a></span>');
var carouselCommentsNumItems = 3, // 3 items visible
carouselCommentsData = [];
var createItem = function(data) {
var item = $('<li><a class="black-links" href="' + data.url + '#comments" title="' + data.title + '"><img data-src="' + data.src + '" src="../dotclear-files/themes/biblio/img/loading.gif"></a></li>');
var img = item.find('img');
img
.hide()
.one('load', function() { $(this).attr('width', data.width).attr('height', data.height).fadeIn(); })
.attr('src', data.src)
.each(function() { if (this.complete) $(this).trigger('load'); });
};
var initCallback = function(event, carousel) {
var list = carousel.list();
$.get('../dotclear-files/themes/biblio/js/dynamic_ajax_php.php', function(data) {
// Store data
$(data).find('image').each(function(index) {
var item = {
'url': $(this).find('url').text(),
'title': $(this).find('title').text(),
'src': $(this).find('src').text(),
'width': $(this).find('width').text(),
'height': $(this).find('height').text()
};
carouselCommentsData.push(item);
});
// Create first set of items
var list = carousel.list(),
size = carouselCommentsData.length;
for (var i = 0; i < carouselCommentsNumItems; i++) {
if (i >= size) {
break;
}
list.append(createItem(carouselCommentsData[i]));
}
carousel.reload();
}, 'xml');
};
var scrollCallback = function(event, carousel, target) {
var list = carousel.list(),
items = carousel.items(),
size = carouselCommentsData.length,
parsed = jCarousel.parseTarget(target),
index = parsed.target;
// Only relative (prev/next buttons)
if (!parsed.relative) {
return;
}
// Out of range
if (index >= size) {
return;
}
// Already added
if (items.eq(index).size() > 0) {
return;
}
for (var i = index; i < carouselCommentsNumItems; i++) {
if (i >= size) {
break;
}
list.append(createItem(carouselCommentsData[i]));
}
carousel.reload();
};
var carouselComments = $('<div class="jcarousel" id="carousel-comments"><ul></ul></div>')
.appendTo('#carousel-comments-container')
.bind('jcarouselinit', initCallback)
.bind('jcarouselscroll', scrollCallback)
.jcarousel();
$("#pager-button-prev a").bind('jcarouselcontrolinactive', function() { $("#pager-button-prev").css("visibility", "hidden"); }).bind('jcarouselcontrolactive', function() { $("#pager-button-prev").css("visibility", "visible"); }).jcarouselControl({ target: '-=3' });
$("#pager-button-next a").bind('jcarouselcontrolinactive', function() { $("#pager-button-next").css("visibility", "hidden"); }).bind('jcarouselcontrolactive', function() { $("#pager-button-next").css("visibility", "visible"); }).jcarouselControl({ target: '+=3' });
}); (However, regarding the previously not-working carousel, now it works ! Thanx a lot !) |
The
|
OK, the items are added now... but there is no more prev/next scroll button added ;) Should I change a particular variable ? |
Now, that we load the items dynamically, the prev/next buttons don't know that there are more items available than actually items in the carousel. I've just pushed to the master branch. Take jquery.jcarousel.js from there and change the following section:
The new part is the binding to the |
Thanx very much ! Unfortunately, it doesn't seem to work : as you can see, there is still no prev/next scroll button displayed... Maybe I've done something wrong ? |
You must use the latest version of jquery.jcarousel.js: https://github.com/jsor/jcarousel/blob/master/src/jquery.jcarousel.js |
Yes, that's what I've done. Just to be sure, I just come to do it again : same result. (I click on the link you gave, and then I copy/paste the code to my jquery.jcarousel.js file, since I don't find how to download it)... |
I checked the file /dotclear-files/themes/biblioTest/js/min/jquery.jcarousel.js and it doesn't have the latest changes in it (b1e0f6f). |
Grrr... Sorry for this : I had changed the wrong file. Now it's better (the "next" scroll button is displayed) but not yet perfect : the next scroll button has no effect (that is to say : when you click on it, nothing happens... it just doesn't scroll)... Thanx very much for all the help you give to me ! |
We have a javascript error:
|
Done... but, unfortunately, same behaviour : the scroll button still doesn't seem to work... |
Small bug. Replace:
with
|
Thanx ! Now it works just fine ! The "next" scroll buttons never "disappear" though (I'm using the "control" plugin, and it never becomes inactive). This is strange, since the "prev" button works just fine... Anyway, thank you very much for all the time you gave to this project, since I'd never have been able to do this on my own ! Here are a few more things I noticed :
|
Fix for the next button: Replace
with
Question 1- 4: Yep, i just wrote that code out of my head. There is probably room for improvement ;-) |
Mmmm... Not sure the "-1" should be added there, since when you scroll for the first time, 4 items are added at once (instead of three : cf. As for the addition of |
The scrollCallback is buggy, replace with
Don't know why |
It works... only the first time you scroll : scroll ("next" button) twice (until the end of the carousel, in fact), then scroll back ("prev" button once or twice, it doesn't matter), and then scroll again ("next" button again) : the four last items are added several times (each time you scroll back and forth, they're added again)... |
Ah, yes. forgt to add the check if the item already exists:
|
Aaaahhh ! Now it really works like a charm :) I'm very grateful to you of all the time you gave to me. Thanx very much for this. One other thing : when I disable javaScript and reload the page, only the current item is displayed in the carousels of my page. Of course, I'm no more talking about a carousel with dynamic content loading : I'm talking about a "normal" carousel, with for example 3 items in it, scrolled 1 by 1. If I disable jS, only 1 item (the current one) will be visible. So, from an accessibility point of view, there's a loss of informations : all the items of the carousels should be displayed (with a vertical or horizontal scrolling bar, for example). Is it a CSS problem ? Please note that I don't want you to do the job for me (in fact... you have ever done all the job for me ;)). I'd just like to know if, with the current 0.3 branch, we can have this sort of behaviour (I'm a bit better in CSS than in jS, so if this is just a CSS problem, I assume I can solve this by myself). PS : the following code has no effect for the moment : |
Yep, its up to you how style it. Since jCarousel adds the class
Regarding the counter. My mistake, multiple events must be separated by a space:
I made a few corrections:
|
Wow ! Thanx very much : it works fine ! So the only trouble left I can see is the annoying keyboard browsing issue. I've seen your "focus" example, but adding the following code to my carousel has no effect : .focus(function(e) {
e.preventDefault();
e.stopPropagation();
$(this).closest('.jcarousel').jcarousel('scroll', this);
}); Here is what it does when tabbing throughout the page using the keyboard :
The focus should go to the first link inside of the first displayed item, and, after the last link in the last displayed item, the focus should go out of the carousel. Is it something which could be done via a plugin ? Or is it something that can already be done using the actual 0.3 code ? Something to settle up inside of the configuration javaScript file maybe ? Thanx for your help... once more, |
If you want to use it like i did in the example, you have to set the tabindex attribute explicitly on each element. |
I can't do that, since I'd have to set the tabindex attribute to each link of my page, right ? But some parts of the page are shared with other pages of the blog, so this is just not possible for me. Is there a way to use the "focus" callback in order to achieve this ? (I mean : the focus goes to the first link of the first displayed item, and then goes out after the last link of the last displayed item ?) Also, I was wondering if jCarousel could be used to create a "more" link, so that more content is added (instead of "scrolled") at the end of a page : it's exactly the same as the carousel with dynamic content loading that you made for me, but without the "scrolling" function (the new content loaded is added at the end of the container, instead of replacing the old one). If possible, I'd like to stay with jCarousel, instead of adding another plugin again... but is this possible ? Thanx, |
Regarding the focus stuff, i don't know actually. Maybe better ask on SO or something. Second question: Use the right tool for the job, jCarousel is not made for something like this. |
OK, I'll see what I can't do for the keyboard browsing issue. I had solved it with the old 0.2.8 version (it can be seen here), but it's been a reaaally hard work for me... and I've been unable to upgrade it so that it can be used with the 0.3 branch :( Now I think it's time to close this looong post ;) Thanx again for all the great help you gave to me ! |
Just in case, I've asked the question about the keyboard browsing problem on SO. |
Unfortunately, I had no answer on SO. And no more luck on the jQuery forums... ... It's a great shame, since this is an important accessibility issue... |
I'm still not sure what exactly the problem is. The topic has nothing to do with jCarousel, not event with JavaScript. If you solved it with your 0.2.8 version, you should be able to solve it for 0.3 as well. |
After all it was not that difficult to fix this issue :) Here's what I've done : // The focus must go to the first link of the first VISIBLE item :
$("#carousel-comments").delegate("li:first a", "focusin", function () {
$("#carousel-comments li.jcarousel-item-first a").focus();
return false;
});
// After the last link of the last visible item, the focus should go out :
$("#carousel-comments").delegate("li.jcarousel-item-last a", "keydown", function (e) {
var code = (e.keyCode ? e.keyCode : e.which);
if (code == 9) { $("#rang3 a").first().focus(); return false; }
}); |
Hello! Everything work's perfectly, but some problem in scrollCallback from this code: var scrollCallback = function(event, carousel, target) { var list = carousel.list(), items = carousel.items(), size = carouselCommentsData.length, parsed = jCarousel.parseTarget(target), first = carousel.last().index() + 1, last = first + parsed.target; for (var i = first; i < last; i++) { if (i >= size) { break; } if (items.eq(i).size() > 0) { continue; } list.append(createItem(carouselCommentsData[i])); } carousel.reload(); }; Error from firebug console: ReferenceError: jCarousel is not defined parsed = jCarousel.parseTarget(target); |
In the meantime, everything was moved under the
|
Works like a charm! Many thx! |
I'd like to convert my carousels to 0.3 branch, in order to fix my focus problems, and the resize problems under Chrome, as discussed in several issues here.
Is there some kind of know limitations with this branch, compared to the 0.2.8 one ? For example :
Furthermore, I've put my config code in an external file : should I use $(document).ready() (as I used to with 0.2.8) ? For the moment, I just have the following code in my config file :
Is that fine ?
Thanx for your help,
Dupond
The text was updated successfully, but these errors were encountered: