views:

106

answers:

5

Currently i have this:

$(".splitCol").click(function () { 
    $.cookie('whichColumn', 'split'); 
    $(".threeCol .active").removeClass("active"); 
    $(".leftCol .active").removeClass("active"); 
    $(".splitCol span").addClass("active"); 

    $(".threeColumns li:eq(3)").removeClass("first");
       $(".threeColumns li:eq(6)").removeClass("first");

    $(".entries").removeClass("threeColumns");
    $(".entries").removeClass("leftColumn");
    $(".entries").addClass("splitColumns"); 

    $(".splitColumns li:eq(2)").addClass("first");
      $(".splitColumns li:eq(4)").addClass("first");
    $(".splitColumns li:eq(6)").addClass("first");
    $(".splitColumns li:eq(8)").css("display", "none");
  });

And i need to repeat all those commands again after i do an if check. How can i take all those and add them to a single function so that if you $(".splitCol").click(function () { then it runs the function. And then also if the IF statement is satisfied it runs it as well?

+2  A: 

Separate it out like this:

function clickHandler()
{
  $.cookie('whichColumn', 'split');
  $(".threeCol .active").removeClass("active");
  $(".leftCol .active").removeClass("active");
  $(".splitCol span").addClass("active");
  $(".threeColumns li:eq(3)").removeClass("first");
  $(".threeColumns li:eq(6)").removeClass("first");
  $(".entries").removeClass("threeColumns");
  $(".entries").removeClass("leftColumn");
  $(".entries").addClass("splitColumns");
  $(".splitColumns li:eq(2)").addClass("first");
  $(".splitColumns li:eq(4)").addClass("first");
  $(".splitColumns li:eq(6)").addClass("first");
  $(".splitColumns li:eq(8)").css("display", "none")
}

$(".splitCol").click(clickHandler);

You can use any anonymous function as your event handler. Bear in mind that the this keyword, when used in such a function, will refer to the DOM element being clicked.

David Andres
+2  A: 

That you have to re-run all that suggests that you may have a larger code structure problem (can't tell without seeing the rest of your code). You may want to revisit the flow/structure of your code.

Also, you've already put all of that code into a function - notice the function(). You can take that function block, put it elsewhere, name it, and then pass the name to click().

Also, for more efficient (less lookups) turn

$(".entries").removeClass("threeColumns");
$(".entries").removeClass("leftColumn");
$(".entries").addClass("splitColumns");

into

$(".entries").removeClass("threeColumns").removeClass("leftColumn").addClass("splitColumns");
Sam Bisbee
+3  A: 

You can extract your current anonymous callback function to a normal function:

In your click event binding:

$(".splitCol").click(function () {
  originalFunction();

  // The if statement you talk about...
  if (condition) {
    originalFunction();
  }
  //...
});


// extracted function
function originalFunction() { // please change the function name
  $.cookie('whichColumn', 'split'); 
  $(".threeCol .active").removeClass("active"); 
  $(".leftCol .active").removeClass("active"); 
  $(".splitCol span").addClass("active"); 

  $(".threeColumns li:eq(3)").removeClass("first");
  $(".threeColumns li:eq(6)").removeClass("first");

  $(".entries").removeClass("threeColumns");
  $(".entries").removeClass("leftColumn");
  $(".entries").addClass("splitColumns"); 

  $(".splitColumns li:eq(2)").addClass("first");
  $(".splitColumns li:eq(4)").addClass("first");
  $(".splitColumns li:eq(6)").addClass("first");
  $(".splitColumns li:eq(8)").css("display", "none");
}

Note: If your extracted function uses the this keyword, for example to get a reference to the element that triggered the click event, you should call it in a different way to preserve the context:

// in your click callback:
originalFunction.call(this); // preserve the context
CMS
+1 for the note about call(). I've been working in javascript for years and only just learned about call() while reading the jQuery source three days ago!
Gabriel Hurley
Ditto, that call tip is good to know.
stimms
A: 

Javascript in the DOM is largely event-based programming. So think like an event-based programmer and... do it with events!

Also, I took the liberty of applying some efficiency measures to your jQuery

$(".splitCol")
  .bind( 'your-custom-event-name', (function ()
  { 
    $.cookie('whichColumn', 'split');

    $(".threeCol, .leftCol")
    .find(".active")
    .removeClass("active");

    $(".splitCol span")
      .addClass("active");

    $(".threeColumns")
      .find("li:eq(3), li:eq(6)")
      .removeClass("first");

    $(".entries")
      .removeClass("threeColumns leftColumn")
      .addClass("splitColumns");

    $( ".splitColumns" )
      .find("i:even:not(li:eq(0),li:eq(8))")
      .addClass("first")
      .end()
      .find( "li:eq(8)" )
      .css("display", "none");
  } )
  .click( function()
  {
    $(this).trigger( 'your-custom-event-name' );
  } );

And then you can trigger this custom event from anywhere else

if ( /* whatever */ )
{
  $(".splitCol").trigger( 'your-custom-event-name' );
}
Peter Bailey
A: 

Highly inspired by David Andres and ravidgemole :D

var clickHandler = function(statement) {
  $.cookie('whichColumn', 'split');
  $(".threeCol, .leftCol").find(".active").removeClass("active");
  $(".splitCol span").addClass("active");
  $(".threeColumns").find("li:(6), li:eq(3)").removeClass("first");
  $(".entries").removeClass("threeColumns leftColumn").addClass("splitColumns");
  $(".splitColumns").find("li:nth-child(8-2n)").addClass("first")
        .end().find('li:eq(8)').hide();
  if (statement) {
    clickHandler(false);
  }      
};
// statement = ( 15 == 16 );
$(".splitCol").click(function(){
  clickHandler(statement);
});;
Mushex Antaranian
Unfortunately the code above does not work, namelt the find("li:6), li stuff doesn't seem to be catching on.
Angel Grablev