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.

This entry was posted in Chrome, Firefox, JavaScript. Bookmark the permalink.

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

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

  2. matt says:

    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?

  3. matt says:

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

  4. matt says:

    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

  5. reenign says:

    Thank you Matthew, it worked flawlessly :)

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

  6. John says:

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

  7. Jeff says:

    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.

  8. Dario says:

    i have this error in the console:

    Error: Permission denied to access property ‘document’

    • Matthew says:

      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 says:

        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! :)

      • Matthew says:

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

  9. Usman says:

    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 says:

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

      • Matthew says:

        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.

  10. Usman says:

    couldnt make it work

  11. Kyle McGough says:

    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.

  12. Kyle says:

    Nevermind – got it working.

  13. Giuseppe says:

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

  14. Tom Fogarty says:

    This is really nice – thanks for sharing!

  15. Daniel Bachmann says:

    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.

  16. Alex says:

    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]}

  17. thupten says:

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

  18. Emanuel says:

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

  19. Nassib says:

    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.

  20. Jose Puentes says:

    Matthew, thank you very much !

  21. Jay Prakash says:

    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

  22. rebecca li says:

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

  23. chris says:

    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 ?

  24. chris says:

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

    should be : if I out it in between script tags

  25. chris says:

    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

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>