js動(dòng)態(tài)設(shè)置關(guān)鍵偵@keyframes的方法技巧
1.前置知識(shí)
關(guān)鍵偵@keyframes規(guī)則通過(guò)在動(dòng)畫序列中定義關(guān)鍵偵的樣式來(lái)控制CSS動(dòng)畫序列的中間步驟
@keyframes slidein {
from {
transform: translateX(0%);
}
to {
transform: translateX(100%);
}
}
// from 等價(jià)于 0%;to 等價(jià)與 100%
// 或者
@keyframes slidein {
0% {
top: 0;
left: 0;
}
30% {
top: 50px;
}
68%,
72% {
left: 50px;
}
100% {
top: 100px;
left: 100%;
}
}
注意,如果在CSS中定義了兩個(gè)相同名字的keyframes,后這會(huì)覆蓋前者


如上圖所示,定義了兩個(gè)相同的動(dòng)畫偵之后,最終在瀏覽器中應(yīng)用的是后者
2.js動(dòng)態(tài)控制keyframes
背景
在 Vue 項(xiàng)目中由于 css 樣式是直接寫在 style 標(biāo)簽中的,那些值都是事先寫死的,比如說(shuō)上面的 translateX(disX),disX 是通過(guò) js 動(dòng)態(tài)計(jì)算出來(lái)的。如果要實(shí)現(xiàn)動(dòng)畫的效果是通過(guò)js動(dòng)態(tài)計(jì)算出來(lái)的,會(huì)比較困難。所以可以通過(guò) js 去設(shè)置 styleSheet 里面的樣式規(guī)則,從而能夠動(dòng)態(tài)的控制 keyframes
StyleSheet是javaScript中表示樣式表的接口,而styleSheet是一個(gè)DOM元素的對(duì)應(yīng)屬性,用于獲取該元素所關(guān)聯(lián)的樣式表
- 獲取樣式表:通過(guò)
styleSheet屬性可以獲取元素關(guān)聯(lián)的樣式表
// 獲取第一個(gè)樣式表 const firstStyleSheet = document.styleSheet[0] // document.styleSheet 可以理解為一個(gè)二維數(shù)組(但是不是數(shù)組) // 有多個(gè)樣式表,每個(gè)樣式表中都有多條規(guī)則
- 插入樣式列表:通過(guò)樣式列表的
insertRules方法可以在樣式列表中插入新的規(guī)則
const styleSheet = document.styleSheet[0]
styleSheet.insertRule(`.styleSheetCls { width: 200px; height: 200px}`,0)
// insertRule 方法中的第二個(gè)參數(shù)表示將樣式插入樣式表的哪里
// 這個(gè)規(guī)則會(huì)出現(xiàn)在第一個(gè)樣式表的第一條
- 刪除樣式規(guī)則:使用樣式表的
deleteRule方法可以刪除指定位置的規(guī)則
const styleSheet = document.styleSheet[0] styleSheet.deleteRule(0) // 刪除第一個(gè)樣式表的第一條
我們可以通過(guò)styleSheet的insertRule方法動(dòng)態(tài)的添加關(guān)鍵偵樣式
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>動(dòng)態(tài)添加 Keyframes</title>
<style id="dynamic-styles"></style>
</head>
<body>
<div id="myDiv"></div>
<script>
// 獲取樣式表
// 這里始終將新的 keyframes 規(guī)則添加在第一個(gè)樣式表的第一條
const styleSheet = document.styleSheet[0];
let dis = 0
//... 動(dòng)態(tài)計(jì)算 dis 的值
// 動(dòng)態(tài)創(chuàng)建 @keyframes
const keyframesName = 'dynamicAnimation';
const keyframesRule = `@keyframes ${keyframesName} {
0% { transform: translateX(${dis}px); }
25% { transform: translateX(-${dis}px) rotate(0.5deg); }
50% { transform: translateX(${dis}px) rotate(-0.5deg); }
75% { transform: translateX(-${dis}px) rotate(0.5deg); }
100% { transform: translateX(0); }
}`
`@keyframes dynamicAnimation{
0% { transform: translateX(5px); }
100% { transform: translateX(0); }
}`
// 每次添加新的規(guī)則之前,可以將之前的規(guī)則給刪除掉,這樣就可以避免第一個(gè)樣式表的規(guī)則里面有多條重復(fù)名稱的 keyframes,避免相同名字的 keyframes 前者被后者覆蓋
// 獲取第一個(gè)樣式表的第一條規(guī)則的名稱
const firstRules = styleSheet.rules || styleSheet.cssRules
// 這里是以防第一條規(guī)則不是 keyframes 規(guī)則,從而導(dǎo)致獲取 name 失敗
const ruleName = firstRules[0].name ? firstRules[0].name : ''
if(ruleName === keyframesName) {
/**
* 這里能夠直接刪除,是因?yàn)槲沂冀K將 keyframes 添加在第一個(gè)樣式表的第一條規(guī)則中
* 如果不能確定樣式位置,那么就需要遍歷整個(gè)樣式表,找到目標(biāo)樣式表的位置
* document.styleSheet 可以理解為一個(gè)二維數(shù)組(但是不是數(shù)組,不適合使用數(shù)組的遍歷方式進(jìn)行遍歷)
* 有多個(gè)樣式表,每個(gè)表中都有多條規(guī)則
**/
styleSheet.deleteRule(0)
}
// 這里始終將新的 keyframes 規(guī)則添加在第一個(gè)樣式表的第一條
styleSheet.insertRule(keyframesRule, 0);
// 動(dòng)態(tài)應(yīng)用 @keyframes
const myDiv = document.getElementById('myDiv');
myDiv.style.animation = `${keyframesName} 2s ease-in-out`;
</script>
</body>
</html>
3. 編寫技巧
- 在編寫
keyframes規(guī)則時(shí),我比較推薦在在style標(biāo)簽中將動(dòng)畫規(guī)則寫好了在復(fù)制到JavaScript邏輯代碼中,因?yàn)槿绻麆?dòng)畫規(guī)則編寫有問(wèn)題,那么在insertRule插入樣式的時(shí)候,可能會(huì)導(dǎo)致樣式表識(shí)別不了 - 查看是否添加成功,可以在控制臺(tái)打印出來(lái)樣式表,尋找我們添加的規(guī)則,如下圖
可以看到第一個(gè)樣式表中的第一個(gè)樣式是我們添加的
keyframes樣式,并且識(shí)別成功了會(huì)有CSSKeyframesRule的屬性,里面就是我們定義的每一幀的動(dòng)畫樣式
補(bǔ)充知識(shí):js動(dòng)態(tài)修改@keyframes屬性值
CSS3中增加了@keyframes規(guī)則用于創(chuàng)建動(dòng)畫,創(chuàng)建動(dòng)畫的原理是,將一套 CSS 樣式逐漸變化為另一套樣式。也就是說(shuō)通過(guò)改變CSS樣式而達(dá)到動(dòng)畫的效果,所以,要?jiǎng)討B(tài)去改變動(dòng)畫,只有修改樣式。
document.styleSheets這個(gè)接口可以獲取網(wǎng)頁(yè)上引入的link樣式表和style樣式表。如下:

拿到樣式表后就可以操作樣式啦~
insertRule方法用來(lái)給當(dāng)前樣式表插入新的樣式規(guī)則。舉個(gè)栗子:

insertRule(rule,index)
rule:要添加到樣式表的規(guī)則。index:要把規(guī)則插入或附加到 cssRules 數(shù)組中的位置。
js既然可以改變樣式了,那傳值就方便啦!
var param = 20;
var style = document.styleSheets[0];
style.insertRule("@keyframes rotate_before{from{ transform: translate(0%,0%); }to{ transform: translate(0%,-"+param +"%);}}",9);//寫入樣式
根據(jù)具體需求傳值并修改樣式就醬。
總結(jié)
到此這篇關(guān)于js動(dòng)態(tài)設(shè)置關(guān)鍵偵@keyframes的文章就介紹到這了,更多相關(guān)js動(dòng)態(tài)設(shè)置關(guān)鍵偵@keyframes內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javascript操作table(insertRow,deleteRow,insertCell,deleteCell方
本篇文章主要介紹了javascript操作table(insertRow,deleteRow,insertCell,deleteCell方法)需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2013-12-12
調(diào)用innerHTML之后onclick失效問(wèn)題的解決方法
調(diào)用innerHTML之后,onclick失效了,這也是在意料之中的,因?yàn)閕nnerHTML是以文本形式插入的button,所以無(wú)法識(shí)別onclick事件2014-01-01
BootStrap table實(shí)現(xiàn)表格行拖拽效果
這篇文章主要為大家詳細(xì)介紹了BootStrap table實(shí)現(xiàn)表格行拖拽效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12
js getBoundingClientRect使用方法詳解
這篇文章主要介紹了js getBoundingClientRect使用方法詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-07-07
JS實(shí)現(xiàn)仿百度輸入框自動(dòng)匹配功能的示例代碼
本篇文章主要是對(duì)JS實(shí)現(xiàn)仿百度輸入框自動(dòng)匹配功能的示例代碼進(jìn)行了介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2014-02-02
js實(shí)現(xiàn)驗(yàn)證碼干擾(動(dòng)態(tài))
這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)驗(yàn)證碼干擾,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-02-02
javascript實(shí)現(xiàn)起伏的水波背景效果
這篇文章主要為大家詳細(xì)介紹了javascript實(shí)現(xiàn)起伏的水波背景效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-05-05

