Making linking between anchors in an IFrame work in Chrome and Firefox 11+

About a year ago I wrote the post Making linking between anchors in an IFrame work in Firefox 4 and above which detailed a workaround for making anchor tags in IFrame’s function as expected. Unfortunately this fix stopped working as of Firefox 11 and in Chrome as well.  Firefox changed how it calculated the offset of an element inside of the IFrame. It used to calculate it relative to the parent window but now calculates relative to the IFrame window. To fix this you now must add the distance between the top of the page and the IFrame in the call to the scrollto function.

Here is the updated code:

$(function() {
  var iframeOffset = $("#ID_OF_MY_IFRAME", window.parent.document).offset();
  $("a").each(function () {
      var link = $(this);
      var href = link.attr("href");
      if (href && href[0] == "#") {
          var name = href.substring(1);
          $(this).click(function () {
              var nameElement = $("[name='" + name + "']");
              var idElement = $("#" + name);
              var element = null;
              if (nameElement.length > 0) {
                  element = nameElement;
              } else if (idElement.length > 0) {
                  element = idElement;
              }

              if (element) {
                  var offset = element.offset();
                  window.parent.scrollTo(offset.left, offset.top + iframeOffset.top);
              }

              return false;
          });
      }
  });
});

 

When using this code you must update the text “#ID_OF_MY_IFRAME” with the id that you give the IFrame tag in the parent page.

