主頁 > 企業開發 > CSS Houdini:用瀏覽器引擎實作高級CSS效果

CSS Houdini:用瀏覽器引擎實作高級CSS效果

2022-07-13 11:56:37 企業開發

vivo 互聯網前端團隊-Wei Xing

Houdini被稱之為Magic of styling and layout on the web,看起來十分神秘,但實際上,Houdini并非什么神秘組織或者神奇魔法,它是一系列與CSS引擎相關的瀏覽器API的總稱,

一、Houdini 是什么

在了解之前,先來看一些Houdini能實作的效果吧:

反向的圓角效果(Border-radius):

圖片

動態的球形背景(Backgrond):

圖片

彩色邊框(Border):

圖片

神奇吧,要實作這些效果使用常規的CSS可沒那么容易,但對CSS Houdini來說,卻很easy,這些效果只是冰山一角,CSS Houdini能做的有更多,(這些案例均來自Google Chrome Labs,更多案例可以通過 Houdini Samples 查看),

看完效果,再來說說Houdini到底是什么,

首先,Houdini 的出現最直接的目的是為了解決瀏覽器對新的CSS特性支持較差以及Cross-Browser的問題,我們知道有很多新的CSS特性雖然很棒,但它們由于不被主流瀏覽器廣泛支持而很少有人去使用,

隨著CSS規范在不斷地更新迭代,越來越多有益的特性被納入進來,但是一個新的CSS特性從被提出到成為一個穩定的CSS特性,需要經過漫長地等待,直到被大部分瀏覽器支持時,才能被開發者廣泛地使用,

而 Houdini 的出現正是洞察和解決了這一痛點,它將一系列CSS引擎API開放出來,讓開發者可以通過JavasScript創造或者擴展現有的CSS特性,甚至創造自己的CSS渲染規則,給開發者更高的CSS開發自由度,實作更多復雜的效果,

二、JS Polyfill vs Houdini

有人會問,實際上很多新的CSS特性在被瀏覽器支持之前,也有可替代的JavaScript Polyfill可以使用,為什么我們仍然需要Houdini呢?這些Polyfill不是同樣可以解決我們的問題嗎?

要回答這個問題也很簡單,JavaScript Polyfill相對于Houdini有三個明顯的缺陷:

1.不一定能實作或實作困難,

CSSOM開放給JavaScript的API很少,這意味著開發者能做的很有限,只能簡單地操縱DOM并對樣式做動態計算和調整,光是去實作一些復雜的CSS新特性的Polyfill就已經很難了,對于更深層次的Layout、Paint、Composite等渲染規則更是無能為力,所以當一個新的CSS特性被推出時,通過JavaScript Polyfill不一定能夠完整地實作它,

2.實作效果差或有使用限制,

JavaScript Polyfill是通過JavaScript來模擬CSS特性的,而不是直接通過CSS引擎進行渲染,通常它們都會有一定的限制和缺陷,例如,大家熟知的css-scroll-snap-polyfill就是針對新的CSS特性Scroll Snap產生的Polyfill,但它在使用時就存在使用限制或者原生CSS表現不一致的問題,

3.性能較差,

JavaScript Polyfill可能造成一定程度的性能損耗,JavaScript Polyfill的執行時機是在DOM和CSSOM都構建完成并且完成渲染后,通常JavaScript Polyfill是通過給DOM元素設定行內樣式來模擬CSS特性,這會導致頁面的重新渲染或回流,尤其是當這些Polyfill和滾動事件系結時,會造成更加明顯的性能損耗,

圖片

Houdini的誕生讓CSS新特性不再依賴于瀏覽器,開發者通過直接操作CSS引擎,具有更高的自由度和性能優勢,并且它的瀏覽器支持度在不斷提升,越來越多的API被支持,未來Houdini必然會加速走進web開發者的世界,所以現在對它做一些了解也是必要的,

在本文,我們會介紹Houdini的APIs以及它們的使用方法,看看這些API當前的支持情況,并給出一些在生產環境中使用它們的建議,

