Allen
Allen

Reputation: 63

JQuery/Javascript - how to minimize duplicated code?

If I wanted to use the following code on multiple DIV#ID, how do I do so without duplicating code

var scrollElem = $('#div1');
scrollElem.scroll(function() {
 /* find the closest (hlisting) home listing to the middle of the scrollwindow */ 
    var scrollElemPos = scrollElem.offset();
    var newCenter = $(document.elementFromPoint(
        scrollElemPos.left + scrollElem.width()  / 2,
        scrollElemPos.top  + scrollElem.height() / 2)
    ).closest('.hlisting');
    if(newCenter.is(".HighlightRow")) return;
    $('.HighlightRow').removeClass("HighlightRow");
    newCenter.addClass('HighlightRow');
});            

What I want to do is perform this not only on div1, but also on div2, div3, div4.

But as you note, scrollElem is a global variable so I can't just stick all of this code in 1 function.

Meaning, to get this to work - I would have to do:

// DIV 2 ---------------------------
var scrollElem2 = $('#div2');
scrollElem.scroll(function() {
 /* find the closest (hlisting) home listing to the middle of the scrollwindow */ 
    var scrollElemPos = scrollElem2.offset();
    var newCenter = $(document.elementFromPoint(
        scrollElemPos.left + scrollElem2.width()  / 2,
        scrollElemPos.top  + scrollElem2.height() / 2)
    ).closest('.hlisting');
    if(newCenter.is(".HighlightRow")) return;
    $('.HighlightRow').removeClass("HighlightRow");
    newCenter.addClass('HighlightRow');
});

// DIV 3 ---------------------------
var scrollElem3 = $('#div3');
scrollElem3.scroll(function() {
 /* find the closest (hlisting) home listing to the middle of the scrollwindow */ 
    var scrollElemPos = scrollElem3.offset();
    var newCenter = $(document.elementFromPoint(
        scrollElemPos.left + scrollElem3.width()  / 2,
        scrollElemPos.top  + scrollElem3.height() / 2)
    ).closest('.hlisting');
    if(newCenter.is(".HighlightRow")) return;
    $('.HighlightRow').removeClass("HighlightRow");
    newCenter.addClass('HighlightRow');
});

That's copying and pasting a lot of duplicate code.

Question: there must be a better way to do this. Any ideas on how to accomplish the same functionality but minimize the duplication of code.

Upvotes: 1

Views: 406

Answers (4)

Joel
Joel

Reputation: 19358

I think a combination of the answers provided by Gaby and munch would be optimal:

Use a multi-selector and $(this),

$('#div1, #div2, ...').scroll(myFunc);

In combination with a predefined function:

function myFunc() {
    var scrollElemPos = $(this).offset();
    // etc...
}

Now existing functionality works as designed, and you can also call myFunc manually with call and apply.

// call myFunc with .call or .apply to set context
myFunc.call(someElement); // inside myFunc "this" will point to someElement

Upvotes: 1

Gabriele Petrioli
Gabriele Petrioli

Reputation: 195982

use multiple selector when you define the scrollElem

var scrollElem = $('#div1, #div2, ...');

and inside the function, wherever you want to use the current scrollElem use $(this)

var scrollElemPos = $(this).offset();

etc..

Upvotes: 4

Ty W
Ty W

Reputation: 6814

couldn't you change the anonymous function to a named function and pass the same function to whatever.scroll?

the only thing you'd have to change would be the reference to scrollElemX. use $(this) instead.

Upvotes: -1

munch
munch

Reputation: 6321

Put it into a function.

function myFunc(elem){
    var scrollElemPos = elem.offset();
    var newCenter = $(document.elementFromPoint(
        scrollElemPos.left + elem.width()  / 2,
        scrollElemPos.top  + elem.height() / 2)
    ).closest('.hlisting');
    if(newCenter.is(".HighlightRow")) return;
    $('.HighlightRow').removeClass("HighlightRow");
    newCenter.addClass('HighlightRow');
}

var scrollElem = $('#div1');
scrollElem.scroll(function() {
  myFunc($(this));
}); 

Upvotes: 2

Related Questions