How do I create a simple history tracker in JavaScript? - javascript

Looking for a way to keep track of clicks in JavaScript. I have a series of javascript controlled sides in separate div wrapppers. I'll need a counter that will keep track of the previous slide number that was clicked. This will be used to fade out the previous div when the new div loads. The HTML page will not reload so I don't think I can use the browser history function as an option. I really only need to know the previous slide number since the slide numbers can be clicked out order.

You can make a variable and update it everytime when there has been clicked on a new slide, but I think it's easier to just fade out all the slides, then fade in the slide that was clicked on.
This way you don't need to know which slide is currently shown.
Léon

If you expect the user to never reload the page, then what is keeping you from simply using a regular JavaScript variable?
var currentSlideIndex = 0;
function nextSlide() {
currentSlide = currentSlide + 1;
if (currentSlide >= slideCount) {
currentSlide = 0;
}
}
You'll find that many similar HTML5-slide packages, keep track of the current slide in the document fragment identifier of the browser. When you do that, the slideshow can survive an F5 and users can send links to the current slide by copy/pasting the address.

The best option is to use History.js, but it's a bit of overkill. The bonus is that it's semantic, and will keep the state on browser reload. Also the back button goes to the previous tab.
Other solutions depend on your setup, and your libraries that are available (jQuery, etc.). If you're using a standard plugin for something, they usually have callbacks for when the state changes. Check the API.
The basic algorithm is applying a click handler to each button. You can store a global variable containing the current state. Give a class like .slideButtons to the absolute buttons (page1, page2, page3, etc.) and a id of #nextSlide and #prevSlide to the next and previous buttons selectively. In the handler, check the class and id. If it's nextSlide, or prevSlide, add one, or subtract one, and then update. If it's one of the absolute ones, search in the parent node and count the matching classes until you find the one you're looking for. The number of your counter when you reach your pressed button is the new state. Set it, and update the slider.

Related

Jump back to index using `scrollToIndex` a second time

(This question pertains to the react-virtualized library)
I have a component that uses <List> to display several categories of items. The resulting output looks something like:
Jump to: Planets, Nebulae
PLANETS
- Mercury
- Venus
- Jupiter
- ...
NEBULAE
- Horsehead
- Ant
- Boomerang
- ...
I'd like to use the "Jump to" links to scroll to the start of the corresponding section in the list. If I scroll around some I'd like subsequent clicks of the jump link to take me back to the section.
The first time I click the "Nebulae" link it works fine, but nothing happens on subsequent clicks. I assume this is because scrollToIndex is a prop and doesn't change after the first click. I've tried using forceUpdateGrid but it doesn't seem to reset the scroll position.
Is there a way to jump to the same index multiple times in a row?
Unfortunately, this is a limitation of the props approach. (react-virtualized only manually scrolls when it detects a new prop. Otherwise, users would be unable to scroll with their mouses once an initial prop was set.)
One way to work around this is to unset the scrollToIndex prop once you've set it (so that if you then reset it, it will still be a new value). Temporarily unsetting it (aka resetting it to undefined) will have no affect on the list either so you should be fine.

javascript function using objects

