一般瀏覽器先加載主頁(yè),再請(qǐng)求關(guān)聯(lián)的js腳本文件。不管你把js代碼嵌入在html中,還是獨(dú)立保存為一個(gè)文件,都必須等待主頁(yè)加載完成,js代碼加載完成后才能執(zhí)行。網(wǎng)上有人說(shuō)把js代碼放在head里面,其實(shí)這樣并不影響腳本執(zhí)行時(shí)機(jī)。因?yàn)閖s或html還沒(méi)有加載,何談執(zhí)行js代碼。先看一下頁(yè)面加載資源的順序
瀏覽器加載頁(yè)面資源順序
再簡(jiǎn)單分析一下onload事件的執(zhí)行時(shí)機(jī)。
Document.onload
它是在結(jié)構(gòu)和樣式加載完才執(zhí)行js。【就是在html和css都完事以后才執(zhí)行】
Window.onload
它不僅僅要在結(jié)構(gòu)和樣式加載完,還要執(zhí)行完所有的樣式、圖片這些資源文件,全部加載完才會(huì)觸發(fā)window.onload事件。
jquery中的ready
指定在DOM完全加載時(shí)要執(zhí)行的函數(shù)。
也許你又會(huì)想到,先執(zhí)行JAVAScript,再打開(kāi)頁(yè)面可以嗎?答案是否定的,因?yàn)閳?zhí)行完JavaScript后,執(zhí)行結(jié)果保存在變量中,當(dāng)打開(kāi)一個(gè)新的頁(yè)面時(shí),js變量會(huì)被清空。
有什么方法在頁(yè)面加載前就執(zhí)行js代碼呢,單從網(wǎng)頁(yè)來(lái)考慮似乎無(wú)解,那就需要從瀏覽器端入手。當(dāng)輸入網(wǎng)址或點(diǎn)擊鏈接導(dǎo)致需要加載另一個(gè)頁(yè)面前就執(zhí)行js代碼(注意只是準(zhǔn)備加載頁(yè)面,還沒(méi)有下載一個(gè)字符)。這樣做可以在頁(yè)面加載前先給某些變量賦值,且這個(gè)變量值在頁(yè)面加載完成后不會(huì)消失。
打開(kāi)木頭瀏覽器的項(xiàng)目管理窗口,創(chuàng)建一個(gè)腳本代碼步驟,并輸入需要執(zhí)行的JavaScript代碼,選擇代碼執(zhí)行時(shí)機(jī)為“頁(yè)面加載前執(zhí)行”,保存這個(gè)項(xiàng)目后,只要執(zhí)行一次這個(gè)項(xiàng)目(點(diǎn)擊測(cè)試也可以),在瀏覽器中打開(kāi)任何網(wǎng)址時(shí),都會(huì)先執(zhí)行這段JavaScript代碼。如下圖所示,為方便體驗(yàn)具體效果,設(shè)置一個(gè)彈窗代碼在頁(yè)面加載前執(zhí)行。
加載頁(yè)面前執(zhí)行腳本
然后在瀏覽器中輸入打開(kāi)一個(gè)網(wǎng)址,此時(shí)頁(yè)面還沒(méi)有加載,就彈出了窗口。由于是模態(tài)彈窗,只有點(diǎn)擊確定后才會(huì)繼續(xù)加載頁(yè)面內(nèi)容。頁(yè)面加載完成后,js變量值亦不會(huì)丟失。
執(zhí)行時(shí)機(jī)測(cè)試
如果需要停止在頁(yè)面加載前執(zhí)行腳本代碼,只需要再添加一個(gè)腳本代碼步驟,代碼為空,設(shè)置執(zhí)行時(shí)機(jī)為“停止加載前執(zhí)行”。當(dāng)此步驟執(zhí)行一次后,在瀏覽器打開(kāi)網(wǎng)頁(yè)就不會(huì)再執(zhí)行腳本代碼彈出窗口了。
停止加載前執(zhí)行腳本
網(wǎng)頁(yè)加載前注入執(zhí)行JavaScript腳本,具體有什么作用呢?可以用于改變系統(tǒng)環(huán)境參數(shù),比如修改屏幕分辨率;執(zhí)行如下代碼后,網(wǎng)頁(yè)獲取分辨率時(shí)將得到預(yù)設(shè)值而非實(shí)際分辨率。
- screen.width = 1024;
- screen.height = 768;
- screen.availWidth = 1024;
- screen.availHeight =768;
- screen.availablewidth =1024;
- screen.availableheight =768;
還可以修改系統(tǒng)函數(shù),替換函數(shù)功能。比如把下面這段代碼放在頁(yè)面加載前執(zhí)行,改變系統(tǒng)的alert函數(shù)功能,那么此頁(yè)面再執(zhí)行alert就不會(huì)彈出窗口了。
- window.alert=function(txt){
- return txt;
某些網(wǎng)站通過(guò)JavaScript功能函數(shù)采集“瀏覽器指紋”,同樣可以通過(guò)修改功能函數(shù),避免被網(wǎng)站跟蹤。比如在頁(yè)面加載前執(zhí)行以下代碼,自動(dòng)給canvas畫(huà)布指紋添加變化的噪聲,導(dǎo)致頁(yè)面每次獲取的“瀏覽器指紋”都不一樣。
- var inject = function () {
- const toBlob = HTMLCanvasElement.prototype.toBlob;
- const toDataURL = HTMLCanvasElement.prototype.toDataURL;
- const getImageData = CanvasRenderingContext2D.prototype.getImageData;
- var noisify = function (canvas, context) {
- if (context) {
- const shift = {
- 'r': Math.floor(Math.random() * 10) - 5,
- 'g': Math.floor(Math.random() * 10) - 5,
- 'b': Math.floor(Math.random() * 10) - 5,
- 'a': Math.floor(Math.random() * 10) - 5
- const width = canvas.width;
- const height = canvas.height;
- if (width && height) {
- const imageData = getImageData.Apply(context, [0, 0, width, height]);
- for (let i = 0; i < height; i++) {
- for (let j = 0; j < width; j++) {
- const n = ((i * (width * 4)) + (j * 4));
- imageData.data[n + 0] = imageData.data[n + 0] + shift.r;
- imageData.data[n + 1] = imageData.data[n + 1] + shift.g;
- imageData.data[n + 2] = imageData.data[n + 2] + shift.b;
- imageData.data[n + 3] = imageData.data[n + 3] + shift.a;
- window.top.postMessage("canvas-fingerprint-defender-alert", '*');
- context.putImageData(imageData, 0, 0);
- Object.defineProperty(HTMLCanvasElement.prototype, "toBlob", {
- "value": function () {
- noisify(this, this.getContext("2d"));
- return toBlob.apply(this, arguments);
- Object.defineProperty(HTMLCanvasElement.prototype, "toDataURL", {
- "value": function () {
- noisify(this, this.getContext("2d"));
- return toDataURL.apply(this, arguments);
- Object.defineProperty(CanvasRenderingContext2D.prototype, "getImageData", {
- "value": function () {
- noisify(this.canvas, this);
- return getImageData.apply(this, arguments);
- document.documentElement.dataset.cbscriptallow = true;
- inject();