javascript - Change a parent window's URL using history pushState when link in Iframe is clicked - Stack Overflow

I have a page that has a header and sidebar with a right content panel that is an Iframe.In a page load

I have a page that has a header and sidebar with a right content panel that is an Iframe.

In a page loaded into the right content panel, I am trying to have a clicked link update the Browser URL in the parent window to the URL of the new page that is loaded into the Iframe.

I do not want the actual parent window to reload the URL but simply to update the URL in the address bar.

Something like:

window.history.pushState('obj', 'newtitle', '/bookmarks/list/');

Is this possible from an Iframe?

I have a page that has a header and sidebar with a right content panel that is an Iframe.

In a page loaded into the right content panel, I am trying to have a clicked link update the Browser URL in the parent window to the URL of the new page that is loaded into the Iframe.

I do not want the actual parent window to reload the URL but simply to update the URL in the address bar.

Something like:

window.history.pushState('obj', 'newtitle', '/bookmarks/list/');

Is this possible from an Iframe?

Share Improve this question edited Feb 20, 2016 at 5:58 Andrew Myers 2,7865 gold badges35 silver badges41 bronze badges asked Feb 20, 2016 at 3:28 JasonDavisJasonDavis 49k107 gold badges326 silver badges559 bronze badges 5
  • "Is this possibble from an Iframe?" Have you tried this approach ? – guest271314 Commented Feb 20, 2016 at 3:37
  • @guest271314 I have tried it, it updated the URL of the Iframe, so my iframe loaded a new page and had the new URL but the parent URL never changed – JasonDavis Commented Feb 20, 2016 at 3:44
  • 1 I think I will try using the ifram onmessage events to send new url to parent from iframe and in the parent page, call the window.history.pushState from parent and see if that will do the magick – JasonDavis Commented Feb 20, 2016 at 3:48
  • See stackoverflow./questions/33645685/… – guest271314 Commented Feb 20, 2016 at 3:54
  • @guest271314 that post is to change the content of a page. I need to update the URL without reloading the page. THe idea posted above worked though. Using post message my parent receive the URL and then send a pushState to update the parent URL – JasonDavis Commented Feb 20, 2016 at 4:07
Add a ment  | 

2 Answers 2

Reset to default 3

I was able to acplish updating the parent windows URL in the address bar using history.pushState by sending the new URL to the parent from the child Iframe window using postMessage and on the parent window listening for this event.

WHen the parent receives the child iframes postMessage event, it updates the URL with pushSTate using the URL passed in that message.

Child Iframe

<script>
// Detect if this page is loaded inside an Iframe window
function inIframe() {
    try {
        return window.self !== window.top;
    } catch (e) {
        return true;
    }
}

// Detect if the CTRL key is pressed to be used when CTRL+Clicking a link
$(document).keydown(function(event){
    if(event.which=="17")
        cntrlIsPressed = true;
});
$(document).keyup(function(){
    cntrlIsPressed = false;
});
var cntrlIsPressed = false;

// check if page is loaded inside an Iframe?
if(inIframe()){
    // is the CTRL key pressed?
    if(cntrlIsPressed){
        // CTRL key is pressed, so link will open in a new tab/window so no need to append the URL of the link
    }else{

        // click even on links that are clicked without the CTRL key pressed
        $('a').on('click', function() {

            // is this link local on the same domain as this page is?
            if( window.location.hostname === this.hostname ) {

                // new URL with ?sidebar=no appended to the URL of local links that are clicked on inside of an iframe
                var linkUrl = $(this).attr('href');
                var noSidebarUrl = $(this).attr('href')+'?sidebar=no';

                // send URL to parent window
                parent.window.postMessage('message-for-parent=' +linkUrl , '*');

                alert('load URL with no sidebar: '+noSidebarUrl+' and update URL in arent window to: '+linkUrl);

                // load Iframe with clicked on URL content
                //document.location.href = url;
                //return false;
            }
        });
    }
}
</script>

Parent window

<script>

// parent_on_message(e) will handle the reception of postMessages (a.k.a. cross-document messaging or XDM).
function parent_on_message(e) {
    // You really should check origin for security reasons
    // https://developer.mozilla/en-US/docs/DOM/window.postMessage#Security_concerns
    //if (e.origin.search(/^http[s]?:\/\/.*\.localhost/) != -1
    //    && !($.browser.msie && $.browser.version <= 7)) {
        var returned_pair = e.data.split('=');
        if (returned_pair.length != 2){
            return;
        }
        if (returned_pair[0] === 'message-for-parent') {
            alert(returned_pair[1]);
            window.history.pushState('obj', 'newtitle', returned_pair[1]);
        }else{
            console.log("Parent received invalid message");
        }

    //}
}

jQuery(document).ready(function($) {
    // Setup XDM listener (except for IE < 8)
    if (!($.browser.msie && $.browser.version <= 7)) {
        // Connect the parent_on_message(e) handler function to the receive postMessage event
        if (window.addEventListener){
            window.addEventListener("message", parent_on_message, false);
        }else{
            window.attachEvent("onmessage", parent_on_message);
        }
    }
});
</script>

Another solution using Window.postMessage().

Iframe:

<a href="/test">/test</a>
<a href="/test2">/test2</a>

<script>
Array.from(document.querySelectorAll('a')).forEach(el => {
  el.addEventListener('click', event => {
    event.preventDefault();
    window.parent.postMessage(this.href, '*');
  });
});
</script>

Main page:

Current URL: <div id="current-url"></div>
<iframe src="iframe-url"></iframe>

<script>
const $currentUrl = document.querySelector('#current-url');
$currentUrl.textContent = location.href;

window.addEventListener('message', event => {
  history.pushState(null, null, event.data);
  $currentUrl.textContent = event.data;
});
</script>

See demo on JS Fiddle.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744220283a4563749.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信