3
\$\begingroup\$

As you will soon see I'm not the best jQuery developer out there (I'm a designer). At best, I make a prototype barely work. That said, I envisioned this Persona-slider which is just like any other jQuery header sliders out there, but slightly different.

See it in action here.

Each persona has its own story consisting of:

  • Name
  • Quote
  • Some paragraphs
  • 2 videos: a walk-in & walk-out sequence

I tried to hack this together but it's very quirky as you can see (certainly without any preloaders).

The switching of text is fairly simple, but I can't get the videos to work in a seamless fashion. When the user clicks a name, the persona is supposed to walk in, sit down in the chair and pause. It's not until the user clicks another persona, then the current persona walks out and the new walks in. Like if they're all sits down in to the same chair and tell their stories.

To complicate things further, it should be on autoplay by default (around 5 sec for each slide/persona). Also, you shouldn't be able to click a persona while a current one is playing already.

So obviously js/_personas.js needs a heavy clean-up and re-thinking to make it simpler, I use a lot of unnecessary variables etc, I believe.

(function() {


// Text for each Persona
  $('.personas--menu--item--01').click(function() {
    $('.selected').removeClass('selected');
    replaceText('Benny', 'Här hjälper dom mig också med att få ordning i min ekonomi.', 'Innan jag kom hit satt jag på ett rättpsykiatriskt sjukhus. Jag är fortfarande dömd men jag fick möjlighet att komma hit till Hillringsberg på öppenvård. Det är bra för här är vi tillsammans och har målet att jobba så att jag blir fri från mina papper. Jag går i terapi och gör mindfulness för att jag ska funka bra rent mentalt, för det kan bli kämpigt med drogsug och sånt.', 'benny');
  });

  $('.personas--menu--item--02').click(function() {
    $('.selected').removeClass('selected');
    replaceText('Göran', 'Här har jag umgänge och jag är trygg.', 'Om jag inte vore här skulle jag vara ett ensamt vrak med begränsad ekonomi. Injektion o mediciner kostar. Förr var jag alkoholist, en självmordsbenägen sådan. En gång fann de mig halvdöd, 31.5 grader hade jag i kroppstemperatur efter att ha tagit för många Stilinoct.', 'goran');
  });

  $('.personas--menu--item--03').click(function() {
    $('.selected').removeClass('selected');
    replaceText('Cecilia', 'Personalen anpassar sig väldigt mycket efter rådande omständigeter.', 'Behandlingshemmet har en egen psykiatriker vilket har varit till stort stöd för bägge mina brukare. Dessutom satsar de på att hjälpa och stödja brukarnas ekonomiska problematik vilket är superbra men ändå ovanligt. Deras rehabilitering är ett individuellt anpassad och dom jobbar med både KBT och Mindfulness.', 'cecilia');
  });

  $('.personas--menu--item--04').click(function() {
    $('.selected').removeClass('selected');
    replaceText('Gustaf', 'Han var som ett vrak, en borttappad och lusfattig kriminell på permis.', 'När min bror kom till Hillringsberg efter att ha suttit många år på rättspsyk, hade vi ingen kontakt. Jag minns senaste gången jag träffade honom när han satt på rättspsyk. Han var som ett vrak, en borttappad och lusfattig kriminell på permiss. Han var tungt medicinerad och svår att få kontakt med.', 'gustaf');
  });


  PlayIn('benny');

  function replaceText (name, h1, p, who) {
    event.preventDefault();

    $('.personas--content--title').fadeOut('slow');
    $('.personas--content--name').fadeOut('slow');
    $('.personas--content--text').fadeOut('slow');

    var current = $("#video1").attr("class");
    var mydiv = $("#player");

    var myvideo = $("<video id='video1' width='880' class='"+ who +"'><source src='http://688812344.r.cdn77.net/videos/"+ current +"_walkout.mp4' type='video/mp4'><source src='http://688812344.r.cdn77.net/videos/"+ current +"_walkout.ogg' type='video/ogg'>Your browser does not support HTML5 video.</video>");
     mydiv.html(myvideo);


     var myVideo = document.getElementById("video1");
     myVideo.load();
     myVideo.play();
     myVideo.onended = function(e) {

       PlayIn(who);
    $('.personas--content--name').fadeIn('slow').html(name);
    $('.personas--content--title').fadeIn('slow').html(h1);
    $('.personas--content--text').fadeIn('slow').html(p);
    $('.personas--main--content--btn--text').html(name +'s historia');
     }

  }

  function PlayIn(newperson) {

    var mydiv = $("#player");

    var myvideo = $("<video id='video1' width='880' preload='auto' class='"+ newperson +"'><source src='http://688812344.r.cdn77.net/videos/"+ newperson +"_walkin.mp4' type='video/mp4'><source src='http://688812344.r.cdn77.net/videos/"+ newperson +"_walkin.ogg' type='video/ogg'>Your browser does not support HTML5 video.</video>");
     mydiv.html(myvideo);
       var myVideo = document.getElementById("video1");
     myVideo.load();
     myVideo.play();
  }

})();
\$\endgroup\$
  • \$\begingroup\$ Welcome to Code Review! Your post looks good so far; please note that fixing problems with your code is off-topic, so e.g. you should try to get help with seamless videos on Stackoverflow instead. That said, I hope you get good reviews for the rest regardless! \$\endgroup\$ – ferada Jun 15 '15 at 15:32
  • 1
    \$\begingroup\$ Thanks for the welcome! Maybe I was a little unclear, I can get the seamless video to work, nevertheless quite quirky and not that smart. What I'm looking for is improvement and thus making it run better. \$\endgroup\$ – dwarflord Jun 15 '15 at 17:36
3
\$\begingroup\$

I am not too clear on what you are asking for exactly, but here are some suggestions that I hope will help you out.

I would suggest trying to make the code more generic. Instead of a function for each link, make one click event function apply to all links. You could then have the name or id as part of the link by either making it an attribute or a class. Then inside the click event handler, get that name/id and pass it to a new function. Pseudo code example:

$('.any-link-with-class').click(function() {
   var id = $(this).attr('persona-id');  // custom attribute you make or something
   var previousId = getCurrentId();  // either store in a local var or get from a control
   updatePersona(id, previousId);
});

I would also suggest storing all the details in a file or other variable so you can load those dynamically and get the details to display by the name/id. You call the clear selected in each function, better to do this in one place, and update the text fields at same time. More pseudo code:

function updatePersona(id, previousId) {
   playWalkOutVideo(previousId);  // show video of them exiting 
   updateSelected(id);  // remove selected class and apply to new person
   updateText(id);
   playWalkInVideo(id);  // pass in id to know which video to play
}

function updateText(id) {
   var persona = getPersonaDetails(id);  // either load from file or array object you make
   $('.title').html(persona.Name);
   // etc.
}

If you don't want the text to appear until they finish walking in for the video, you can do a setTimeout call to delay the text appearing until the video finishes (5 seconds = 5000 milliseconds which the function call uses). You will probably at least want to add a setTimeout call before you play the next video.

Edit based on comment:

One way to implement the getCurrentId is to create a hidden input field like this on the page:

<input type="text" id="currentId" style="display: none;" />

You can then set the value when you change the current person like this:

$("#currentId").text(id);  // if .text doesn't work, try .html(id)

You can then get the id in a similar way:

var id = $("#currentId").text();

You can also use hidden input types and other means to hold values on a page, this is just one way to do it. People can view the source code, so it isn't secure, but it is fine for holding variables or data you want to use on the same page.

\$\endgroup\$
  • \$\begingroup\$ Thanks, Steven. Exactly the re-thinking I was looking for - looks way proper. I'm going to implement this and see how it goes. I'll keep you posted. Just quick off the bat: I rather not do setTimeout as each video has different lengths, may vary 0.5-1s. Is there some way to do "Ok, this video is done playing, now do this" instead? \$\endgroup\$ – dwarflord Jun 15 '15 at 17:46
  • \$\begingroup\$ Also, could you please elaborate on the getCurrentId() function. Where would I store the previousId variable to have it remembered throughout the code? This is where code beats me! \$\endgroup\$ – dwarflord Jun 15 '15 at 18:12
  • \$\begingroup\$ I was thinking all your videos were 5 seconds, but I think you were on the right track with onended event handler, so I would try setting that to call the next video once it finishes. \$\endgroup\$ – Steven Kohus Jun 15 '15 at 20:24
  • \$\begingroup\$ As for getCurrentId() function there are a few ways to go about it. One quick way is to create a hidden text field (set the css style to 'display: none'), and then use jquery to set the text value to the id of the current person you are displaying. I'll edit the answer to show a quick example. Other ways include setting a cookie (nice if you want them to come back to which one they were viewing last the next time they visit the site), adding a class to the active person (similar to the ".select" you were going for, find which one is selected, then pull their id), etc. \$\endgroup\$ – Steven Kohus Jun 15 '15 at 20:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.