1

This function only works once, when I click an anchor element again, nothign happens. I thought the selector would apply the .click function to all matched elements?

 $('#welcome-nav li a').click(function (e) {
   // prevent anchor from firing
    e.preventDefault();

    var chosenElement = $(this).parent().attr('class');
    var index = articles.indexOf('.' + chosenElement) + 1;


   //remove all classes of active on articles
    $.each(articles, function (index, value) {

       $(value).removeClass('active');
   })

    $('.' + chosenElement).addClass('active');
    $('#sharpContainer').bgStretcher.sliderDestroy();
    startBgStretcher(returnImageArray(index));


 })

Below is the plugin that I think is breaking the onclick function

    $('#sharpContainer').bgStretcher({

        images: imageContainer,
        anchoring: 'left top', //Anchoring bgStrtcher area regarding window
        anchoringImg: 'left top',   //Anchoring images regarding window
        nextSlideDelay: 8000, //Numeric value in milliseconds. The parameter sets delay until next slide should start.
        slideShowSpeed: 2000, //Numeric value in milliseconds or(’fast’, ‘normal’, ’slow’). The parameter sets the speed of transition between images
        transitionEffect: 'superSlide',
        slideDirection: 'W',
        callbackfunction: homepageSlide
    });



function homepageSlide() {

    //homepage slide is called after a slide has loaded
    var index = $('li.bgs-current').index();

    //hide current article
    $.each(articles, function (index, value) {

        $(value).removeClass('active');
    })

    //show next article
    $(articles[index]).addClass('active');


}
Claire
  • 3,683
  • 13
  • 47
  • 74
  • make sure to have ; at end of alert(); and after the }) on the jquery – AbstractChaos Jun 26 '12 at 09:21
  • 1
    You do not require the ; JS can work without it – Sammaye Jun 26 '12 at 09:22
  • @Nicola - Can you make an example on http://jsfiddle.net? What you have [should work](http://jsfiddle.net/KJRhQ/). – James Allardice Jun 26 '12 at 09:24
  • this code has no errors, and working absolutely fine see demo: http://jsfiddle.net/rathoreahsan/bdbQ8/ – Ahsan Rathod Jun 26 '12 at 09:27
  • good practice as developer to do so anyway. :) – David 'the bald ginger' Jun 26 '12 at 09:28
  • yes seen that, however, my code isn't as simple as above. I thought it would be the same, so I simply removed the rest, it has a whole bunch of other stuff below the alert. But I didn't think this shoudl make any difference. – Claire Jun 26 '12 at 09:29
  • @Sammaye yes it can work with out the ; however it removes ambiguity and helps minification (i believe for the same reason). see this [answer](http://stackoverflow.com/questions/444080/do-you-recommend-using-semicolons-after-every-statement-in-javascript) for some reasons for and against – AbstractChaos Jun 26 '12 at 09:29
  • @Nicola, with this code you will not face any problem, can you show us full code... – Ahsan Rathod Jun 26 '12 at 09:33
  • @Nicola, Silly question, still asking, do you have this event binding inside `document ready`? As it's working with `on and not with click`, that can be the case, because `.on()` one will work even if it's outside `document ready` while `.click()` wont. – Prasenjit Kumar Nag Jun 26 '12 at 09:38
  • no its inside the document.ready – Claire Jun 26 '12 at 09:48
  • @Nicola: What is `articles` in this line `var index = articles.indexOf('.' + chosenElement) + 1;` Have you defined it somewhere? As it is doesn't exists in your code that's why your code is not executing. – Ahsan Rathod Jun 26 '12 at 10:09
  • sorry, yes it is an array thats at the beginning of my js file – Claire Jun 26 '12 at 10:11
  • So you got why it is not executing? – Ahsan Rathod Jun 26 '12 at 10:15
  • no, not really, but it works with document.on('click'... – Claire Jun 26 '12 at 10:21

3 Answers3

4

I think this might be due to the way JQuery binds by default. If you use:

$(document).on('click', '#welcome-nav li a', function(e){
    e.preventDefault();
    alert('here');
});

What happens?

Edit

Example of static element usage

$('#welcome-nav li').on('click', 'a', function(e){
    e.preventDefault();
    alert('here');
});
Sammaye
  • 43,242
  • 7
  • 104
  • 146
  • that works! Why is that? Why wasn't it working as I had it? – Claire Jun 26 '12 at 09:27
  • Maybe because you are loading the items with AJAX? Also you are now binding the event to the document to select all li a's within it. You can read more about on here: http://api.jquery.com/on/ – Sammaye Jun 26 '12 at 09:29
  • No, I'm not using AJAX, coding in visual studio and the elements are all hard coded in. – Claire Jun 26 '12 at 09:31
  • I do remember something dodgy about normal binding on multiple elements. I must admit I have forgotten the problem, either way on() is much better and attaching it to document means you can use AJAX and what on without ever losing the bind. – Sammaye Jun 26 '12 at 09:34
  • ah, but not my other elements on the page that have a click handler aren't working – Claire Jun 26 '12 at 09:49
  • Without a fiddle I cannot really explain that to you but you should use delegation in the manner described above for all your click(), hover() etc. – Sammaye Jun 26 '12 at 09:59
  • so I need to add a document.on for every click function then? – Claire Jun 26 '12 at 10:03
  • That or just use on() with element selectors, you don't always need to use document just when you cannot rely on the element always being static. – Sammaye Jun 26 '12 at 10:04
  • I have added a static element example which should help you out – Sammaye Jun 26 '12 at 10:04
  • Verrrrrrrry weird, can you provide an example fiddle of this? I wouldn't mind hacking at it personally – Sammaye Jun 26 '12 at 10:06
  • I would do, but I think it's too complicated to with it being in visual studio and I'm also firing a plugin in that function too – Claire Jun 26 '12 at 10:10
  • Ah I see that now `bgStretcher.sliderDestroy();` hmm can you trace exactly what line using dev tools (f12) with line breaks in your code? – Sammaye Jun 26 '12 at 10:15
  • I think it has something to do with my plugin, I'll just post the startup function and the callback function above. The plugin creates a background on the full page thats a slideshow, so it takes an array of images to use. – Claire Jun 26 '12 at 10:23
  • oh and the amended .on selector works as my original code did, only on the first click, then it stops firing – Claire Jun 26 '12 at 10:29
  • Why do you check the answer as accepted if your problem isn't solved yet? – Simon Jun 26 '12 at 10:45
  • Well I have it working via another method, so it is solved, it's just that I don't know why what I had wasn't working – Claire Jun 26 '12 at 10:47
  • Either way you should post your method in an answer and check that as accepted because it's the idea to find a working solution ;). – Simon Jun 26 '12 at 11:08
0

You could try the simple "return false;" after doing all the things you want to do in the .click event function.

David 'the bald ginger'
  • 1,296
  • 3
  • 20
  • 38
  • 1
    return false does not do what you think http://fuelyourcoding.com/jquery-events-stop-misusing-return-false/ – Sammaye Jun 26 '12 at 09:37
  • @Sammaye Ah! An interesting read. Ok, will admit that return false; may not be the best solution seeing as Nicola is targeting links in lists in a container. – David 'the bald ginger' Jun 26 '12 at 09:46
0

I would bind it like this:

$('#welcome li').on('click', 'a', function(e) {
    e.preventDefault();
    whatever();
});
Simon
  • 7,182
  • 2
  • 26
  • 42
  • No offense, but you do not seem to understand the concept of .on(), you can choose any element which will be the range of the event binding, the second parameter to .on() gives the action selector. You can set $(document).on('click', 'a', function() {}); if it conforms to your aims. – Simon Jun 26 '12 at 10:10
  • I don't know if they have changed their coding now but if #welcome does no exist on bind time of the on() then the on() will not bind will it? Which means that when the a comes to be loaded through some other method like AJAX that event will not be binded. At least that's how on() worked a couple of months ago. – Sammaye Jun 26 '12 at 10:24
  • if just the anchor gets loaded via AJAX it works, if #welcome gets loaded via AJAX it won't work: "Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on()." – Simon Jun 26 '12 at 10:42
  • Yea that's what I meant by #welcome being dynamic. But I agree if #welcome is a static object that exists on page load your method is better – Sammaye Jun 26 '12 at 10:54