Houdini的名稱與一位著名美國逃脫魔術師Harry Houdini的名稱一樣,也許正是取逃脫之意,讓CSS新特性逃離瀏覽器的掌控,

三、Houdini APIs

上文提到CSS Houdini提供了很多CSS引擎相關的API,根據Houdini提供的規范說明檔案,API共分為兩種型別:high-level APIs 和 low-level APIs ,

圖片

high-level APIs:顧名思義是高層次的API,這些API與瀏覽器的渲染流程相關,

  • Paint API

提供了一組與繪制(Paint)程序相關的API,我們可以通過它自定義的渲染規則,例如調整顏色(color)、邊框(border)、背景(background)、形狀等繪制規則,

  • Animation API

提供了一組與合成(composite)渲染相關的API,我們可以通過它調整繪制層級和自定義影片,

  • Layout API

提供了一組與布局(Layout)程序相關的API,我們可以通過它自定義的布局規則,類似于實作諸如flex、grid等布局,自定義元素或子元素的對齊(alignment)、位置(position)等布局規則,

low-level APIs:低層次的API,這些API是high-level APIs的實作基礎,

  • Typed Object Model API
  • CSS Properties & Values API
  • Worklets
  • Font Metrics API
  • CSS Parser API

這些APIs的支持情況在不斷更新中,可以看到當前最新的一次更新時間是在2021年5月份,還是比較活躍的,(注:圖片來源于Is Houdini ready yet? )

圖片

對比下圖2018年底的情況,Houdini目前得到了更廣泛的支持,我們也期待圖里更多綠色的板塊被逐漸點亮,

圖片

大家可以訪問 Is Houdini ready yet? 看到Houdini的最新支持情況,

下文中,我們會著重介紹Typed Object Model API、CSS Properties & Values API、Worklets和Paint API、Animation API,因為它們目前具有比其他API更好的支持度,且它們的特性已經趨于穩定,在未來不會有很大的變更,大家也能在了解它們之后直接將它們使用在專案中,

四、 Typed Object Model API

在Houdini出現以前,我們通過JavaScript操作CSS Style的方式很簡單,先看看一段大家熟悉的代碼,

// Before Houdini
 
const size = 30
target.style.fontSize = size + 'px' // "20px"

const imgUrl = 'https://www.exampe.com/sample.png'
target.style.background = 'url(' + imgUrl + ')' // "url(https://www.exampe.com/sample.png)"

target.style.cssText = 'font-size:' + size + 'px; background: url('+ imgUrl +')'  
// "font-size:30px; background: url(https://www.exampe.com/sample.png)"

我們可以看到CSS樣式在被訪問時被決議為字串回傳,設定CSS樣式時也必須以字串的形式傳入,開發者需要手動拼接數值、單位、格式等資訊,這種方式非常原始和落后,很多開發者為了節省性能損耗,會選擇將一長串的CSS Style字串傳入cssText,可讀性很差,而且很容易產生隱蔽的語法錯誤,

Typed Object ModelTypeScript的命名類似,都增加了Type這個前綴,如果你使用過TypeScript就會了解到,TypeScript增強了型別檢查,讓代碼更穩定也更易維護,Typed Object Model也是如此,

相比于上面晦澀的傳統方法,Typed Object Model將CSS屬性值包裝為Typed JavaScript Object,讓每個屬性值都有自己的型別,簡化了CSS屬性的操作,并且帶來了性能上的提升,通過JavaScript物件來描述CSS值比字串具有更好的可讀性和可維護性,通常也更快,因為可以直接操作值,然后廉價地將其轉換回呼層值,而無需構建和決議 CSS 字串,

Typed Object Model中CSSStyleValue是所有CSS屬性值的基類,在它之下的子類用于描述各種CSS屬性值,例如:

  • CSSUnitValue
  • CSSImageValue
  • CSSKeywordValue
  • CSSMathValue
  • CSSNumericValue
  • CSSPositionValue
  • CSSTransformValue
  • CSSUnparsedValue
  • 其它

通過它們的命名就可以看出這些不同的子類分別用于表示哪種型別的CSS屬性值,以CSSUnitValue為例,它可以用于表示帶有單位的CSS屬性值,例如font-size、width、height,它的結構很簡單,由value和unit組成,

{
  value: 30,
  unit: "px"
}

可以看到,通過物件來描述CSS屬性值確實比傳統的字串更易讀了,

要訪問和操作CSSStyleValue還需要借助兩個工具,分別是attributeStyleMap和computedStyleMap(),前者用于處理行內樣式,可以進行讀寫操作,后者用于處理非行內樣式(stylesheet),只有讀操作,

// 獲取stylesheet樣式
target.computedStyleMap().get("font-size"); // { value: 30, unit: "px"}

// 設定行內樣式
target.attributeStyleMap.set("font-size", CSS.em(5));

// stylesheet樣式仍然回傳20px
target.computedStyleMap().get("font-size"); // { value: 30, unit: "px"}

// 行內樣式已經被改變
target.attributeStyleMap.get("font-size"); // { value: 5, unit: "em"}

當然attributeStyleMap和computedStyleMap()還有更多可用的方法,例如clear、has、delete、append等,這些方法都為開發者提供了更便捷和清晰的CSS操作方式,

五、CSS Properties & Values API

根據MDN的定義,CSS Properties & Values API也是Houdini開放的一部分API,它的作用是讓開發者顯式地宣告自定義屬性(css custom properties),并且定義這些屬性的型別、默認值、初始值和繼承方法,

--my-color: red;
--my-margin-left: 100px;
--my-box-shadow: 3px 6px rgb(20, 32, 54);

在被宣告之后,這些自定義屬性可以通過var()來參考,例如:

// 在:root下可宣告全域自定義屬性
:root {
  --my-color: red;
}
 
#container {
  background-color: var(--my-color)
}

了解了自定義屬性的基本概念和使用方式后,我們來考慮一個問題,我們能否通過自定義屬性來幫助我們完成一些過渡效果呢?

例如,我們希望為一個div容器設定背景色的transition影片,我們知道CSS是無法直接對background-color做transition過渡影片的,那我們考慮將transition設定在我們自定義的屬性--my-color上,通過自定義屬性的漸變來間接完成背景的漸變效果,是否能做到呢?根據剛才的自定義屬性簡介,也許你會嘗試這么做:

// DOM
<div id="container">container</div>
 
// Style
:root {
  --my-color: red;
}
 
#container {
  transition: --my-color 1s;
  background-color: var(--my-color)
}
 
#container:hover {
  --my-color: blue;
}

這看起來是個符合邏輯的寫法,但實際上由于瀏覽器不知道該如何去決議--my-color這個變數(因為它并沒有明確的型別,只是被當做字串處理),所以也無法對它采用transition的效果,因此我們并不能得到一個漸變的背景色影片,

圖片

但是,通過CSS Properties & Values API提供的CSS.registerProperty()方法就可以做到,就像這樣:

// DOM
<div id="container">container</div>
 
// JavaScript
CSS.registerProperty({
  name: '--my-color',
  syntax: '<color>',
  inherits: false,
  initialValue: '#c0ffee',
});
 
// Style
#container {
  transition: --my-color 1s;
  background-color: var(--my-color)
}
 
#container:hover {
  --my-color: blue;
}

與上面的不同之處在于,CSS.registerProperty()顯式定義了--my-color的型別syntax,這個syntax告訴瀏覽器把--my-color當做color去決議,因此當我們設定transition: --my-color 1s時,瀏覽器由于提前被告知了該屬性的型別和決議方式,因此能夠正確地為其添加過渡效果,得到的效果如下圖所示,

圖片