I create a demo page where you can see the above fix in action.

  • Pingback: JavaScript - Making linking between anchors in an IFrame work in Firefox 4 and above - Matthew Manela - Farblondzshet in Code()

  • matt

    Tried your original code then saw this new link. Neither work. I am using “https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js” for my jQuery in ff12. I am entering the iframe Id that the parent is using for the iframe. Any suggestions?

    • https://www.google.com/accounts/o8/id?id=AItOawlrLeowWytSCscAcNv3ky4tdtP7AcgDAC8 Matthew

      Do you have a site I can look at to see your implementation?

  • matt

    Sorry its behind a firewall and contains not for public prices.

    • https://www.google.com/accounts/o8/id?id=AItOawlrLeowWytSCscAcNv3ky4tdtP7AcgDAC8 Matthew

      If you can create a repro I can check it out.

  • matt

    Untitled Document

    var iframeOffset = $("#iframe1", window.parent.document).offset();
    $("a").each(function () {
    var link = $(this);
    var href = link.attr("href");
    if (href && href[0] == "#") {
    var name = href.substring(1);
    $(this).click(function () {
    var nameElement = $("[name='" + name + "']");
    var idElement = $("#" + name);
    var element = null;
    if (nameElement.length > 0) {
    element = nameElement;
    } else if (idElement.length > 0) {
    element = idElement;
    }

    if (element) {
    var offset = element.offset();
    window.parent.scrollTo(offset.left, offset.top + iframeOffset.top);
    }

    return false;
    });
    }
    });


    Check out specials, promotions, and new offers from: |
    Nike | Rebook | Converse

    • https://www.google.com/accounts/o8/id?id=AItOawlrLeowWytSCscAcNv3ky4tdtP7AcgDAC8 Matthew

      I created a demo page of the code working.

      Let me know if that helps

  • reenign

    Thank you Matthew, it worked flawlessly :)

    @matt: don’t forget to surround the code in $(function() { … });

    • https://www.google.com/accounts/o8/id?id=AItOawlrLeowWytSCscAcNv3ky4tdtP7AcgDAC8 Matthew

      Good catch. I updated the code with your suggestion.

  • John

    is it possible to use something like this if the iframe is on another domain ?

    • https://www.google.com/accounts/o8/id?id=AItOawlrLeowWytSCscAcNv3ky4tdtP7AcgDAC8 Matthew

      I don’t believe so since this would violate the same-origin security restriction.

  • Jeff

    This same problem now exists in IE8.
    Looks like your demo page works though, thanks for the code!

    Shows that FF and chrome are more secure than IE. They fixed this almost a year and a half (Early 2011 vs Mid-June 2012) before it was fixed in IE.

    • https://www.google.com/accounts/o8/id?id=AItOawlrLeowWytSCscAcNv3ky4tdtP7AcgDAC8 Matthew

      That is great. Thanks for letting me know.

  • http://problem Dario

    i have this error in the console:

    Error: Permission denied to access property ‘document’

    • https://www.google.com/accounts/o8/id?id=AItOawlrLeowWytSCscAcNv3ky4tdtP7AcgDAC8 Matthew

      Are you trying to run this code on a site where the iframe is loaded from a different domain than the parent page? That will cause an error.

      • Dario

        yes i do, and that’s exaclty the problem, do you know if there is a solution to work around this issue having the two files on different servers?

        thanks! :)

      • https://www.google.com/accounts/o8/id?id=AItOawlrLeowWytSCscAcNv3ky4tdtP7AcgDAC8 Matthew

        No, there is no way to get around that since it is a browser security feature

  • Usman

    Works great, i have one question though. I have a page in iframe which has a drop down box. Selecting an option from the drop down scrolls you to the required anchor. How do i make your code work for the drop down?

    Offer 1234
    Offer 123

    • Usman

      select name=”cboOnThisPage” onchange=’window.location=this[this.selectedIndex].value;’
      <option selected value=”#1234″>
      Offer 1234 </option>

      • https://www.google.com/accounts/o8/id?id=AItOawlrLeowWytSCscAcNv3ky4tdtP7AcgDAC8 Matthew

        The way the above code works is by using scanning for all anchor links and hooking into onclick event. When you click that anchor it find where you are targeting and uses its offset to scroll the parent page. To make it work in your case you would need to scan for your select control and hook into the onchange event and do the same calculation.

  • Usman

    couldnt make it work

    • https://www.google.com/accounts/o8/id?id=AItOawlrLeowWytSCscAcNv3ky4tdtP7AcgDAC8 Matthew

      Could you give a link to a repro of your issue so I could help?

  • http://www.yosefscabin.com/mountaineermessageboard Kyle McGough

    First – thanks for your efforts. This is an annoying problem to have.

    I can’t seem to get the code working. I’ve inserted the script into my ‘overall_header’ file for phpbb, which is the header that is within the iframe. When going to the FAQ and clicking any of those links, it doesn’t seem to function as I thought it would. Any suggestions?

    Thanks.

  • http://www.yosefscabin.com/mountaineermessageboard Kyle

    Nevermind – got it working.

  • Giuseppe

    It works very good! Thank you for this precious fix.

  • http://www.tomfogarty.com Tom Fogarty

    This is really nice – thanks for sharing!

  • Daniel Bachmann

    Thanks alot for providing me with a working solution when I was just searching IF it is possible :). Have a some internets on me…

    I made some (very) minor changes to the code, so that I can implement it on the site containing the iframe and not in the iframe itself (was the goal from the beginning to not change the original site), for example:
    $(“a”).each(…) becomes $(“#ID_OF_MY_IFRAME”).contents().find(“a”)

    I call it in a function with an timeout together with some code that resizes the iframe, which isn’t pretty but the only solution where I don’t have to add javascript to the contained site.

    Thought someone could be interessted, but anyway thanks again.

    • Daniel Bachmann

      $(“a”).each(…) becomes $(“#ID_OF_MY_IFRAME”).contents().find(“a”).each(…)
      of course

  • Alex

    for facebook apps iframe this will work in chrome (in IE normal jumps works by default)

    function tjump(objid)
    {
    // FB.init({appId:'your_id',status:true,cookie:true,frictionlessRequests:true,oauth:true});
    obj=document.getElementById(objid);
    FB.Canvas.scrollTo(getpos(obj,"offsetLeft"),getpos(obj,"offsetTop"));
    }
    function getpos(w, ot){return (w.offsetParent)? w[ot]+this.getpos(w.offsetParent,ot) : w[ot]}

  • thupten

    awesome..just what i was looking for. will try this. thanks.

  • http://none Emanuel

    So , where I insert this code?
    Sorry for asking but i know only small html thing :D

  • Nassib

    What about if I want to use this script but not in an iframe. Can it be done? I have the following link (www.nhgraphics.com/step) and the side links dont work on Chrome or Safari. Please help. Thanks.

    • https://www.google.com/accounts/o8/id?id=AItOawlrLeowWytSCscAcNv3ky4tdtP7AcgDAC8 Matthew

      The purpose of this code is for an iframe issue.

  • Jose Puentes

    Matthew, thank you very much !

  • Jay Prakash

    Hi Mathew,

    I am trying to implement this. but it did not work in case of iframe within iframe. My page html is:

    my text answer 1

    my text answer 2

    Question 1

    Question 2

    For this I have written following jquery script :

    $(document).ready(function() {
    var iframeOffset = $(“#main-frame”, window.parent.document).offset();
    $(“.question_lists”).live(“click”, function(){
    var id = this.id;
    $(‘div[id^=”student_question_box_”]’).css({‘background':’none’,’border':’none’})
    $(“#student_question_box_”+id).css({‘background':’#ccc’,’margin':’12px 0px’,’border':’2px solid #a3a3a3′,’padding-left':’5px’,’border-radius':’2px’,’width':’100%’,’color':’#111′});

    var idElement = $(“#student_question_box_”+id);
    var element = null;
    if(idElement.length > 0) {
    element = idElement;
    }

    if(element) {
    var offset = element.offset();
    alert(window.parent.scrollTo(offset.left, offset.top + iframeOffset.top));
    }
    return false;

    });
    });

    Can you please tell me where exactly I am making mistake? Actually you have given sample for only one Iframe tag. but what shud I do for page opens in iframe withing iframe?

    Thanks & Regards

    Jay

  • rebecca li

    Matthew,it help me a lot , thank u very much.Fortunately I found this original source code.^_^

  • chris

    Hi Matthew,
    I don’t understand how to use the code, if I paste it as it is (and replacing the ID with mine) it just shows the code on the page as if it was text.
    If I put it in between I get error messages
    what do you have to add for it to work ?

  • chris

    >>If I put it in between I get error messages

    should be : if I out it in between script tags

    • chris

      sorry again,
      should be : if I put it in between script tags I get error messages

  • chris

    And on your demo page you point to, we can see it working, but no clue on how to do the same, there’s nothing in the source code related to it