I am designing a sort of game where there are team bases that surround a hexagonal board. The idea is that when a team base is clicked, it will be that team's turn. I have:
$('.team').click(function(){
var teamID=$(this).attr('id');
explore(teamID);
});
I then use the teamID to find the index of the team that was clicked, which is stored as an object from a json file with attributes such as teamname, score, etc.
function explore(index){ // the game portion
var turn=file[index]; // finds the team's info from json file
$('.hex').click(function(){ // when a hex is clicked.... play the game
alert(turn.teamname);
// game elements
}
This always works the first time around, however if I click on a different team box and then a hex, oftentimes it thinks that it is the turn of the box I clicked before. I added the alert(turn.teamname) to try to debug. If I'm clicking a different box, it will always alert the first box, and then send a second alert with the different box. I can't figure out why there would be two alerts? So it will always alert 'team1' and then 'team1','team2'. as I click more boxes it keeps alerting until it just alerts all of them. Additionally, if I have clicked more than two boxes before, even if I keep clicking the same hex it seems like it alternates between alerting me that it is 'team1' and 'team2'.
This is my first stackoverflow post so I hope it makes sense! Thanks!
The reason you get this behavior is that you add event handlers to dom elements but never remove them. You need to change the way you handle clicks on the hexes. You may add an event handler once with http://api.jquery.com/one/ to the parent element that holds all hexes and check which hex is clicked inside the event handler.
Or you can try a more trivial solution where you add an event listener once to the hexes and check if there is a selected team:
var turn;
var teamSelected = false;
function explore(index){ // the game portion
teamSelected = true;
turn=file[index]; // finds the team's info from json file
}
$('.hex').click(function(){ // when a hex is clicked.... play the game
if (teamSelected) {
alert(turn.teamname);
// game elements
teamSelected = false;
}
}
For something like this, I would recommend getting into meteor. The reactive programming model is much cleaner than an imperative one (especially in a game where it can quickly get complex).
I feel that this example illustrates what can be done very quickly using this framework (closest to your question's example).
To dive in, I'd recommend looking at the intro video, then proceed to the docs and a recent book about it.

jCarousel with keyboard : wrong focus using the tab key

I'm using the 0.3 version of the jQuery jCarousel script to display three carousels on the webpage I'm working on. Those three carousels work just fine.
The trouble is : you can't use them properly using the keyboard.
If you tab through the page, the focus goes to the first link of the first item in the carousel, even if this item is not visible ! (For example : click on a "next" link in one of the carousels, then use the tab key to browse : the focus will go to a link which is not visible inside of the carousel).
If you keep using the "tab" key, the focus will successively go to all the links of all the items in the carousel.
Instead of that : the focus should go to the first link of the first visible item ; then, if the last link of the last visible item is reached, then the focus should go out of the carousel (the next link outside of it, in fact).
A solution could be to use tabindex... but some parts of the page are shared with other pages of the website, so I just can't use tabindex in all the links of all my pages...
Instead of that, I had tried things like this :
$("#carousel-editos li a").focusin(function () {
$("#carousel-editos li.jcarousel-item-first .post-title a").focus();
return false;
});
but then it prevents any further use of the "tab" key...
I hope this is clear... Thanx for any help !
I think you need a combination of the answers that you've already provided. It seems like you should be able to use Javascript to dynamically set tabindex attributes on the HTML that you need to be tabbable (heh, new word). I'm thinking of something like this:
On page load, find all visible items in the carousel. Use jQuery to set the tabindex property for each item that you want in the tab cycle.
Assign tabindex properties to all other links on the page that you want to cycle through.
Add some jQuery to modify the tabindex attributes when the user changes the items in the carousel (click the next/prev buttons).
It would be much easier to help you if you made a simplified example in jsFiddle.
On the carousel createEnd and scrollEnd functions you can reset the contents of .jCarousel so that only the visible carousel items are "tabbable". I have done that in my code as follows:
var bannerSlider_scrollEnd = function(event, carousel) {
var $carousel = carousel.element(),
$items = carousel.items(),
$bannerContent,
$visibleItemsContent = carousel.visible().find('.bannerContent');
$items.each(function (index) {
$bannerContent = $(this).find('.bannerContent');
disableTabbing($bannerContent);
});
reenableTabbing($visibleItemsContent);
$visibleItemsContent.find(':focusable').eq(0).focus();
};
The disableTabbing($container) and reenableTabbing($container) lines refer to helper functions I coded into my site which basically find all :focusable elements in a given container and set the tabindex to "-1", then "0" respectively.
After this processes, users will be left tabbing only through visible carousel items instead of all carousel items.

Top and Bottom Pagination Sync

I have some weird behavior with jQuery paginate plug-in (jPaginate). I need to have top and bottom pagination and I want to sync them - whenever one is clicked, the second one should be properly changed as well.
I have two divs with number_pagination class and they are initialized the same way:
$(".number_pagination").paginate(options);
Now, here where it gets weird. Whenever I click on the top div, everything works as supposed to, but if I click on the bottom one, it changes the bottom one and does the pagination, but the top one stays the same. I cannot figure out why that could be happening.
Here's the onChange function that is supposed to change both pagination divs. Note the jQuery.fn.draw function that is a part of jPaginate. This is where it applies classes and style.
var opts=jQuery.extend({},jQuery.fn.paginate.defaults,options);
var o=jQuery.meta?jQuery.extend({},opts,jQuery(this).data()):opts;
jQuery(".number_pagination").each(function(){
var obj=jQuery(this);
jQuery.fn.draw(o,obj,page);
});
Found another solution that works perfectly.
It may even work for other pagination plug-ins. It checks the class that has the currently selected page number and checks if the content matches the selected NOW page, and if it doesn't, it looks for siblings that have the correctly selected page and triggers the click event.
jQuery(".jPag-current").each(function(){
if(jQuery(this).html() != page){
jQuery(this).parent().siblings().children().each(function(){
if(jQuery(this).html() == page){
jQuery(this).trigger("click");
}
});
}
});
You should probably look at using the onChange event to redraw the other pager that didn't incur the change

How to handle Android's Back Button click in a single HTML page webapp using PhoneGap?

I read from the documentation that we can handle the back button click using the following code:
document.addEventListener("backbutton", backKeyDown, true);
function backKeyDown() {
// Call my back key code here.
alert('go back!');
}
My concern is that I have a single HTML5 web page in which I have multiple div tags which I animate using jQuery as per the navigation option selected by the user from the menu options.
How can I, in this single page webapp, handle the back button click using PhoneGap and show the user the previously animated div. Clicking on the back button again would again take him to the previous div of the current previous div :-)
Thanks.
I solved the problem by creating a global array variable as
var myStack = new Array();
Then whenever I clicked on the div tag, I inserted the function prototype along with the arguments inside the myStack variable. For eg:
myStack.push(\"myfunction(args1, args2);\");
Then, using the code which I posted in my question, inside the BackButton handler, I wrote the following code:
var divToShow = myStack.pop();
eval(divToShow);
Hope this helps others.
I did an implementation in a similarly structured phonegap app. My situation was a bit more complex because I was loading in html as well as external data via ajax (rather than just unhiding divs). I created a global array called history which I used to keep track of current position as well as previous positions (position here being the most recent ajax function called, so the array was actually storing function names as text). The right sequence and combination of .pop and .push array methods got me a fully functioning js back button that scaled nicely and handled any kind of back and forth navigation I could think of.
I will just post my overall idea of handling this situation. Hope you can improvise and change it to suit your needs.
Have a global variable to remember the current div id that is
visible. For example, when a menu item x is clicked, set this global
variable to the div id that is currently visible (before showing the next div corresponding to menu item x).
When the back button is pressed, use the global variable's value to identify the previous div. Hide the current div and show the previous one.

Categories