那些不常見,但卻很是實用的js知識(整理不易)

1、window

window 對象表示一個包含 DOM 文檔的窗口,其 document 屬性指向窗口中載入的 DOM 文檔 。css

一、window 屬性和方法

在有標籤頁功能的瀏覽器中,每一個標籤都擁有本身的 window 對象;也就是說,同一個窗口的標籤頁之間不會共享一個 window 對象。html

1.一、幾個瀏覽器的高度

window.screen.height==window.screen.availHeight
表示手機的屏幕高度,在一部手機中是固定的。不一樣瀏覽器打開,都不會變。vue

window.innerHeight==document.documentElement.clientHeight
表示瀏覽器中,除去頂部地址欄,下部工具欄以外,暴露給用戶,能夠看的見的中間區域。也就是實際的網頁瀏覽高度,不一樣瀏覽器不一樣。web

document.body.clientHeight
body 元素的高度。
若是設置 body 的 height:30px; 那麼這個屬性就是 30。canvas

下面是示意圖,在 pc 端同理
imagesegmentfault

1.二、window.performance

Web Performance API 容許網頁訪問某些函數來測量網頁和 Web 應用程序的性能,包括 Navigation Timing API 和高分辨率時間數據。瀏覽器

performance.now()

該方法返回一個 DOMHighResTimeStamp 對象,該對象表示從某一時刻(譯者注:某一時刻一般是 navigationStart 事件發生時刻)到調用該方法時刻的毫秒數。網絡

image

1.三、devicePixelRatio

返回當前顯示設備的物理像素分辨率與 CSS 像素分辨率之比。dom

物理像素分辨率表示,你的電腦的硬件部分,在出場時,已經肯定。異步

而 css 像素分辨率,則能夠動態調整。
當電腦顯示設置爲 100%時,物理像素分辨率和 css 像素分辨率是相等的。即 devicePixelRatio 爲 1

window.devicePixelRatio   //1

image

而若是你將電腦設置爲 150%;或者在電腦設置 100%時,同時將瀏覽器分辨率調成 150%,那麼 devicePixelRatio 都爲 1.5
image

image

window.devicePixelRatio   //1.5

你能夠將 devicePixelRatio 爲 1.5 理解爲,1px 的 css 樣式,佔用了電腦硬件屏幕分辨路的 1.5 個 dpi,因此肉眼看起來電腦上的文字更大些。

這種放大的效果在某些狀況下,會致使 html 中的元素失真,典型的即是 canvas 變得模糊。

下面是矯正代碼

//size爲本來的大小
let scale = window.devicePixelRatio;
canvas.width = Math.floor(size * scale);
canvas.height = Math.floor(size * scale);

image

1.四、base64 編碼/解碼
window.btoa() 編碼爲 base64

window.atob() 解碼

let encodedData = window.btoa("Hello, world"); // 編碼
let decodedData = window.atob(encodedData);    // 解碼

image

1.五、requestAnimationFrame / cancelAnimationFrame()

window.requestAnimationFrame() 告訴瀏覽器——你但願執行一個動畫,而且要求瀏覽器在下次重繪以前調用指定的回調函數更新動畫。

回調函數執行次數一般是每秒 60 次,但在大多數遵循 W3C 建議的瀏覽器中,回調函數執行次數一般與瀏覽器屏幕刷新次數相匹配。可是卻和 setInterval(),不一樣,由於 setInterval 設置的秒,並不必定準確在對應秒後執行,而是須要看是否有其餘資源在執行,若是有,則等待。實際可能大於等於設置的秒數,而 requestAnimationFrame 會準確的按照瀏覽器渲染的頻率想匹配

//兼容性處理
var requestAnimationFrame =
  window.requestAnimationFrame ||
  window.mozRequestAnimationFrame ||
  window.webkitRequestAnimationFrame ||
  window.msRequestAnimationFrame;

var cancelAnimationFrame =
  window.cancelAnimationFrame || window.mozCancelAnimationFrame;

var start = window.mozAnimationStartTime; // 只有Firefox支持mozAnimationStartTime屬性,其餘瀏覽器可使用Date.now()來替代.

var myReq;
function step(timestamp) {
  var progress = timestamp - start;
  d.style.left = Math.min(progress / 10, 200) + "px";
  if (progress < 2000) {
    myReq = requestAnimationFrame(step); //必須再調用一次,這樣就造成了遞歸
  }
}
myReq = requestAnimationFrame(step);

//當不須要是取消動畫,好比 在vue destoryed中
window.cancelAnimationFrame(myReq);

image

image

1.六、getSelection()

此方法沒必要傳入具體的 dom,選中哪一個區域或者光標在哪一個輸入框, 此方法會獲取到那個 dom。 返回一個selection對象

window.getSelection();

image

1.七、scroll() / scrollBy() / scrollTo()

scroll()滾動至文檔中的絕對位置(相似於 css 中的 display:absolute), scrollBy()滾動指定的距離(相似於 css 中的 display:relative)

scrollTo 和 scroll 一致。

window.scroll({
  top: 100,
  left: 100,
  behavior: 'smooth'  //表示是否平滑的過渡仍是便可調到指定位置,同css屬性scroll-behavior
});
window.scrollBy({
  top: 100,
  left: 100,
  behavior: "smooth"
});

scroll() scrollBy() scrollTo()合稱爲 scrollOptions API
image

二、window 事件

一般在定義 window 中的事件時,有兩種方式:

  • window.onXXX = function(){};
  • window.addEventListener("XXX", ()=>{}, {capture:true, once:true, passive:true});

那麼這兩種方式有區別嗎? 有區別,但也沒區別。

由於雖然定義的方式不一樣,可最終都會走到事件中。

可是又有區別,尤爲在多個組件中,同時定義相同的事件,那麼 window.onXXX 會後面定義的把前面定義的相同事件覆蓋掉。最終只會執行最後定義的那個。而 window.addEventListener 不一樣,定義幾個,執行幾回,並且還能夠再 options 中設置 once,capture,passive 等選項。

以 passive 爲例,它能夠忽略事件得默認行爲,不會阻止它。當你在 js 操做時,html 中會立馬響應到。最典型得可使得觸摸事件和 scroll 事件再也不卡頓,很是流暢。

一般有 XXX 方式,那麼對應也會有 onXXX

2.一、onbeforeunload

當窗口即將被卸載(關閉)時,會觸發該事件.此時頁面文檔依然可見,且該事件的默認動做能夠被取消.

須要注意的是,點擊瀏覽器標籤頁的 x 號前,若是沒有對頁面進行過任何「操做」,則不會彈框直接關閉,若是進行過操做,則會彈出確認框。

這裏所指的「操做」包括,但不限於,input 輸入,打開 console,複製頁面的一段文字等等。

window.onbeforeunload = () => {
    let isIE = xxxxxxxx; //忽略經過user-agent判斷ie瀏覽器的方法
    if (isIE) {
      return "The system may be not save your changes.";
    } else {
      return false; //其餘瀏覽器會彈出本身的文字,如上圖。是中文
    }
};

image

2.二、onhashchange

當 一個窗口的 hash (URL 中 # 後面的部分)改變時就會觸發 hashchange 事件(參見 location.hash)。

window.onhashchange = (newURL, oldURL)=>{
    //newURL 當前頁面新的URL
    //oldURL 當前頁面舊的URL
};

image

2.三、onload / DOMContentLoaded

DOMContentLoaded 指 html 頁面加載完畢就會觸發,至於一些異步資源的好比 img,video 等等,它不關心。

而 onload 表示除了 html 加載完,img,video 等也加載完,才執行

window.addEventListener("load", function () {

});

window.addEventListener("DOMContentLoaded", function () {

});

image

image

看到沒: JavaScript event that fires when the DOM is loaded, but before all page assets are loaded (CSS, images, etc.). 說的再清楚不過了

2.四、onmouseover、onmouseout / onmouseenter、onmouseleave

onmouseover、onmouseout:鼠標移動到自身時候會觸發事件,同時移動到其子元素身上也會觸發事件 onmouseenter、onmouseleave:鼠標移動到自身是會觸發事件,可是移動到其子元素身上不會觸發事件

onmouseover 和 onmouseout 支持性一致
image

onmouseenter 和 onmouseleave 支持性一致
image

2.五、onscroll / onwheel

onwheel 事件在鼠標滾輪在元素上下滾動時觸發,必須滾輪要轉,至於頁面滾不滾動,它不關心。

onscroll 事件在元素滾動條在滾動時觸發,必須滾動條存在且上下運動。
觸發方式有:滾輪滾動,鼠標按住滾動條拖動,鍵盤上下鍵滾動,js 腳本去滾動如 scrollTo,scrollBy,scrollByLines, scrollByPages 等。

在這裏有個特殊,在手機端,雖然沒有鼠標,可是手指觸摸上下滾動,也是觸發 onscroll 的。

image

image
什麼? 支持率這麼一點點? 大大出乎個人意料

2.六、copy 事件/cut 事件/ paste 事件

window 的複製/剪切, 粘貼事件。

window.addEventListener("copy", function (e) {
    //將複製的數據,存入到剪切板中
    e.clipboardData.setData("abc", "Hello, world!");
    e.preventDefault();
});

window.addEventListener("paste", function (e) {
    //再從剪切板中取出數據
    let data = e.clipboardData.getData("abc");
    e.preventDefault();
});

這三個事件支持性一致

image

2.七、error 事件

當資源加載失敗或沒法使用時,會在 Window 對象觸發 error 事件。例如:script 執行時報錯。

window.addEventListener('error', (event) => {

});

image

2.八、orientationchange 事件

orientationchange 事件在設備的縱橫方向改變時觸發。

window.addEventListener("orientationchange", function() {

});

image
pc 上幾乎都不支持,這也能理解,畢竟 pc 上是使用 resize 的,只有手機纔會使用 橫豎屏。

2.九、rejectionhandled 事件 / unhandledrejection 事

當 Promise 被 rejected 且有 rejection 處理器時會在全局觸發 rejectionhandled。

當 Promise 被 reject 且沒有 reject 處理器的時候,會觸發 unhandledrejection 事件;

window.addEventListener("rejectionhandled", event => {

}, false);

window.addEventListener("unhandledrejection", event => {

});


function getName() {
    return Promise.reject("error");
}

let p = getName();   //觸發unhandledrejection
setTimeout(() => {
    p.catch((err) => {});  //觸發rejectionhandled
}, 1000);

image

image

2.十、storage 事件

當 localStorage 被修改時,將觸發 storage 事件。

注意:

  • 只有在同域名的不一樣文件之間,纔可以監聽到,
  • 同一個文件中,是監聽不到的(合理,同一個文件直接拿就好了,用 storage 監聽畫蛇添足)
  • 經過 iframe 引入的另外一個站點,也能夠監聽到

image

2.十一、online 事件 / offline 事件

online 當網絡鏈接時,觸發,
offline 當網絡斷開時觸發

online 和 offline 支持性一致
image

2、element(DOM 對象)

一、element 屬性和方法

1.一、clientHeight / clientWidth 屬性
  • clientHeight:元素內部的高度,包含內邊距,但不包括水平滾動條、邊框和外邊距。
  • clientWidth:元素內部的寬度,包含內邊距,但不包括垂直滾動條、邊框和外邊距。

此屬性會將獲取的值四捨五入取整數。

document.querySelector("span").clientWidth

clientHeight 和 clientWidth 支持性一致
image

1.二、scrollHeight / scrollWidth 屬性

相似於上方的 clientHeight / clientWidth,不一樣在於 clientHeight / clientWidth 在元素設置 overflow 後,不包含隱藏不可見的高度部分。而 scrollHeight / scrollWidth 卻包含隱藏的那部分高度。

我以爲利用這個特性來判斷是否超長,若是 scrollWidth 大於 clientWidth,則表示超長,此時能夠對於那些超長後顯示...的元素在浮上去後展現一個自定義的 toolip.

scrollHeight 和 scrollWidth 支持性一致
image

1.三、getBoundingClientRect()方法

返回元素的大小及其相對於視口的位置(眼睛看的見的文檔區域)。

這個方法超級好用。無論你的元素在什麼位置,它都會計算出來當前元素 至關於 視口的邊緣的位置,和滾動條無關。

image

返回值爲

{
    bottom: xx,  //元素底部離視口頂部的距離
    height: xx,   //元素高度,和元素的clientHeight屬性一致,但比它精確,會保留小數
    left: xx,  //元素左邊離視口左側的距離
    right: xx,  //元素右邊離視口左側的距離
    top: xx,   //元素上部離視口頂部的距離
    width: xx,   //元素寬度,和元素的clientWidth屬性一致,但比它精確,會保留小數
}

image
這個方法的支持性爲 100%, 良心啊,爲何我才知道這個方法?

1.四、scrollIntoView()方法

若是父元素定義了 overflow,併產生了滾動條,裏面有個子元素,在滾動條滑動後,看不到了。那麼可讓這個子元素執行這個方法,讓元素滾動到父元素可視區域內。

能夠定義滾動條可視區域的頂部,底部,仍是左邊,右邊。
也能夠定義平滑的滾動過來,仍是一瞬間滾動過來。

這個方法的好處是自動計算裏面子元素距離可見區域多少,不須要給數值進行人爲干涉,而 scroll()或 scrollTo()方法,必須人爲計算滾動條的距離,而後給個數值,才能滾動到某個位置。

首先看個例子,
image

div1 超過屏幕的區域有個 div2,超過 div2 的區域有個 span1,此時咱們能夠經過調用 span1 元素的 scrollIntoView 方法,讓 span1,滾動到 div2 的可見區域,也就是向左邊滾動,可是有個壞處,就是 div1 也會向上滾動,直到 div2 能被用戶看到。
而 scroll()或 scrollTo()方法在 span1 滾動到 div2 的可見區域時,div1 不動。不會產生其餘附加做用,直到你慢慢滑屏,纔會看到 span1,已經停留在 div2 的可視範圍了。

image

1.五、scroll() / scrollTo() / scrollBy() 方法

scrollTo 方法可使界面滾動到給定元素的指定座標位置。

以產生滾動條的那個父元素爲基準,

scroll() scrollBy() scrollTo()合稱爲 scrollOptions API
image

二、element 事件

2.一、contextmenu 事件

contextmenu 事件會在用戶嘗試打開上下文菜單時被觸發。該事件一般在鼠標點擊右鍵或者按下鍵盤上的菜單鍵時被觸

<p id="noContextMenu">這個段落右鍵菜單已被禁用。</p>



noContext = document.getElementById('noContextMenu');

noContext.addEventListener('contextmenu', e => {
  e.preventDefault();
});

單擊右鍵,不會出現標準的右鍵菜單項目

image

2.二、copy 事件/cut 事件/ paste 事件

dom 的複製/剪切, 粘貼事件。

<div class="source">
  Try copying text from this box...
</div>
<div class="target" contenteditable="true">
  ...and pasting it into this one
</div>
let sourceDom = document.querySelector(".source");
sourceDom.addEventListener("copy", function (e) {
  //將數據存入剪切板
  e.clipboardData.setData("abc", "Hello, world!");
  e.preventDefault();
});

let targetDom = document.querySelector(".target");
targetDom.addEventListener("paste", function (e) {
  //從剪切板取出來
  let data = e.clipboardData.getData("abc");

  //自定義轉化數據
  data = data.toUpperCase();

  //獲取光標位置
  const selection = window.getSelection();
  if (!selection.rangeCount) return false;
  selection.deleteFromDocument();
  //將轉換後的數據插入到光標位置
  selection.getRangeAt(0).insertNode(document.createTextNode(data));

  e.preventDefault();
});

這三個事件支持性一致

image

2.三、focusin 事件 / focusout 事件

當元素得到焦點時,focusin 事件被觸發。
focusin 事件和 focus 事件之間的主要區別在於 focus 不會冒泡。

當元素即將失去焦點時,focusout 事件被觸發。
focusout 事件和 blur 事件之間的主要區別在於 blur 不會冒泡。

image

2.四、onscroll / onwheel

相似於 window 的 onscroll 和 onwheel。只不過綁定對象爲 element

let sourceDom = document.querySelector(".source");
sourceDom.addEventListener("scroll", function (e) {
    console.log("111");
});

sourceDom.addEventListener("wheel", function (e) {
    console.log("111");
});

3、document(文檔對象)

一、document 屬性和方法

1.一、characterSet

返回當前文檔的字符編碼,但有至關一部分瀏覽器未實現,可以使用原始的 charset 代替

document.characterSet || document.charset
1.二、compatMode

代表當前文檔的渲染模式是怪異模式/混雜模式仍是標準模式。

document.compatMode  //  BackCompat怪異模式, CSS1Compat標準模式

image

1.三、defaultView

返回當前 document 對象所關聯的 window 對象,若是沒有,會返回 null。

document.defaultView   //返回仍是window,我爲何不直接 使用window呢?

上面的代碼很平淡,不足爲奇,但是下面的就不必定了

<div class="source" style="height: 200px; overflow: auto;">
    <object type="text/html" style="width: 100%; height: 100%;"> </object>
</div>
let doc = document.querySelector("object").contentDocument; //獲得一個document對象

doc.defaultView; //接着獲得一個window

獲得這個 window 後,有什麼用呢?

咱們能夠想象一個場景,當咱們縮放 window 窗口時,會觸發 window 的 onresize 事件,可是縮放 div,卻不會觸發 onresize 事件,由於 dom 沒有 onresize,那麼如何監聽一個 div 的 resize 呢?

就是上述的方式,在 div 中套一個 object。我不監聽 div,我監聽 div 中的 object,一旦 div 變了,object 不也就變了嗎?

而後經過 object 返回的一個 window 對象,就天然能夠綁定 onresize 事件了

document.querySelector("object").contentDocument.defaultView .addEventListener("resize", () => {
    //只要div尺寸變化,object尺寸就變化,resize就能監聽到。無論何種緣由致使的尺寸變化。都會監聽到。
});

image

除此以外,我有一遍專門介紹如何完全解決 div 尺寸變化問題的文章,有興趣的夥伴能夠閱讀

1.四、designMode

控制整個文檔是否可編輯。有效值爲 "on" 和 "off" 。

默認值爲 "off" 。若是設置爲"on",則比如給 html 全部的元素都添加了 contenteditable 屬性。

image

1.五、documentElement

會返回文檔對象(document)的根元素。

能夠經過 document.documentElement.clientHeight 來獲取瀏覽器的可用高度,這個高度和 html 或者 body 的 style 上的 height 無關,只與瀏覽器的上方地址欄,下方工具欄等有關,和 window.innerHeight 相等。

image

二、document 事件

2.一、onscroll / onwheel

相似於 window 的 onscroll 和 onwheel。只不過綁定對象爲 document

document.addEventListener("scroll", function (e) {
    console.log("111");
});

document.addEventListener("wheel", function (e) {
    console.log("111");
});
相關文章
相關標籤/搜索