admin管理员组

文章数量:1290934

I'm working on a site which dynamically creates facebook-like buttons via PHP. However, the <div> that the buttons are contained in needs to have the CSS property overflow: hidden; This is the only way I've found that works to make a two-column format which forces both columns to expand to be the length of the longest one. The only problem with this method is that any facebook-like buttons placed near the bottom of the container get clipped when someone clicks on them and they expand.

Here's the way I've tried to solve this issue:

  1. Using jQuery, I loop through all facebook like buttons on the page and calculate their document offset using the offset() method.

  2. I then clone() each button as well as give it absolute positioning and the calculated offset using jQuery's css() method. I hope that each cloned button will be placed in the same position of the button it was cloned from when I append it to the document.

  3. Finally, I change each old facebook-like button's css to visibility: hidden; in order to make it invisible but still take up the space it would have previously on the page. I add the clones of the facebook-like buttons to a div without the overflow: hidden; property using the appendTo() function.

Here's my entire code for this process:

// Replaces functional facebook remend buttons with identical ones
// in a div where they won't get clipped when they expand.
// Hides the old buttons so space is still left for new ones
$(window).load(function(){
    $(".fb-remend").each(function(){ // cycle through each remend button
        var offset = $(this).offset(); // calculate offset of each button
        var newButton = $(this).clone(); // clone the button
        newButton.css({'position':'absolute', 'left':offset.left, 'top':offset.top});
        $(this).css("visibility","hidden"); // hide the old button
        newButton.appendTo("#wrapper"); // put the new button in the wrapper where it won't get clipped
    });
});

At the end of all this, I expect to have clones of each button placed where the old button was but in a different <div>. The whole process works, except that the cloned facebook-like buttons are appearing at a slightly different position than the ones they were cloned from (as PitaJ points out they seem to be off by vertical offset multiples of around 39px). You can view the issue here:

LINK TO TEST WEBSITE

As you can see, the first button is placed in the correct location (the empty space filled by its hidden clone) but the other offsets were not calculated correctly.

I'd appreciate any ideas or help offered. Let me know if you'd like me to explain better or post more code!

Edit: I figured I'd post the CSS for the facebook-like buttons here (even though all I'm changing is the margin):

#content .fb-remend {
    margin: 15px 0 5px 0;
}

Edit 2: As per UnLoco's suggestion, I added a min-height property to the fb-recmend CSS and mented out the line of code that was hiding the old buttons so it's easier to see the problem (which is still there, though slightly lessened. The CSS now looks like this:

#content .fb-remend {
    margin: 15px 0 5px 0;
    min-height: 39px;
}

Edit 3: The problem appears to have been solved in all browsers but IE by changing the CSS to this:

.fb-remend {
    min-height: 24px;  // I used 24 because the fb-buttons are 24px in height
}

Final Edit? This seems to work on all browsers on my end, including IE:

.fb-remend {
    min-height: 39px;
}

I'm thinking now that the 39 might have e from the 15px margin of the old fb-button + its 24px height. I think I can get around it by simply setting the height to be 39px and not having a margin.

I'm working on a site which dynamically creates facebook-like buttons via PHP. However, the <div> that the buttons are contained in needs to have the CSS property overflow: hidden; This is the only way I've found that works to make a two-column format which forces both columns to expand to be the length of the longest one. The only problem with this method is that any facebook-like buttons placed near the bottom of the container get clipped when someone clicks on them and they expand.

Here's the way I've tried to solve this issue:

  1. Using jQuery, I loop through all facebook like buttons on the page and calculate their document offset using the offset() method.

  2. I then clone() each button as well as give it absolute positioning and the calculated offset using jQuery's css() method. I hope that each cloned button will be placed in the same position of the button it was cloned from when I append it to the document.

  3. Finally, I change each old facebook-like button's css to visibility: hidden; in order to make it invisible but still take up the space it would have previously on the page. I add the clones of the facebook-like buttons to a div without the overflow: hidden; property using the appendTo() function.

