2

I have a order list with about 10 list items that have anchor tag links associated with them. I am trying to force the user to only be able to click the child of the parent li once the link is visited. So in a sense I want to force the user to click the li links in the sequential order that is generated by the ol.

Here is my html:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>titlePage</title>
  <link rel="stylesheet" type="text/css" href="titlePage.css"></head>
  <script src="../jsLibraries/jquery-3.1.0.js"></script>
  <script src="titlePage.js"></script>
</head>

<body>

<img id="backgroundIMG" src="images/Chapter-v2.png">

<ol id="chapterNumbers">
   <li><a href="../chapters/chapter0.html">Chapter 0 - Animate Content</a></li>
  <li><a href="../chapters/chapter1.html">Chapter 1 - Animate Content 2</a></li>
  <li><a href="../chapters/chapter2.html">Chapter 2 - Video Content</a></li>
  <li><a href="../chapters/chapter3.html">Chapter 3 - Video Content 2</a></li>
  <li><a href="../chapters/chapter4.html">Chapter 4 - Audio Content</a></li>
  <li><a href="../chapters/chapter5.html">Chapter 5 - Blah</a></li>
  <li><a href="../chapters/chapter6.html">Chapter 6 - Blah</a></li>
  <li><a href="../chapters/chapter7.html">Chapter 7 - Blah</a></li>
  <li><a href="../chapters/chapter8.html">Chapter 8 - Blah</a></li>
  <li><a href="../chapters/exam.html">Exam</a></li>
</ol>

<header id="courseTitle"> 001234OOELNA - Example Course Using Adobe Animate </header>


</body>
</html>

Here is my jQuery JS that I was starting with:

$(document).ready(function(){

  $("li").first().nextAll().click(function( event ) {
      event.preventDefault();
  });

});

Here is the CSS associated with the anchor tag being visited:

a:visited {
color:white;
}

Here is a link to the out put as it is:

http://skywest.theyard.space/index/titlePage.html

Can anyone please help me figure out where I'm going wrong and how to make it so once that first link is clicked the first-child's link is activated (returned true?) and so on so the user has to click the links in sequential order?

Thank you! Eric

  • 1
    FYI, you cannot target `:visited` pseudo selector in javascript for obvious security reason. Now if you just want user to click in sequential order per page load, this is of course possible – A. Wolff Sep 02 '16 at 15:52
  • 3
    whats the problem with only showing "available" links on each page (ie page 1 only show page 1 link, page 2 show page 1,2 links)? – Samuel Cook Sep 02 '16 at 15:52
  • So once they click the first link, **then** they can click the second link and so on and so forth? Can they click the same link more than once? – J. Allan Sep 02 '16 at 15:53
  • _"So in a sense I want to force the user to click the li links in the sequential order that is generated by the ol"_ Not entirely sure what expected result is? User must click `` in sequential order? User must click first `` first? Then, only second `` can be clicked? – guest271314 Sep 02 '16 at 15:57
  • So how do you know when the next link should be clickable? What happens when they refresh the page? – epascarello Sep 02 '16 at 16:11
  • @epascarello Should be possible using `history` or `localStorage`, see http://stackoverflow.com/questions/29986657/global-variable-usage-on-page-reload/30144363?s=2|1.3555#30144363 – guest271314 Sep 02 '16 at 16:17
  • 1
    Why have navigation in the page if the user isn't going to be allowed to click on it? Just omit the extra links from each page. – Daniel Beck Sep 02 '16 at 16:43
  • @JefréN. Yes this is exactly what I'm looking for. Yes they can click the link more than once. Do you know how to do it? – Eric Belisle Giddings Sep 02 '16 at 19:29
  • @SamuelCook because it's like the table of contents in a book. – Eric Belisle Giddings Sep 02 '16 at 19:34
  • You already accepted an answer ... Confused. Why do you want to know if I can do it? – J. Allan Sep 02 '16 at 21:44
  • Sorry man. Was working top to bottom and didn't see the answer until after I replied to you. Thank you for your help! @JefréN. – Eric Belisle Giddings Sep 02 '16 at 21:50
  • Ok. No problem. Glad you got your problem solved. – J. Allan Sep 02 '16 at 21:52
  • Well I'm still having problems figuring out how to be able to click the link more than once. As you can see in the thread below with the answer I marked correct. localStorage doesn't seem to be solving the issue right now for some reason... @JefréN. – Eric Belisle Giddings Sep 02 '16 at 21:57
  • Is it supposed to save what links can be clicked between page loads? – J. Allan Sep 02 '16 at 22:07
  • Yea. For example. User goes to titlePage. Initially only chapter 0 link is enabled. User clicks chapter 0 and goes through pages until returns to titlePage. At that point since chapter 0 has been visited. Chapter 0 and Chapter 1 are now enabled. User clicks Chapter 1 and goes through until returning to titlePage. Now Chapter 0, Chapter 1, and Chapter2 are enabled. And so on...User can click any of the previous chapters that they have visited to review if they desire...Does this make sense? @JefréN. – Eric Belisle Giddings Sep 03 '16 at 00:54
  • Yea, it does. mile – J. Allan Sep 03 '16 at 01:13
  • There. I gave you an answer with error checking and all the goodies... Please Upvote if it's useful ... Ask if you don't understand. Thanks. :D – J. Allan Sep 03 '16 at 03:16

3 Answers3

2

If user click on link, is navigated out of links page, so any trick with add/remove class will not work.

So this code is supposed to work even after return to page with links. And order is reseted after closing/opening browser.

$(document).ready( function() {
  if (!sessionStorage.active) {
    sessionStorage.active = "1";
  }

  (function set() {
    $("li a").each(function(idx, elm) {
      if (sessionStorage.active != idx+1) {
        $(elm)
          .parent().fadeTo(1, 0.7)
          .off("click").on("click", function(evt) {
            evt.preventDefault();
          });
      } else {
        $(elm)
          .parent().fadeTo(500, 1)
          .off("click").on("click", function() {
            sessionStorage.active = parseInt(sessionStorage.active, 10) + 1;
            set();
          });
      }
    });
  }());
});

Version 2:

$(document).ready( function() {
  if (!localStorage.active) {
    localStorage.active = "1";
  }

  (function set() {
    $("li a").each(function(idx, elm) {
      if (localStorage.active < idx+1) {
        $(elm)
          .parent().fadeTo(1, 0.7)
          .off("click").on("click", function(evt) {
            evt.preventDefault();
          });
      } else if (localStorage.active == idx+1){
        $(elm)
          .parent().fadeTo(1000, 1)
          .off("click").on("click", function() {
            localStorage.active = parseInt(localStorage.active, 10) + 1;
            set();
          });
      } else if (localStorage.active > idx+1) {
        $(elm)
          .parent().fadeTo(1000, 1)
          .off("click").on("click", function() {
            return true;
          });
      } 
    });
  }());
});

Or Version 2 hyper "smplfd", partly inspired by jefré-n code

$(function(){var a=localStorage.a||0,l=$('a')
l.click(function(){if(l.index(this)>a)return false
if(l.index(this)==a)localStorage.a=++a})})
  • Is there any way to keep the ones that have been visited still able to be visited a second time? Sorry I didn't make that original comment clear enough... – Eric Belisle Giddings Sep 02 '16 at 20:20
  • 2
    Yes, it is. Just use localStorage instead of sessionStorage. –  Sep 02 '16 at 21:35
  • So are you saying just change the words sessionStorage to localStorage? I tried that and it still doesn't seem to be allowing me to visit a link twice. Once it moves on I can not click on a link I previously visited...Any idea why? You're a big help I appreciate this a lot! – Eric Belisle Giddings Sep 02 '16 at 21:59
  • I might not have been clear - By second time I meant if they want to review a link's content that they have already visited... For example. User goes to titlePage. Initially only chapter 0 link is enabled. User clicks chapter 0 and goes through pages until returns to titlePage. At that point since chapter 0 has been visited. Chapter 0 and Chapter 1 are now enabled. User clicks Chapter 1 and goes through until returning to titlePage. Now Chapter 0, Chapter 1, and Chapter2 are enabled. And so on...User can click any of the previous chapters that they have visited to review if they desire. – Eric Belisle Giddings Sep 03 '16 at 00:57
  • Ok. I added Version 2. I hope its what you want. –  Sep 03 '16 at 11:10
  • Sorry - I realized I don't have access to the server and my documents until after the Labor Day holiday. I'll get back to you on Tuesday about this. Hope that's ok? Thank you! Your help is appreciated so much! – Eric Belisle Giddings Sep 03 '16 at 13:00
  • I appreciate the "partly inspired" part. Thanks. – J. Allan Sep 03 '16 at 13:21
  • Thank you for your help! It's appreciated a lot! Both you and @JefréN. have been a huge help! – Eric Belisle Giddings Sep 06 '16 at 21:31
