简体   繁体   中英

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.

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..

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));
}); 

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM