Since I previously maintained several older projects that were developed using jquery family buckets, some of the requirements required cross-page interaction and parent-child page communication, I would like to summarize this. The other is the front-end file download function, although there are many methods, in order not to repeat the wheel, here is a summary of a wave, after all, the multi page application scenario is still a lot of.

The article based on

  • Methods to achieve communication between pages
  • Realization of the parent page and child page and child page communication between the method
  • The front-end implements file download function

Since this article is mainly based on javascript and does not involve any framework issues (you can move on to my other articles if you want to explore vue, React, and Angular technical issues), let’s use native javascript to solve the problems we mentioned above.

The body of the

1. The method of realizing the communication between pages

Although we can use PostMessage for page communication, we mainly use the window.opener API, which MDN explains as follows:

The Window interface’s opener property returns a reference to the window that opened the window using open().

In other words, if page A opens page B, then page B’s opener returns A. In this way, we can define global methods on page A and mount them on window, so page B can get the methods of page A through Opener and control the behavior of page A.

The current major browsers have good support for this API, so consider using it in most scenarios.

In order to understand its application scenario more easily, we implement A small function here: we define two pages, A, B, when A opens B page, using B page to change the background color of A page. The code is as follows:

/ / A page<body>
    <h1>The parent page A</h1>
    <a href="./b.html" target="_blank">Open page B</a>
    <script>
        function changeColor(color) {
            document.body.style.background = color
        }
    </script>
</body>/ / B page<body>
    <h1>The parent page B</h1>
    <script>
        window.opener.changeColor('blue')
    </script>
</body>
Copy the code

First, we define A global method in page A. When clicking A tag to jump to the newly opened page B, page B will call changeColor defined by A through Opener and pass parameters to page A, so as to change the background color of page A. The effect is as follows:

2. Realize the communication method between the parent and child pages and child pages

Parent and child pages This section mainly refers to the iframe, that is, the communication between the iframe and the parent page and the iframe page. For example:

  • contentWindow
  • The contentWindow allows you to access the methods and DOM elements inside the iframe to manipulate the iframe page

First, let’s look at A scenario where the parent page controls the child page: The parent page A calls A method on the child page to pass A piece of data and displays it in the child page:

/ / the parent page
window.onload = function() {
    let iframe1 = $id('a1').contentWindow;
    // Control the subpage DOM
    iframe1.document.body.style.background = "# 000"
    iframe1.loadData({a: '1'})}function $id(id) {
    return document.getElementById(id)
}

/ / child pages
function loadData(data) {
    document.body.append('Parent page data data${data.a}`)}Copy the code

The parent page gets the Iframe window object through the contentWindow and passes data to it and calls its methods.

Similarly, a child page can manipulate a parent page:

/ / the parent page
function $id(id) {
    return document.getElementById(id)
}
/ / child pages
parent.window.$id('bridge').innerHTML = 'Child page controls parent page DOM'
Copy the code

As you can see from the code, we use parent-. window to get the parent page window, and then call the parent page provided by the $ID method to manipulate the parent page DOM.

Next, let’s solve the problem of communication between child pages and child pages. In fact, the method mentioned above, we can use the parent page as A bridge, child page A gets the parent page window through parent-. window, and then can get the DOM of another child page B. In this way, we can let child page A operate child page B. The reverse is also true.

// Subpage A
let iframeBWin = parent.window.$id('a2').contentWindow
iframeBWin.onload = function() {
    iframeBWin.document.getElementById('show').innerHTML = "Greetings from subpage A"
}
Copy the code

As we can see from the above code, we can communicate with the child page B by using the parent. Window. In this way, we can achieve a lot of interesting things.

Note that all of the methods we discussed are based on the same domain, but there are many ways to implement cross-domain, such as using intermediate iframe to bridge, setting window.domain to raise the window to the top level, etc., but it is a little bit difficult to implement, but can be used in most scenarios.

4. Download files on the front end

For download files, most of the scene is the back-end, front end only need to request interface, but sometimes this way it will take up extra resources and bandwidth, if need to download the content or user generated content has returned to the client, this time can not download task generated directly after the service side, It saves a lot of resources and time.

Generally, the idea is to dynamically create a tag, set its download property, and then delete a. You can always download a file that is not an image, but if it is an image, some browsers will automatically open the image, so you need to manually convert it to data:URLs or blob:URLs. Based on this principle, we can either use fileReader or fetch- url.createObjecturl, which I used after a lot of testing:

function download(url, filename) {
    return fetch(url).then(res= > res.blob().then(blob= > {
        let a = document.createElement('a');
        let url = window.URL.createObjectURL(blob);
        a.href = url;
        a.download = filename;
        a.click();
        window.URL.revokeObjectURL(url); }}))Copy the code

This method passes in the address of the file and the desired file name, so that we can use it elegantly for downloading.

The last

Since I am currently writing an open source CMS, technical architecture:

  • Background the Node + Koa + + JsonSchema redis
  • Manage the background interface vue-CLI3 + vue + TS + vuex + ANTD -vue + AXIos
  • React + ANTD + React-hooks + AXIos

The design idea, architecture and implementation process of the system will be introduced later. Welcome to see a more detailed introduction in the public account “Interesting Talk Front end”.

Welcome to learn from each other and explore the frontiers of the front end.

More recommended

  • How to draw a tree of structures recursively in Javascript
  • Write a mock data server using nodeJS in 5 minutes
  • Cartesian product is implemented and applied in javascript
  • JavaScript binary tree and binary search tree implementation and application
  • With JavaScript and C3 to achieve a turntable small game
  • Teach you to use 200 lines of code to write a love bean spell H5 small game (with source code)
  • Exploration and summary of front-end integrated solutions based on React/VUE ecology
  • How to use gulP4 development project scaffolding
  • How to write your own JS library in less than 200 lines of code
  • A summary of common JS functions that make you more productive in an instant
  • A picture shows you how to play vue-Cli3 quickly
  • 3 minutes teach you to use native JS implementation with progress listening file upload preview component
  • 3 minutes teach you to use native JS implementation with progress listening file upload preview component
  • Developing travel List with Angular8 and Baidu Maps API
  • Js basic search algorithm implementation and 1.7 million data under the performance test
  • How to make front-end code 60 times faster
  • Front End Algorithm series array deweighting
  • Vue Advanced Advanced series – Play with Vue and vuex in typescript
  • In the first three years, talk about the top five books worth reading