Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

anchor links in page #68

Closed
beardedgeek opened this issue Jun 30, 2014 · 19 comments
Closed

anchor links in page #68

beardedgeek opened this issue Jun 30, 2014 · 19 comments

Comments

@beardedgeek
Copy link

Thanks for such a great script. It's working great apart from one tiny issue that I'm hoping is my config rather than it not working.

I'm embedding a mediawiki application within a page which creates a table of contents at the top. The TOC has a load of in page anchor links to content lower down the page, however when I click on one of the links it doesn't scroll down to focus it.

@davidjbradshaw
Copy link
Owner

The problem is that you need to scroll the parent frame, not the child.

So you have to write script to to workout the position and send a message
to the host page and then have that scroll.

I have been working on a parentIFrame.scrollTo() function to help with
this, currently it is undocumented as I need to find some time to add some
tests for it, but give it a go and let me know how you get on with it.

On Monday, June 30, 2014, Huw Davies [email protected] wrote:

Thanks for such a great script. It's working great apart from one tiny
issue that I'm hoping is my config rather than it not working.

I'm embedding a mediawiki application within a page which creates a table
of contents at the top. The TOC has a load of in page anchor links to
content lower down the page, however when I click on one of the links it
doesn't scroll down to focus it.


Reply to this email directly or view it on GitHub
#68.

David J. Bradshaw )'( [email protected]

'The people we think are a little weird are the ones who change the world'

  • Simon Sinek

@mhulse
Copy link

mhulse commented Nov 1, 2014

Just for future readers, below is basically one way to get anchor links working (only tested, so far, on mac/Firefox).

Put on iframe page:

$(function() {

    $('a').click(function($e) {

        var $this = $(this);
        var href;

        if ('parentIFrame' in window) { // I only want to do this on parent pages that have enablePublicMethods turned on; this will allow me to use iframe on target and external pages.

            $e.preventDefault();
            $e.stopPropagation();

            $this.blur();

            href = $this.attr('href');

            //console.log(href.substring(href.indexOf('#') + 1));

            window.parentIFrame.sendMessage(href.substring(href.indexOf('#')));

        }

    });

});

On the parent:

(function() {

    var $attn = $('#attn').iFrameResize({
        enablePublicMethods: true,
        messageCallback: function (obj) {

            //console.log(obj.message);

            $.smoothScroll({
                scrollTarget: obj.message
            });

        }
    });

})();

The above uses Smooth Scroll Plugin.

@letmaik
Copy link

letmaik commented Nov 3, 2014

@davidjbradshaw Shouldn't there be some kind of check in the iframe page part whether if its really an anchor on the same page and not a regular link?

@davidjbradshaw
Copy link
Owner

@neothemachine anchor links are a real edge case and it's not clear how you would tell if an anchor referenced the parent page.

I think that @mhulse has the best solution for this, although as a simple example I'd cut it down to this.

$('a=[href^=#]').click(function(e) {
    if ('parentIFrame' in window) {
        var href = $(this).blur().attr('href');
        e.preventDefault();
        window.parentIFrame.sendMessage(href.substring(href.indexOf('#')));
    }
});

and

iFrameResize({
    enablePublicMethods: true,
    messageCallback: function (obj) {
        location.href = obj.message;
    }
});

Will add this to the docs when I get time to test.

@letmaik
Copy link

letmaik commented Nov 3, 2014

