document.createElement("script")和window.onload执行顺序
时间: 2023-07-24 19:10:56 浏览: 34
在一般情况下,使用document.createElement("script")创建的<script>元素是异步加载的,并且不会阻塞页面的加载和渲染过程。而window.onload事件是在页面的所有资源(包括脚本、样式表、图片等)都加载完成后触发的。
因此,如果在window.onload事件中动态创建并加载脚本,那么这个脚本将在页面的所有资源加载完成后再执行。但是,如果在window.onload事件之前使用document.createElement("script")创建并加载脚本,那么这个脚本可能会在页面的加载过程中被执行,而不是等到所有资源加载完成后再执行。
总结起来,使用document.createElement("script")创建的脚本元素是异步加载的,它的执行时间取决于脚本的加载速度和页面的加载进度。而window.onload事件则是在所有资源都加载完成后触发的,可以确保页面完全加载后再执行相应的逻辑。
相关问题
const print = () => { if (!baseInfo.orderCode) { message.error("打印正在准备,请5秒后再点击") return } const el = document.getElementById("print-container") const iframe = document.createElement("IFRAME") let doc = null // iframe.setAttribute('style', 'position:absolute;top:0px;left:0px;width:100%;height:100%',); document.body.appendChild(iframe) doc = iframe.contentWindow.document // 引入打印的专有CSS样式,根据实际修改 doc.write(`<LINK rel="stylesheet" type="text/css" href="./orderPrint.css">`) doc.write(el.innerHTML) doc.close() // 获取iframe的焦点,从iframe开始打印 iframe.contentWindow.focus() iframe.onload = () => { iframe.contentWindow.print() document.body.removeChild(iframe) } if (navigator.userAgent.indexOf("MSIE") > 0) { document.body.removeChild(iframe) } const old = window.document.body.innerHTML const printPart = document.getElementById("print-container") window.document.body.innerHTML = "" window.document.body.appendChild(printPart) window.print() window.document.body.innerHTML = old window.location.reload() }优化这段代码
这段代码可以进行如下的优化:
1. 避免在函数内部操作 DOM,最好将其作为参数传递进来,这样可以提高代码的可重用性和可维护性。
```javascript
const print = (elId, cssUrl) => {
const el = document.getElementById(elId)
if (!el) {
message.error("找不到打印内容,请检查elId")
return
}
if (!baseInfo.orderCode) {
message.error("打印正在准备,请5秒后再点击")
return
}
const iframe = document.createElement("IFRAME")
document.body.appendChild(iframe)
const doc = iframe.contentWindow.document
doc.write(`<LINK rel="stylesheet" type="text/css" href="${cssUrl}">`)
doc.write(el.innerHTML)
doc.close()
iframe.contentWindow.focus()
iframe.onload = () => {
iframe.contentWindow.print()
document.body.removeChild(iframe)
}
if (navigator.userAgent.indexOf("MSIE") > 0) {
document.body.removeChild(iframe)
}
}
```
2. 将打印的专有CSS样式和打印的内容分开处理,以便更好地维护和修改样式。
```javascript
const print = (elId, cssUrl, printContent) => {
const el = document.getElementById(elId)
if (!el) {
message.error("找不到打印内容,请检查elId")
return
}
if (!baseInfo.orderCode) {
message.error("打印正在准备,请5秒后再点击")
return
}
const iframe = document.createElement("IFRAME")
document.body.appendChild(iframe)
const doc = iframe.contentWindow.document
const link = document.createElement("link")
link.rel = "stylesheet"
link.type = "text/css"
link.href = cssUrl
doc.head.appendChild(link)
doc.body.innerHTML = printContent || el.innerHTML
iframe.contentWindow.focus()
iframe.onload = () => {
iframe.contentWindow.print()
document.body.removeChild(iframe)
}
if (navigator.userAgent.indexOf("MSIE") > 0) {
document.body.removeChild(iframe)
}
}
```
3. 将打印内容从 DOM 中分离出来,以便在不同的场合下方便地调用。
```javascript
const printContent = (elId) => {
const el = document.getElementById(elId)
if (!el) {
message.error("找不到打印内容,请检查elId")
return ""
}
return el.innerHTML
}
const print = (elId, cssUrl, printContent) => {
if (!baseInfo.orderCode) {
message.error("打印正在准备,请5秒后再点击")
return
}
const iframe = document.createElement("IFRAME")
document.body.appendChild(iframe)
const doc = iframe.contentWindow.document
const link = document.createElement("link")
link.rel = "stylesheet"
link.type = "text/css"
link.href = cssUrl
doc.head.appendChild(link)
doc.body.innerHTML = printContent || printContent(elId)
iframe.contentWindow.focus()
iframe.onload = () => {
iframe.contentWindow.print()
document.body.removeChild(iframe)
}
if (navigator.userAgent.indexOf("MSIE") > 0) {
document.body.removeChild(iframe)
}
}
```
let myChart export default { mounted() { if (typeof window.echarts === 'function') { this.initEcharts() } else { // 动态引入较大类库避免影响页面展示 const script = document.createElement('script') // view 层的页面运行在 www 根目录,其相对路径相对于 www 计算 script.src = 'static/echarts.js' script.onload = this.initEcharts.bind(this) document.head.appendChild(script) } }, methods: { initEcharts() { myChart = echarts.init(document.getElementById('echarts')) // 观测更新的数据在 view 层可以直接访问到 myChart.setOption(this.option) }, updateEcharts(newValue, oldValue, ownerInstance, instance) { // 监听 service 层数据变更 myChart.setOption(newValue) }, onClick(event, ownerInstance) { // 调用 service 层的方法 ownerInstance.callMethod('onViewClick', { test: 'test' }) } } } 这个程序发生了报错:Cannot read property '0' of undefined,请说明原因,和修改建议
这个错误可能是因为在初始化 chart 之前,没有正确地设置 option 属性。建议添加一个判断,在调用 setOption 之前先确保 option 已经被正确设置。修改后的代码如下:
```
let myChart
export default {
mounted() {
if (typeof window.echarts === 'function') {
this.initEcharts()
} else {
// 动态引入较大类库避免影响页面展示
const script = document.createElement('script')
// view 层的页面运行在 www 根目录,其相对路径相对于 www 计算
script.src = 'static/echarts.js'
script.onload = this.initEcharts.bind(this)
document.head.appendChild(script)
}
},
methods: {
initEcharts() {
myChart = echarts.init(document.getElementById('echarts'))
// 确保 option 已经被正确设置
if (this.option) {
myChart.setOption(this.option)
}
},
updateEcharts(newValue, oldValue, ownerInstance, instance) {
// 监听 service 层数据变更
myChart.setOption(newValue)
},
onClick(event, ownerInstance) {
// 调用 service 层的方法
ownerInstance.callMethod('onViewClick', {
test: 'test'
})
}
}
}
```
另外,建议在组件销毁时,调用 `myChart.dispose()` 方法来销毁 chart 实例,以避免内存泄漏。