1

Check this out. (I comment my code well so an explanation shouldn't be necessary. If, however, you need clarification, just tell me... :D)

var $links = $("li a");

//simplify localStorage error checking
var supportsLS = true;
try {
    //this will throw an exception if we can't use localStorage
    //ie. the user, like me, disables cookies ... :)
    localStorage.supportsLocalStorage = true;
    }
catch (exc) {
    supportsLS = false;
    }

//initialize the first link they can use
if (supportsLS && localStorage.getItem("nextAvail") === null) {
    localStorage.nextAvail = 0;
    }

function onLinkClick (evt) {
    /*
    This handles a given click on a link.
    */

    //no point in running rest of code--they don't have localStorage support
    //OR we aren't allowed to use it
    if (supportsLS === false) {
        return;
        }

    //cache some info -- improve readability
    var thisInd = $links.index(this);
    var nextAvail = parseInt(localStorage.nextAvail);

    //they can't view this link -- prevent it from working
    if (thisInd > nextAvail) {
        evt.preventDefault();
        }

    //if they clicked the last link they're allowed to click,
    //update localStorage.nextAvail so they can click the next link.
    else if (thisInd === nextAvail) {
        localStorage.nextAvail = thisInd + 1;
        }
    }

//setup onclick handlers
$links.click(onLinkClick);

Summary of what was wrong:

The way I originally handled "updating" localStorage.nextAvail was flawed plain wrong. You can check the code to see why, but suffice it to say that the "updating" updated nothing, and while using the program in the intended way, the user could accidentally undo their progress.

J. Allan
  • 1,418
  • 1
  • 12
  • 23
  • Brilliant! Thank you! I'm going to test this when I get home from this flight and get back to you :) – Eric Belisle Giddings Sep 03 '16 at 10:11
  • Sorry - I realized I don't have access to the server and my documents until after the Labor Day holiday. I'll get back to you on Tuesday about this. Hope that's ok? Thank you! Your help is appreciated so much! – Eric Belisle Giddings Sep 03 '16 at 12:59
  • @EricBelisleGiddings: No problem. :) – J. Allan Sep 03 '16 at 13:05
  • @EricBelisleGiddings: I'm looking forward to you testing my answer tomorrow... :) – J. Allan Sep 06 '16 at 00:08
  • It doesn't seem to be letting me past the first link. 1-9 are locked down but don't open up sequentially once the first link is visited. I'm guessing it's a small fix since WaldemarIce was inspired by your code ;) Or maybe I'm doing something wrong implementing it? I have it inside a $(document).ready( function() {}); – Eric Belisle Giddings Sep 06 '16 at 14:33
  • 1
    @EricBelisleGiddings: Hmmm. Let me check it out. :( – J. Allan Sep 06 '16 at 15:36
  • Ok that's cool. I'm here all day. Let me know if you need any of my help doing anything... – Eric Belisle Giddings Sep 06 '16 at 15:52
  • @EricBelisleGiddings: Sorry about that. It should work now. :) – J. Allan Sep 06 '16 at 16:18
  • Perfect! Thank you so much! You're awesome! The commenting is very helpful too! Can I not mark both your answers correct? – Eric Belisle Giddings Sep 06 '16 at 21:29
  • 1
    @EricBelisleGiddings: I'm afraid not. However, you can upvote both of our answers. *(I think you already did, though.)* In truth, I think Walder@ probably deserves to be accepted since he gave you a *(semi)* working answer, first. :) – J. Allan Sep 06 '16 at 23:32
0

Your JS makes all links but the first non-clickable, regardless of the the fact they have been visited or not.

Unfortunately, you can not determine if a link was visited, based on js (see this link).

anthony
  • 61
  • 1
  • 6