@davidjbradshaw Thanks for this. Are you sure your expression is right? It says Syntax error, unrecognized expression: a=[href=^=#].

EDIT: I think it should be a[href^=#].

@davidjbradshaw
Copy link
Owner

Yep. Have fixed above.

@letmaik
Copy link

letmaik commented Nov 3, 2014

Hm, actually it doesn't even work manually for me. So when I append #anchor to the address in the browser and hit enter nothing happens. Maybe that's why @mhulse used the smooth scroll plugin.

@davidjbradshaw
Copy link
Owner

Like I said, not tested it. Not sure how you move to an anchor in JS, I'd suggest looking at the location object on MDN. Let me know what you find out.

@letmaik
Copy link

letmaik commented Nov 3, 2014

I think it doesn't work that way because at least Chrome separates the anchors for both pages and you cannot use the iframe anchors from the parent page (maybe Firefox as tested by @mhulse has less restrictions on that). So I guess for this to work you have to determine the scroll position within the iframe page and send this number as a message to the parent, and the parent then scrolls to that position plus the iframe offset.

@letmaik
Copy link

letmaik commented Nov 3, 2014

Ok, this is my current working approach:

On the iframe:

    $(function() {
        $('a[href^=#]').click(function(e) {
            if ('parentIFrame' in window) {
                var href = $(this).blur().attr('href');
                var anchor = $('a[name=' + href.substring(1) + ']');
                var offset = Math.round(anchor.offset().top);
                e.preventDefault();
                window.parentIFrame.sendMessage(offset);
            }
        });
    });

On the parent page:

iFrameResize({
        enablePublicMethods: true,
        messageCallback: function (obj) {
            window.scrollTo(0, obj.message);
        }
    });

I didn't add the iframe offset yet as this is not an issue for me (offset is quite small) but that should be trivial.

@mhulse
Copy link

mhulse commented Nov 3, 2014

It's great to see other examples. Thanks for sharing codes!

Btw, this is an awesome plugin. I can't wait to use it for other projects. 👍 :octocat:

@davidjbradshaw
Copy link
Owner

I've started work on a more complete solution to this problem. Aim is to support the following.

Scroll to anchor in iFrame
If not found in iframe, scroll to anchor in host page
Scroll to anchor on page load in iFrame
Automatic support for <a href="#name">
JS call parentIFrame.scrollToId()
Observe window.onhashchange event.
scrollCallback() method to allow callout to fancy scrolling functions

Can you think of anything else that might be needed?

Work in progress can found here.
https://github.com/davidjbradshaw/iframe-resizer/tree/anchorLinks

@davidjbradshaw davidjbradshaw reopened this Dec 4, 2014
@davidjbradshaw davidjbradshaw changed the title anchor links in page not working anchor links in page Dec 4, 2014
@letmaik
Copy link

letmaik commented Dec 6, 2014

I think this covers most use cases. Can't think of anything else. One (unrelated) thing that annoys me though is when I navigate within the iframe and then press the browser back button I'm back at the top of the page and not where I was.

@davidjbradshaw
Copy link
Owner

Might be able to fix that via window.onhashchange. It's on my list.

On Saturday, December 6, 2014, Maik Riechert [email protected]
wrote:

I think this covers most use cases. Can't think of anything else. One
(unrelated) thing that annoys me though is when I navigate within the
iframe and then press the browser back button I'm back at the top of the
page and not where I was.


Reply to this email directly or view it on GitHub
#68 (comment)
.

Sent from my iPhone.

@davidjbradshaw
Copy link
Owner

Just released version v2.8.0 with support for In Page Anchor links. The code now intercepts these in the iFrame and reposition the parent page. Both html links and JS calls to the location object are intercepted.

It will first look for an anchor in the iframe and if it is not found it will bubble up through nested parent pages until it finds the correct link.

I've also added a new scrollCallback function that allows you to hook in your own code for animated scrolling.

This works with in page links and also the parentIFrame.scrollTo() and parentIFrame.scrollToOffset() methods.

@lucaswxp
Copy link

lucaswxp commented Feb 2, 2017

Hey guys.

Anchor scrolling is not working for me, is this still valid today?

I'm using angular and the html anchors are created dynamically, could this be it?

@davidjbradshaw
Copy link
Owner

Yep take a look at the example. If it is an Angular issue you would be better asking on StackOverflow.

@LukeLeber
Copy link

Just pointing out that there are major accessibility problems with the approaches in this issue.

Simply using javascript to scroll the viewport to a new place on the page is not an inclusive solution.

@davidjbradshaw
Copy link
Owner

@LukeLeber that is a fair point. Would you like to raise a PR? Or create an accessibility issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants