2

css @keyframes를 사용하여 원의 기본 애니메이션을 만들었습니다. 자바 스크립트를 사용하여 원 안을 클릭하여 애니메이션 시작/정지를 트리거합니다.deleteRule CSSKeyframesRule 메서드는 IE11의 동작을 혼동합니다.

는 애니메이션 자체는 5 (루프) 단계로 나눌 수 있습니다 :
일시 정지 - 확장 - 일시 정지 수축 - 일시 정지

내가 달성하고자하는 목표는 (아래 @keyframes CSS의 섹션을 참조) 결국 애니메이션 기간을 설정하고 키 프레임 값을 변경할 수 있습니다 (예 : 일시 중지 및 확장/축소 기간에 대한 입력 필드가 있으므로 세부 사항은이 질문의 범위와 관련이 없습니다). 이 작업을 수행하기 위해 JavaScript 함수를 조합하여 작동 방법을 테스트하기 위해 onload으로 설정했습니다.

내 HTML :

<!doctype html> 
<html> 
    <head> 
     <meta content="text/html;charset=utf-8" http-equiv="Content-Type"> 
     <meta content="utf-8" http-equiv="encoding"> 

     <link rel="stylesheet" href="style.css"> 
     <script src = "animation.js"></script> 

    </head> 
    <body onload=setAnimationDuration(1,1)> 
     <div id="circle" class='circle-paused' onclick=cssAnimation()></div> 
    </body> 
</html> 

내 CSS :

#circle { 
position: absolute; 
top: 50%; 
left: 50%; 
transform: translateX(-50%) translateY(-50%); 
} 

.circle-paused { 
width: 9%; 
padding-top: 9%; 
border-radius: 50%; 
background-color: #800080; 
margin: auto; 
} 

.circle-animated { 
/* 2 sec pause 4 sec expand_shrink*/ 
width: 9%; 
padding-top: 9%; 
-webkit-animation-name: my-circle; /* Safari 4.0 - 8.0 */ 
-webkit-animation-duration: 12s; /* Safari 4.0 - 8.0 */ 
animation-name: my-circle; 
animation-duration: 12s; 
animation-iteration-count: infinite; 
animation-timing-function: linear; 
border-radius: 50%; 
margin: auto; 
} 

@keyframes my-circle { 
0% {background-color: #800080; width: 9%; padding-top: 9%;} 
33.3% {background-color: #D8BFD8; width: 28%; padding-top: 28%;} 
50% {background-color: #D8BFD8; width: 28%; padding-top: 28%;} 
83.3% {background-color: #800080; width: 9%; padding-top: 9%;} 
100% {background-color: #800080; width: 9%; padding-top: 9%;} 
} 

내 자바 스크립트 :

function cssAnimation() { 
    if (document.getElementById('circle').className == 'circle-paused') { 
    document.getElementById('circle').className = 'circle-animated' 
    } else { 
    document.getElementById('circle').className = 'circle-paused' 
    } 
} 


function findKeyframes(animation_name) { 
    // get list of current keyframe rules 
    var style_sheet = document.styleSheets; 
    for (var i = 0; i < style_sheet.length; ++i) { 
    for (var j = 0; j < style_sheet[i].cssRules.length; ++j) { 
     // type 7 correspond to CSSRule.KEYFRAMES_RULE, for more info see https://developer.mozilla.org/en-US/docs/Web/API/CSSRule 
     if (style_sheet[i].cssRules[j].type == 7 && style_sheet[i].cssRules[j].name == animation_name) { 
     return style_sheet[i].cssRules[j]; 
     } 
    } 
    } 
    // keyframe rules were not found for given animation_name 
    return null; 
} 


function getPercentage(total, fraction) { 
    // Returns what percentage the fraction is from total 
    // The result is rounded to 1 decimal place 
    return Math.round(((100/total) * fraction) * 10)/10; 
} 


function setAnimationDuration(pause, expand_shrink) { 
    var total_animation_duration = (pause * 2) + (expand_shrink * 2) 
    var pause_percentage = getPercentage(total_animation_duration, pause) 
    var expand_shrink_percentage = getPercentage(total_animation_duration, expand_shrink) 

    var pause1 = pause_percentage + expand_shrink_percentage; 
    var shrink = pause1 + expand_shrink_percentage; 

    var frame_percentage_list = [0, expand_shrink_percentage, pause1, shrink, 100] 

    var key_frame_list = findKeyframes('my-circle') 
    var new_rule_list = [] 
    var to_be_removed_key_list = [] 

    //create array of new rules to be inserted 
    //collecting old keys of rules to be deleted 
    for(var i = 0; i < key_frame_list.cssRules.length; i++) { 
    var current_rule = key_frame_list.cssRules[i].cssText 

    to_be_removed_key_list.push(key_frame_list.cssRules[i].keyText) 
    new_rule_list.push(current_rule.replace(/[+-]?([0-9]*[.])?[0-9]+%/, frame_percentage_list[i] + '%')) 
    } 

    // delete old rules 
    for(var i = 0; i < to_be_removed_key_list.length; i++) { 
    key_frame_list.deleteRule(to_be_removed_key_list[i]) 
    } 

    // populate new ruels 
    for(var i = 0; i < new_rule_list.length; i++) { 
    key_frame_list.appendRule(new_rule_list[i]) 
    } 


    document.getElementById('circle').style.animationDuration = total_animation_duration + "s" 
} 

Code above, on JSFiddle

문제 자체 :
코드는 FireFox (55.0.3), Chrome (61.0) 및 Safari (11.0)에서 예상대로 작동합니다. 그러나 IE11에서 테스트를 시작했을 때 key_frame_list.deleteRule('rule_key')Invalid argument 오류를 발생시키는 것을 발견했습니다. 이 문제를 조사하는 동안 this article (IE 문제를 해결하지는 못했지만 CSS 애니메이션의 전반적인 이해를 향상 시켰습니다). MSDN에서 deleteRule에 관한 두 개의 참조를 찾으 셨습니다 : onetwo. the second one에서 나는 무엇을 의미하는지 정말로 이해하지 못했지만, :

키는 0과 1 사이의 숫자로 해결되어야합니다. 그렇지 않으면 규칙이 무시됩니다.

IE에서 문자열 키 대신 deleteRule에 색인을 전달해야한다고 가정했습니다. 그래서 나는 IE 콘솔에서 내 가정을 확인하려고했습니다.

key_frame_list.deleteRule(0) -
key_frame_list.deleteRule(1) (0 %입니다) 첫 번째 규칙을 제거 - 제거합니다

var key_frame_list = findKeyframes('my-circle') 
key_frame_list.cssRules.length => 5 
key_frame_list.deleteRule(0) 
key_frame_list.cssRules.length => 4 
key_frame_list.deleteRule(1) 
key_frame_list.cssRules.length => 3 
key_frame_list.deleteRule(0) 
key_frame_list.deleteRule(1) 
key_frame_list.deleteRule(2) 
... 
key_frame_list.cssRules.length => 3 

어떤 일이 일어나고 것은 : 여기에 내가 발견 한 것입니다 (주어진 내 JS 코드는 온로드에) (100 %) 마지막 규칙 그 후
상관없이 내가 key_frame_list.deleteRule()에 전달하는 인덱스 key_frame_list.cssRules.length 3.
내 기대 내가 key_frame_list.deleteRule(0)으로 재발 할 수 있어야하고, 제거이었다 남아있는 모든 규칙 (각 규칙 삭제 후 인덱스가 바뀔 것으로 예상했기 때문에).

지금, 나는 이해하고 싶습니다

가 무엇 IE에서 deleteRule를 사용하는 적절한 방법 (기본적으로 '? 내가 뭔가 잘못하고 있는가')이다
  1. (또는 다른 방법을 사용할 필요가있는 경우) ?
  2. 5 개 중 2 개 이상을 삭제할 수없는 이유는 무엇입니까?
  3. Firefox, Chrome 및 IE11에서 동일한 인수로 작동 할 수있는이 방법에 적합한 방법이 있습니까?

답변

3
  1. 익스플로러에 deleteRule를 사용 (또는 다른 방법을 사용해야하는 경우) 적절한 방법 (기본적으로, '내가 뭔가 잘못하고 오전?') 란 무엇입니까?

  2. 이유는 다섯 가지 중 두 개 이상의 규칙을 삭제할 수 없습니다 무엇입니까?

    첫 번째 MSDN 링크는 적용되지 않습니다. deleteRule() 메서드는 키 프레임 규칙이 아닌 최상위 규칙에 적용됩니다.

    텍스트는 "키는 0과 1 사이의 숫자로 해결되어야합니다. 그렇지 않으면 규칙이 무시됩니다."라는 텍스트가 표시됩니다. 두 번째 링크의 실제로는 2013 WD of css-animations에서 가져온 것으로, 0 % -100 % 키 프레임 선택기가 포함 된 문자열 대신 Internet Explorer에서 백분율을 나타내는 십진수가 필요하다는 것을 의미합니다. 인수는 색인을 나타내지 않습니다.

    0 % 키 프레임 규칙의 경우 IE는 값 0을 기대합니다. 100 % 키 프레임 규칙의 경우 IE는 값 1을 기대합니다. 더 0 % 규칙은 아무것도하지 않는 것 deleteRule(0)에 추가적인 통화를 유지하지 않는 경우 0 % 룰 일단

    key_frame_list.deleteRule(0)  // Deletes the 0% keyframe rule 
    key_frame_list.deleteRule(0.333) // Deletes the 33.3% keyframe rule 
    key_frame_list.deleteRule(1)  // Deletes the 100% keyframe rule 
    

    삭제되었습니다와 33.3 %의 키 프레임 규칙, IE는 부동 소수점 값 0.333은 기대하고있다.

    키 프레임이 100 %를 초과 할 수 없기 때문에 deleteRule(2)은 존재할 수없는 200 % 키 프레임 규칙을 삭제한다는 의미이므로 의미가 없습니다.

  3. Firefox, Chrome 및 IE11에서 동일한 인수로 작동하는이 방법에 적합한 방법이 있습니까?

    아니오; Internet Explorer 11은 2013 년 WD (Internet Explorer 10 출시 이후 2012 년과 2013 년 사이에 개발 됨)를 따르며 구현이 현재 표준 인 the deleteRule() method has been changed to accept a string argument instead of a numeric argument과 일치하지 않음을 의미합니다.

    이것은 API가 호환되지 않으므로 깨끗한 해결 방법이 없음을 의미합니다. 두 가지 인수를 모두 시도하면됩니다. 나는 당신의 바이올린에 다음 문을 changed :

    // delete old rules 
    for(var i = 0; i < to_be_removed_key_list.length; i++) { 
        key_frame_list.deleteRule(to_be_removed_key_list[i]) 
    } 
    

    에 :

    // delete old rules 
    for(var i = 0; i < to_be_removed_key_list.length; i++) { 
        try { 
        key_frame_list.deleteRule(to_be_removed_key_list[i]) 
        } catch (e) { 
        key_frame_list.deleteRule(+(parseFloat(to_be_removed_key_list[i])/100).toFixed(3)) 
        } 
    } 
    

    +(parseFloat(to_be_removed_key_list[i])/100).toFixed(3) 비트 계정으로 반올림 오류를 복용하는 숫자 값을 백분율 문자열로 변환합니다.IEEE-754 부동 소수점 숫자에 내재 된 반올림 오류로 인해 API가 처음에 변경된 것입니다 (즉, 문자열이 항상 예상되는 appendRule() 메서드와의 일관성). 이후 변경된 경우는 예외입니다. Internet Explorer 11이 출시되었으며 이후로는 IE11 will no longer receive platform updates으로, 이는 IE11이 이전 WD 구현과 관련되어 있음을 의미합니다 (강조해야하는 것은 현재 개발 당시 였음).