Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check whether ancestor of element is fixed

I've got a website that has a fixed navbar, and I want to use Zurb Joyride to attach tips to elements in the navbar. The problem is that when the page scrolls, the navbar stays put but the tooltips don't.

I tried attaching the tooltips to elements within the navbar (instead of body), but I got strange rendering issues. Setting position: fixed on the div containing the tip seems to work, but I'm wondering if there's an easy way to programmatically detect if an element is non-scrolling, due to the fact that its contained within a fixed-position container, so that I can detect when to set the Joyride tips to be fixed as well. Any suggestions?

like image 659
acjay Avatar asked Mar 23 '23 07:03

acjay


2 Answers

Here is a pure JavaScript approach. It iterates over all offset parents until it finds a fixed one (or none at all).

function isFixed(elem){
    do{
      if(getComputedStyle(elem).position == 'fixed') return true;
    }while(elem = elem.offsetParent);
    return false;
}

If you're using jQuery, you'll need to extract the node object using elem[0] or elem.get(0).

like image 153
Jameson the dog Avatar answered Apr 02 '23 17:04

Jameson the dog


You can use jQuery to do this. Lets say your ancestor element which is the fixed position container has a class of "ancestor" for simplicity. Lets also say your descendants (Joyride tips) have a class of "descendant". Both of these assumptions should be something you can easily add to your HTML, or alternatively use an existing class as a different jQuery selector. Then you can do something like this to do your detection.

if ($(".descendant").closest(".ancestor").css("position") == "fixed") {
    // set your Joyride tip to fixed
}

Updated

Since you have given a little more away of what you want to do, I think the question is something like "How can I check if an ancestor has a fixed position and there is no closer ancestor that scrolls?". Adding to that, there is a requirement that none of the ancestors have classes or ids specified. I am going to assume that your Joyride stops all have a class of "joyride-stop" purely for this example. So to determine whether to apply a fixed position to your Joyride stop or not, you would just need to do the following (using jQuery, since zurb joyride has it as a dependency):

var jStops = $(".joyride-stop");

for (var i=0; i<jStops.length; i++) {
    var pEls = jStops[i].parents();
    for (var j=0; j<pEls.length; j++) {
        if(pEls[j].css("position") == "fixed") {
            // closest ancestor is fixed.
            // insert code to fix your Joyride element here
            break;
        } else if (pEls[j].css("overflow") == "scroll") {
            // closest ancestor scrolls so just break and move on
            break;
        }
    }
}

Note that I have only checked for the overflow css property here. If you wanted to get fancy you could check for overflow-x, overflow-y and potentially any other attribute that may be influencing whether scrolling is present (such as some other custom JavaScript widget). The check depends on what you need to worry about on your page really,

Is this what you were after?

like image 31
dcarson Avatar answered Apr 02 '23 17:04

dcarson