Here's my entire code for this process:

// Replaces functional facebook remend buttons with identical ones
// in a div where they won't get clipped when they expand.
// Hides the old buttons so space is still left for new ones
$(window).load(function(){
    $(".fb-remend").each(function(){ // cycle through each remend button
        var offset = $(this).offset(); // calculate offset of each button
        var newButton = $(this).clone(); // clone the button
        newButton.css({'position':'absolute', 'left':offset.left, 'top':offset.top});
        $(this).css("visibility","hidden"); // hide the old button
        newButton.appendTo("#wrapper"); // put the new button in the wrapper where it won't get clipped
    });
});

At the end of all this, I expect to have clones of each button placed where the old button was but in a different <div>. The whole process works, except that the cloned facebook-like buttons are appearing at a slightly different position than the ones they were cloned from (as PitaJ points out they seem to be off by vertical offset multiples of around 39px). You can view the issue here:

LINK TO TEST WEBSITE

As you can see, the first button is placed in the correct location (the empty space filled by its hidden clone) but the other offsets were not calculated correctly.

I'd appreciate any ideas or help offered. Let me know if you'd like me to explain better or post more code!

Edit: I figured I'd post the CSS for the facebook-like buttons here (even though all I'm changing is the margin):

#content .fb-remend {
    margin: 15px 0 5px 0;
}

Edit 2: As per UnLoco's suggestion, I added a min-height property to the fb-recmend CSS and mented out the line of code that was hiding the old buttons so it's easier to see the problem (which is still there, though slightly lessened. The CSS now looks like this:

#content .fb-remend {
    margin: 15px 0 5px 0;
    min-height: 39px;
}

Edit 3: The problem appears to have been solved in all browsers but IE by changing the CSS to this:

.fb-remend {
    min-height: 24px;  // I used 24 because the fb-buttons are 24px in height
}

Final Edit? This seems to work on all browsers on my end, including IE:

.fb-remend {
    min-height: 39px;
}

I'm thinking now that the 39 might have e from the 15px margin of the old fb-button + its 24px height. I think I can get around it by simply setting the height to be 39px and not having a margin.

Share Improve this question edited Aug 19, 2012 at 6:32 Alex Kalicki asked Aug 18, 2012 at 21:10 Alex KalickiAlex Kalicki 1,5339 silver badges20 bronze badges 4
  • 2 They're off by multiples of 39px – PitaJ Commented Aug 18, 2012 at 22:09
  • @PitaJ how'd you figure out the exact number of pixels? Any idea why that's happening? By trial and error I set my top CSS attribute to be offset.top + i*40, where i was passed in by the .each function, and this seemed to get it pretty close. – Alex Kalicki Commented Aug 18, 2012 at 22:14
  • I just used trial and error to get the 39, but I can't figure out why it's that many pixels off. – PitaJ Commented Aug 18, 2012 at 22:41
  • 1 now i get it bro, (i deleted older ments) this is because you are retrieving the offset before the iframes actually load. just add a css rule like this div.fb-remend{min-height:39px} – unloco Commented Aug 19, 2012 at 4:31
Add a ment  | 

2 Answers 2

Reset to default 6 +50

this is because you are retrieving the offset before the fb iframes actually load. just add a css rule like this
div.fb-remend{min-height:39px}

I believe you're problem is some odd jQuery weirdness.

To fix this, simple change your code to this:

$(window).load(function(){
    $(".fb-remend").each(function(index){ // cycle through each remend button
        var offset = $(this).offset(); // calculate offset of each button
        var newButton = $(this).clone(); // clone the button
        newButton.css({'position':'absolute', 'left':offset.left, 'top':offset.top + (39*index)});
        $(this).css("visibility","hidden"); // hide the old button
        newButton.appendTo("#wrapper"); // put the new button in the wrapper where it won't get clipped
    });
});

This will account for the weird offset problem.

本文标签: javascriptjQuery offset() not retrieving correct positionStack Overflow