CSS.registerProperty()接受一個引數物件,引數中包含下面幾個選項:

  • name: 變數的名字,不允許重復宣告或者覆寫相同名稱的變數,否則瀏覽器會給出相應的報錯,
  • syntax: 告訴瀏覽器如何決議這個變數,它的可選項包含了一些預定義的值等,
  • inherits: 告訴瀏覽器這個變數是否繼承它的父元素,
  • initialValue: 設定該變數的初始值,并且將該初始值作為fallback,

在未來,開發者不僅可以在JavaScript中顯式宣告CSS變數,也可以直接在CSS中直接宣告:

@property --my-color{
  syntax: '<color>',
  inherits: false,
  initialValue: '#c0ffee',
}

六、Font Metrics API

目前 Font Metrics API 還處于早期的草案階段,它的規范在未來可能會有較大的變更,在當前的specification檔案中,說明了** Font Metrics API** 將會提供一系列API,允許開發者干預文字的渲染程序,創建文字或者動態修改文字的渲染效果等,期待它能在未來被采納和支持,為開發者提供更多的可能,

七、CSS Parser API

目前** Font Metrics API **也處于早期的草案階段,當前的specification檔案中說明了它將會提供更多CSS決議器相關的API,用于決議任意形式的CSS描述,

八、Worklets

Worklets是輕量級的 Web Workers,它提供了讓開發者接觸底層渲染機制的API,Worklets的作業執行緒獨立于主執行緒之外,適用于做一些高性能的圖形渲染作業,并且它只能被使用在HTTPS協議中(生產環境)或通過localhost來啟用(開發除錯),

Worklets不像Web Workers,我們不能將任何計算操作都放在Worklets中執行,Worklets開放了特定的屬性和方法,讓我們能處理圖形渲染相關的操作,我們能使用的Worklet型別暫時有如下幾種:

  • PaintWorklet - Paint API
  • LayoutWorklet - Animation API
  • AnimationWorklet - Layout API
  • AudioWorklet - Audio API(處于草案階段,暫不介紹)

Worklets提供了唯一的方法Worklet.addModule(),這個方法用于向Worklet添加執行模塊,具體的使用方法,我們在后續的Paint API、Layout API、Animation API中介紹,

九、Paint API

Paint API允許開發者通過Canvas 2d的方法來繪制元素的背景、邊框、內容等圖形,這在原始的CSS規則中是無法做到的,

Paint API需要結合上述提到的PaintWorklet一起使用,簡單來說就是開發者構建一個PaintWorklet,再將它傳入Paint API就可以繪制相應的Canvas圖形,如果你熟悉Canvas,那Paint API對你來說也不會陌生,

使用Paint API的程序簡述如下:

  1. 使用registerPaint()方法創建一個PaintWorklet,
  2. 將它添加到Worklet模塊中,CSS.paintWorklet.addModule(),
  3. 在CSS中通過paint()方法使用它,

圖片

其中registerPaint()方法用于創建一個PaintWorklet,在這個方法中開發者可以利用Canvas 2d自定義圖形繪制,

可以通過Google Chrome Labs給出的一個paint API案例checkboardWorklet來直觀看看它的具體使用方法,案例中利用Paint API為textarea繪制彩色的網格背景,它的代碼組成很簡單:

/* checkboardWorklet.js */
 
class CheckerboardPainter {
  paint(ctx, geom, properties) {
    const colors = ['red', 'green', 'blue'];
    const size = 32;
    for(let y = 0; y < geom.height/size; y++) {
      for(let x = 0; x < geom.width/size; x++) {
        const color = colors[(x + y) % colors.length];
        ctx.beginPath();
        ctx.fillStyle = color;
        ctx.rect(x * size, y * size, size, size);
        ctx.fill();
      }
    }
  }
}
 
// 注冊checkerboard
registerPaint('checkerboard', CheckerboardPainter);
/* index.html */
<script>
    CSS.paintWorklet.addModule('path/to/checkboardWorklet.js')  // 添加checkboardWorklet到paintWorklet
</script>
/* index.html */
<!doctype html>
<textarea></textarea>
<style>
  textarea {
    background-image: paint(checkerboard);  // 使用paint()方法呼叫checkboard繪制背景
  }
</style>

