2

I want to add a class to an object when I click on an div with the class "arrow right" or "arrow left". On http://jsfiddle.net/ does it work perfect. But on my Site it doesn't work :(

Can anyone help me?

jQuery:

var currentPage = 0;
var lastPage = ($(".post-preview > div").length)-1;
currentPage = $('.post-preview > div.show').attr('id');

$('.news > .right').stop().click(function() {
    if (currentPage == lastPage) {
            $('.post-preview > div#' + lastPage).hide();
            $('.post-preview > div#' + lastPage).removeClass('show');

        $('.post-preview > div#0').fadeIn(300);
        $('.post-preview > div#0').addClass('show');
        currentPage = 0;
    } else {
        $('.post-preview > div#'+currentPage).hide();
        $('.post-preview > div#'+currentPage).removeClass('show');
        currentPage++;
        var nextPage = currentPage;
        currentPage--;
        $('.post-preview > div#'+nextPage).fadeIn(300);
        $('.post-preview > div#'+nextPage).addClass('show');
        currentPage = nextPage;
    }
 });

 $('.news > .left').stop().click(function() {
     if (currentPage == 0) {
        $('.post-preview > div#0').hide();
        $('.post-preview > div#0').removeClass('show');

        $('.post-preview > div#' + lastPage).fadeIn(300);
        $('.post-preview > div#' + lastPage).addClass('show');
        currentPage = lastPage;
    } else {
        $('.post-preview > div#'+currentPage).hide();
        $('.rpost-preview > div#'+currentPage).removeClass('show');
        currentPage--;
        var nextPage = currentPage;
        currentPage++;
        $('.post-preview > div#'+nextPage).fadeIn(300);
        $('.post-preview > div#'+nextPage).addClass('show');
        currentPage = nextPage;
    }
});

CSS for show class:

.news > .post-preview > div.show    { display: inline-block !important; }

My HTML Code:

<div class="news">
<div class="arrow left"></div>
    <div class="post-preview">
        <div id="0" class='show'></div>
        <div id="1"></div>
        <div id="2"></div>

    </div>
<div class="arrow right"></div>
</div>
10
  • 2
    You are likely executing the JavaScript too early, i.e. before the DOM is ready. Please read the jQuery tutorial, it tells you exactly how to setup jQuery. In order to help you or give a better suggestion, we really have to know what "it does not work" means. What is the behaviour you see and which behaviour do you expect? Commented Feb 5, 2013 at 14:12
  • 3
    If you have a jsfiddle, you should better show a link to your code, not to jsfiddle home page. Commented Feb 5, 2013 at 14:13
  • 1
    You should be caching the return of your jquery selectors, not reselecting over and over on the same element. Commented Feb 5, 2013 at 14:14
  • 1
    That logic of the ++ followed by the -- makes no sense. Commented Feb 5, 2013 at 14:16
  • 1
    Here my jsfiddle link: jsfiddle.net/mD3sy Commented Feb 5, 2013 at 14:51

1 Answer 1

5

You are trying to access an element that probably does not exist at the time of the execution. This is why it doesn't work.

You need to wrap your code inside a $(function() { /* put code here */ } ); block.

The reason why it works on jsfiddle is because the site does it for you as convenience.

** Edit **

In JavaScript, it is a good (if not best) practice to enclose your code inside it's own context. Take a look at the jQuery, jQuery UI and many JavaScript widgets and libraries. For example :

(function($) {    // receive $ as parameter; a jQuery instance

    /* place code here

})(jQuery);   // invoke the function above with this instance of jQuery

The reason for this is

  1. If you need to use a different version of jQuery, or are using a library that overrides the $ variable, this function above will not get affected by the changes
  2. Every variables declared (ie. var x = "foo";) will not be available outside the function, so you are certain that you are not polluting the window (global) namespace and have the right value when you need it. (Expose a global object if you need access to something outside the function (Ex: window.someVar = localVar;)

However, the above function will get executed as it is loaded by the browser, and might get executed before any DOM element is inserted into the DOM tree. This can be a problem for scripts setting up event listeners and such. Thus, if you need the function to be executed only when the DOM element is completely loaded and ready to be used, enclose your code inside a jQuery onload callback :

jQuery(function() {

    /* place code here */

});

or even

(function($) {
    // executed right now

    $(function() {
        // executed only when the DOM is ready

        /* place code here */

    });

})(jQuery);

** Update **

After reading your code a little further, I can only see (as commented) some odd things.

  1. Your IDs are numeric. From the HTML specification,

    ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").

    So you should a an id prefix... or base your selection on element indexes

  2. You can chain your queries instead of reparsing them all the time.

For example

jQuery(function() {

var firstPage = $(".post-preview > div:first").index(); // index of the first page
var lastPage = $(".post-preview > div:last").index(); // index of the last page
var currentPage = $('.post-preview > div.show').index() || firstPage;  // default to 0

$('.news > .right').stop().click(function() {
    if (currentPage == lastPage) {
        currentPage = $('.post-preview > div:eq(' + lastPage + ')')
           .hide()
           .removeClass('show')
           .siblings('div:first')  // first DIV
           .fadeIn(300)
           .addClass('show')
           .index();  // should be 0... but we never know
    } else {
        // note : will receive the next element index
        currentPage = $('.post-preview > div:eq(' + currentPage + ')')
           .hide()
           .removeClass('show')
           .next('div')             // get next DIV element
           .fadeIn(300)
           .addClass('show')
           .index();
    }
 });

 $('.news > .left').stop().click(function() {
     if (currentPage == firstPage) {
        currentPage = $('.post-preview > div:eq(' + currentPage + ')')
           .hide()
           .removeClass('show')
           .siblings('div:last')  // last DIV
           .fadeIn(300)
           .addClass('show')
           .index();
    } else {
        currentPage = $('.post-preview > div:eq(' + currentPage + ')')
           .hide()
           .removeClass('show')
           .prev('div')
           .fadeIn(300)
           .addClass('show')
           .index();
    }
});

});

And your HTML (no need for IDs anymore)

<div class="news">
<div class="arrow left"></div>
    <div class="post-preview">
        <div class='show'>Preview 1</div>
        <div>Preview 2</div>
        <div>Preview 3</div>
    </div>
</div>
</div>
Sign up to request clarification or add additional context in comments.

1 Comment

Note that if you modify the content (ie. add, remove div elements) of your div#post-preview container, you will need to reset the firstPage and lastPage variables! Just a thought.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.