3

Posting as a jquery newbie. I am sure there must be a way to condense the code below in a DRY fashion. Essentially this is just a show/hide that is applied to multiple elements on a page, all using the same template and naming conventions:

$("#homelink1").hover(
    function() { $("#poptext1").show(); },
    function() { $("#poptext1").hide(); }
);

$("#homelink2").hover(
    function() { $("#poptext2").show(); },
    function() { $("#poptext2").hide(); }
);
...

I'm stuck on how to convert this to a function with passed parameters, so that I could just pass the integer (1 or 2) and have the function evaluate the rest, e.g.

$("#homelink" + param).hover

1
  • 1
    Show us the related HTML items Commented Jul 7, 2010 at 21:07

5 Answers 5

5

How about this:

function setHover( param ){
   $("#homelink" + param).hover(
    function() { $("#poptext" + param).show(); },
    function() { $("#poptext" + param).hide(); }
  );
}
Sign up to request clarification or add additional context in comments.

2 Comments

or param as an array? eh? eh?
Or you could just use a for loop :)
2

I'd probably try something like the following:

$('.homelink').bind('hover', function(){
    $('.poptext', this).toggleClass('hide');
});

# and some CSS

.hide {
    display: none
}

Bind the hover event to a generic classname, rather than trying to figure out how to hackishly bind it to #homelink{somenumber} and #poptext{somenumber}. Keep your ids in place if you must (for styling hooks for example), but simplify things and use classes.

3 Comments

I agree -- it seems like a case of "coincidental coupling", where two things are expected to have a relationship just because they share a naming convention. Classes are definitely the way to go here.
+1 I don't know the HTML structure, but am assuming that .poptext class is somehow structurally related to .homelink. If so, this makes adding new stuff extremely easy - just change the HTML, JavaScript remains intact.
Yeah, this is definitely a more flexible solution. I ended up going with Faisal's solution because it required the least refactoring of my existing code, but I like this approach.
2

Are the #poptext elements children of their respective #homelink? If so, you could create a "homelink" class and a "poptext" class and then do something like the following:

$(".homelink .poptext").hover(
    function() { $(this).show(); },
    function() { $(this).hide(); }
});

As a side note, most functions in jQuery work just as well on collections of objects as they do on a single one. In this case, even though $(".homelink .poptext") is returning a collection of objects, each one is individually associated with a mouseover and mouseout handler by hover().

2 Comments

I actually already had some similar classes in the code, so this ended up working great. The .poptext elements were siblings of .homelabel elements, so the code that worked for me is: $("div.homelabel").hover( function() { $(this).siblings(".poptext").show(); }, function() { $(this).siblings(".poptext").hide(); } );
Great! Also, kind of a "duh" moment for me here, but I forgot that you wanted the hover() event associated with the homelink and not the poptexts, in which case my code doesn't work. Good on you for figuring it out in the end anyway. :)
2

You could use a regexp to get the number from the homelink that was hovered, then toggle the associated poptext.

Try it out: http://jsfiddle.net/xFR3s/

$("#homelink1,#homelink2").hover( function() { 
    $("#poptext" + this.id.match(/\d+$/)[0]).toggle(); 
});​

You could make it shorter with a "starts with" selector for the homelink elements. Less efficient, but it only runs once on DOM load, so perhaps it's alright.

Try it out: http://jsfiddle.net/xFR3s/1/

$("[id^=homelink]").hover( function() { 
    $("#poptext" + this.id.match(/\d+$/)[0]).toggle(); 
});​

EDIT: If you don't want it interpreted on the fly, I guess I'd do something like this:

Try it out: http://jsfiddle.net/xFR3s/2/

$("[id^=homelink]").each(function() {
    var num = this.id.match(/\d+$/)[0];
    $(this).hover( function() { 
        $("#poptext" + num).toggle(); 
    });​
});

or this:

Try it out: http://jsfiddle.net/xFR3s/3/

$("[id^=homelink]").each( function() {
    $(this).hover( setUpHover(this.id.match(/\d+$/)[0]) );
});

function setUpHover(num) {
    return function() {
        $("#poptext" + num).toggle(); 
    };
}​

Comments

0

why don't you create an element with a class so you can do like this :

jQuery('.homelink').each(function() {
    var me = jQuery(this);
    var target = me.find('.poptext'); //if the target is 'poptext' class
    me.hover(
        function() {
           target.show();
        },
        function() {
            target.hide();
        }
    );
});

Comments

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.