通過上述三個步驟,最終生成的textarea背景效果如圖所示:

圖片

感興趣的同學可以訪問 houdini-samples查看更多官方樣例,

十、Animation API

在過去,當我們想要對DOM元素執行影片時,通常只有兩個選擇:CSS Transitions和CSS Animations,這兩者在使用上雖然簡單,也能滿足大部分的影片需求,但是它們有兩個共同的缺點

  • 僅僅依賴時間來執行影片(time-driven):影片的執行僅和時間有關,
  • 無狀態(stateless):開發者無法干預影片的執行程序,獲取不到影片執行的中間狀態,

但是在一些場景下,我們想要開發一個非時間驅動的影片或者想要控制影片的執行狀態,就很難做到,比如視差滾動(Parallax Scrolling),它是根據滾動的情況來執行影片的,并且每個元素根據滾動情況作出不一致的影片效果,下面是個簡單的視差滾動效果示例,在通常情況下要實作更加復雜的視差滾動效果(例如beckett頁面的效果)是比較困難的,

圖片

Animation API卻可以幫助我們輕松做到,

在功能方面,它是CSS Transitions和CSS Animations的擴展,它允許用戶干預影片執行的程序,例如結合用戶的scroll、hover、click事件來控制影片執行,像是為影片增加了進度條,通過進度條控制影片行程,從而實作一些更加復雜的影片場景,

在性能方面,它依賴于AnimationWorklet,運行在單獨的Worklet執行緒,因此具有更高的影片幀率和流暢度,這在低端機型中尤為明顯(當然,通常低端機型中的瀏覽器內核還不支持該特性,這里只是說明Animation API對影片的視覺體驗優化是很友好的),

Animation API的使用和Paint API一樣,也同樣遵循Worklet的創建和使用流程,分為三個步驟,簡述如下:

  1. 使用registerAnimator()方法創建一個AnimationWorklet,
  2. 將它添加到Worklet模塊中,CSS.animationWorklet.addModule(),
  3. 使用new WorkletAnimation(name, KeyframeEffect)創建和執行影片,

圖片

/* myAnimationWorklet.js */
registerAnimator("myAnimationWorklet", class {
  constructor(options) {
    /* 建構式,影片示例被創建時呼叫,可用于做一些初始化 */
  }
   
  //
  animate(currentTime, effect) {
    /* 干預影片的執行 */
  }
});
/* index.html */
await CSS.animationWorklet.addModule("path/to/myAnimationWorklet.js");;
/* index.html */
 
/* 傳入myAnimationWorklet,創建WorkletAnimation */
new WorkletAnimation(
  'myAnimationWorklet', // 影片名稱
  new KeyframeEffect(   // 影片timeline(對應于步驟一中animate(currentTime, effect)中的effect引數)
    document.querySelector('#target'), 
    [
      {
        transform: 'translateX(0)'
      },
      {
        transform: 'translateX(200px)'
      }
    ],
    {
      duration: 2000, // 影片執行時長
      iterations: Number.POSITIVE_INFINITY  // 影片執行次數
    }
  ),
  document.timeline // 控制影片執行行程的數值(對應于步驟一中animate(currentTime, effect)中的currentTime引數)
).play();

可以看到步驟一的animate(currentTime, effect)方法有兩個引數,就是它們讓開發者能夠干預影片執行程序,

  • currentTime:

用于控制影片執行的數值,對應于步驟3例子中傳入的document.timeline引數,通常根據它的數值來動態修改另一個引數effect,從而影響影片執行,例如我們可以傳入document.timeline或者傳入element.scrollTop作為這個動態數值,傳入前者表明我們只是想用時間變化來控制影片的執行,傳入后者表明我們想通過滾動距離來控制影片執行,

document.timeline是每個頁面被打開后從0開始遞增的時間數值,可以簡單理解為頁面被打開的時長,初始時document.timeline === 0,隨著時間不斷遞增,

  • effect:

對應于步驟3中傳入的new KeyframeEffect(),可通過修改它來影響影片執行,一個很常見的做法是,通過修改effect.localTime控制影片的執行,effect.localTime的作用相當于控制影片播放的進度條,修改它的數值就相當于拖動影片播放的進度,

如果不修改effect.localTime或者設定effect.localTime = currentTime,那么影片會隨著document.timeline正常勻速執行,線性影片,但是如果將effect.localTime設定為某個固定值,例如effect.localTime = 1000ms,那么影片將會定格在1000ms時對應的幀,不會繼續執行,

為了更好理解effect.localTime,可以來看看effect.localTime和影片執行之間的關系,假設我們創建了一個2000ms時長的影片,并且影片沒有設定delay時間,

圖片

通過上面的描述,大家應該get到如何做一個簡單的滾動驅動(scroll-driven)的影片了,實際上有個專門用于生成滾動影片的類:ScrollTimeline,它的用法也很簡單:

/* myWorkletAnimation.js */
 
new WorkletAnimation(
  'myWorkletAnimation',
  new KeyframeEffect(
    document.querySelector('#target'),
    [
      {
        transform: 'translateX(0)'
      },
      {
        transform: 'translateX(500px)'
      }
    ],
    {
      duration: 2000,
      fill: 'both'
    }
  ),
  new ScrollTimeline({
    scrollSource: document.querySelector('.scroll-area'), // 監聽的滾動元素
    orientation: "vertical", // 監聽的滾動方向"horizontal"或"vertical"
    timeRange: 2000 // 根據scroll的高度,傳入0 - timeRage之間的數值,當滾動到頂端時,傳入0,當滾動到底端時,傳入2000
  })
).play();

圖片

這樣一來,通過簡單的幾行代碼,一個簡單的滾動驅動的影片就做好了,它比任何CSS Animations或CSS Transitions都要順暢,

接下來再看看最后一個同樣有潛力的API:**Layout API **,

十一、Layout API

Layout API允許用戶自定義新的布局規則,創造類似flex、grid之外的布局,

但創建一個完備的布局規則并不簡單,官方的flex、grid布局是充分考慮了各種邊界情況,才能確保使用時不會出錯,同時Layout API使用起來也比其它API更為復雜,受限于篇幅,本文僅簡單展示相關的API和使用方式,具體細節可參考官方描述,

Layout API和其它兩個API相似,使用步驟同樣分為三個步驟,簡述如下:

  • 通過registerLayout()創建一個LayoutWorklet,
  • 將它添加到Worklet模塊中,CSS.layoutWorklet.addModule(),
  • 通過display: layout(exampleLayout)使用它,

圖片

Google Chrome Labs案例如下所示,通過Layout API實作了一個瀑布流布局,

圖片

雖然通過Layout API自定義布局較為困難,但是我們依然可以引入別人的優秀開源Worklet,幫助自己實作復雜的布局,

十二、新特性檢測

鑒于當前Houdini APIs的瀏覽器支持度仍然不是很完美,在使用這些API時需要先做特性檢測,再考慮使用它們,

/* 特性檢測 */
 
if (CSS.paintWorklet) {
  /* ... */
}
 
if (CSS.animationWorklet) {
  /* ... */
}
 
if (CSS.layoutWorklet) {
  /* ... */
}

想要在chrome中除錯,可以在地址欄輸入chrome://flags/#enable-experimental-web-platform-features,并勾選啟用Experimental Web Platform features,

圖片

十三、總結

Houdini APIs讓開發者有辦法接觸到CSS渲染引擎,通過各種API實作更高性能和更復雜的CSS渲染效果,雖然它還沒有完全準備好,很多API甚至還處于草案階段,但它給我們帶來了更多可能性,并且諸如paint API、Typed OM、Properties & Values API這些新特性也都被廣泛支持了,可以直接用于增強我們的頁面效果,未來Houdini APIs一定會慢慢走進開發者的世界,大家可以期待并做好準備迎接它,

參考文獻:

  1. W3C Houdini Specification Drafts
  2. State of Houdini (Chrome Dev Summit 2018)
  3. Houdini’s Animation Worklet - Google Developers
  4. Interactive Introduction to CSS Houdini
  5. CSS Houdini Experiments
  6. Interactive Introduction to CSS Houdini
  7. Houdini Samples by Google Chrome Labs
分享 vivo 互聯網技術干貨與沙龍活動,推薦最新行業動態與熱門會議,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/498884.html

標籤:JavaScript

上一篇:Object.defineProperty也能監聽陣列變化?

下一篇:執行vue create時到底做了什么

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • IEEE1588PTP在數字化變電站時鐘同步方面的應用

    IEEE1588ptp在數字化變電站時鐘同步方面的應用 京準電子科技官微——ahjzsz 一、電力系統時間同步基本概況 隨著對IEC 61850標準研究的不斷深入,國內外學者提出基于IEC61850通信標準體系建設數字化變電站的發展思路。數字化變電站與常規變電站的顯著區別在于程序層傳統的電流/電壓互 ......

    uj5u.com 2020-09-10 03:51:52 more
  • HTTP request smuggling CL.TE

    CL.TE 簡介 前端通過Content-Length處理請求,通過反向代理或者負載均衡將請求轉發到后端,后端Transfer-Encoding優先級較高,以TE處理請求造成安全問題。 檢測 發送如下資料包 POST / HTTP/1.1 Host: ac391f7e1e9af821806e890 ......

    uj5u.com 2020-09-10 03:52:11 more
  • 網路滲透資料大全單——漏洞庫篇

    網路滲透資料大全單——漏洞庫篇漏洞庫 NVD ——美國國家漏洞庫 →http://nvd.nist.gov/。 CERT ——美國國家應急回應中心 →https://www.us-cert.gov/ OSVDB ——開源漏洞庫 →http://osvdb.org Bugtraq ——賽門鐵克 →ht ......

    uj5u.com 2020-09-10 03:52:15 more
  • 京準講述NTP時鐘服務器應用及原理

    京準講述NTP時鐘服務器應用及原理京準講述NTP時鐘服務器應用及原理 安徽京準電子科技官微——ahjzsz 北斗授時原理 授時是指接識訓通過某種方式獲得本地時間與北斗標準時間的鐘差,然后調整本地時鐘使時差控制在一定的精度范圍內。 衛星導航系統通常由三部分組成:導航授時衛星、地面檢測校正維護系統和用戶 ......

    uj5u.com 2020-09-10 03:52:25 more
  • 利用北斗衛星系統設計NTP網路時間服務器

    利用北斗衛星系統設計NTP網路時間服務器 利用北斗衛星系統設計NTP網路時間服務器 安徽京準電子科技官微——ahjzsz 概述 NTP網路時間服務器是一款支持NTP和SNTP網路時間同步協議,高精度、大容量、高品質的高科技時鐘產品。 NTP網路時間服務器設備采用冗余架構設計,高精度時鐘直接來源于北斗 ......

    uj5u.com 2020-09-10 03:52:35 more
  • 詳細解讀電力系統各種對時方式

    詳細解讀電力系統各種對時方式 詳細解讀電力系統各種對時方式 安徽京準電子科技官微——ahjzsz,更多資料請添加VX 衛星同步時鐘是我京準公司開發研制的應用衛星授時時技術的標準時間顯示和發送的裝置,該裝置以M國全球定位系統(GLOBAL POSITIONING SYSTEM,縮寫為GPS)或者我國北 ......

    uj5u.com 2020-09-10 03:52:45 more
  • 如何保證外包團隊接入企業內網安全

    不管企業規模的大小,只要企業想省錢,那么企業的某些服務就一定會采用外包的形式,然而看似美好又經濟的策略,其實也有不好的一面。下面我通過安全的角度來聊聊使用外包團的安全隱患問題。 先看看什么服務會使用外包的,最常見的就是話務/客服這種需要大量重復性、無技術性的服務,或者是一些銷售外包、特殊的職能外包等 ......

    uj5u.com 2020-09-10 03:52:57 more
  • PHP漏洞之【整型數字型SQL注入】

    0x01 什么是SQL注入 SQL是一種注入攻擊,通過前端帶入后端資料庫進行惡意的SQL陳述句查詢。 0x02 SQL整型注入原理 SQL注入一般發生在動態網站URL地址里,當然也會發生在其它地發,如登錄框等等也會存在注入,只要是和資料庫打交道的地方都有可能存在。 如這里http://192.168. ......

    uj5u.com 2020-09-10 03:55:40 more
  • [GXYCTF2019]禁止套娃

    git泄露獲取原始碼 使用GET傳參,引數為exp 經過三層過濾執行 第一層過濾偽協議,第二層過濾帶引數的函式,第三層過濾一些函式 preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'] (?R)參考當前正則運算式,相當于匹配函式里的引數 因此傳遞 ......

    uj5u.com 2020-09-10 03:56:07 more
  • 等保2.0實施流程

    流程 結論 ......

    uj5u.com 2020-09-10 03:56:16 more
最新发布
  • 使用Django Rest framework搭建Blog

    在前面的Blog例子中我們使用的是GraphQL, 雖然GraphQL的使用處于上升趨勢,但是Rest API還是使用的更廣泛一些. 所以還是決定回到傳統的rest api framework上來, Django rest framework的官網上給了一個很好用的QuickStart, 我參考Qu ......

    uj5u.com 2023-04-20 08:17:54 more
  • 記錄-new Date() 我忍你很久了!

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 大家平時在開發的時候有沒被new Date()折磨過?就是它的諸多怪異的設定讓你每每用的時候,都可能不小心踩坑。造成程式意外出錯,卻一下子找不到問題出處,那叫一個煩透了…… 下面,我就列舉它的“四宗罪”及應用思考 可惡的四宗罪 1. Sa ......

    uj5u.com 2023-04-20 08:17:47 more
  • 使用Vue.js實作文字跑馬燈效果

    實作文字跑馬燈效果,首先用到 substring()截取 和 setInterval計時器 clearInterval()清除計時器 效果如下: 實作代碼如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta ......

    uj5u.com 2023-04-20 08:12:31 more
  • JavaScript 運算子

    JavaScript 運算子/運算子 在 JavaScript 中,有一些運算子可以使代碼更簡潔、易讀和高效。以下是一些常見的運算子: 1、可選鏈運算子(optional chaining operator) ?.是可選鏈運算子(optional chaining operator)。?. 可選鏈操 ......

    uj5u.com 2023-04-20 08:02:25 more
  • CSS—相對單位rem

    一、概述 rem是一個相對長度單位,它的單位長度取決于根標簽html的字體尺寸。rem即root em的意思,中文翻譯為根em。瀏覽器的文本尺寸一般默認為16px,即默認情況下: 1rem = 16px rem布局原理:根據CSS媒體查詢功能,更改根標簽的字體尺寸,實作rem單位隨螢屏尺寸的變化,如 ......

    uj5u.com 2023-04-20 08:02:21 more
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 08:01:50 more
  • 如何在 vue3 中使用 jsx/tsx?

    我們都知道,通常情況下我們使用 vue 大多都是用的 SFC(Signle File Component)單檔案組件模式,即一個組件就是一個檔案,但其實 Vue 也是支持使用 JSX 來撰寫組件的。這里不討論 SFC 和 JSX 的好壞,這個仁者見仁智者見智。本篇文章旨在帶領大家快速了解和使用 Vu ......

    uj5u.com 2023-04-20 08:01:37 more
  • 【Vue2.x原始碼系列06】計算屬性computed原理

    本章目標:計算屬性是如何實作的?計算屬性快取原理以及洋蔥模型的應用?在初始化Vue實體時,我們會給每個計算屬性都創建一個對應watcher,我們稱之為計算屬性watcher ......

    uj5u.com 2023-04-20 08:01:31 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:01:10 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:00:32 more