質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
CSS3

CSS(Cascading Style Sheet)の第3版です。CSS3と略されることが多いです。色やデザインを柔軟に変更することが可能になります。

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

Q&A

解決済

1回答

1560閲覧

setAttributeで行った2回目のCSSアニメーションのanimation-fill-mode: forwards;が効かない。

vfxl9827

総合スコア11

CSS3

CSS(Cascading Style Sheet)の第3版です。CSS3と略されることが多いです。色やデザインを柔軟に変更することが可能になります。

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

0グッド

0クリップ

投稿2020/12/13 13:28

編集2020/12/14 11:27

cssでスライドして移動していくアニメーションについてです。

以下のコードでコンボボックスで「1ページ」を押して起動したときに
本来ならば 「1ページ(赤)」→「0ページ(黒)」→「1ページ(赤)」 で止まるコードを書いたのはずですが,setAttributeで行った2回目のCSSアニメーションのanimation-fill-mode: forwards;が効かず 「1ページ(赤)」→「0ページ(黒)」→「1ページ(赤)」→一瞬で「2ページ(ピンク)」 になってしまうのですが,
どうすればよいでしょうか?


※コマンドの動きの特性※
・現在位置が[1ページ13ページ]の状態で[2ページ13ページ]を選択して実行した場合は途中のページを通過しながら直接移動。
・現在位置が[2ページ~13ページ]の状態で[1ページ]を選択して実行した場合は途中のページを通過し,更に一旦「1ページ」を通過してから「0ページ(黒)」まで巻き上げてから「1ページ」に巻き戻るという動作をする。
・現在位置が[1ページ]の状態で[1ページ]を選択して実行した場合は「0ページ(黒)」まで巻き上げてから「1ページ」に巻き戻るという動作をする。
・再選択可能。
・意図的にすべての動作において止まるたびに一瞬少し過ぎてから戻るように動くアニメーションをする。

html

1<div class="parent"> 2<span class="child" id="box"> 3 <div style=" width:592px;height:400px; background-color: #000;">0ページ</div> 4 <div style=" width:592px;height:400px; background-color: #ff7f7f;">1ページ</div> 5 <div style=" width:592px;height:400px; background-color: #ff7fbf;">2ページ</div> 6 <div style=" width:592px;height:400px; background-color:#ff7fff;">3ページ</div> 7 <div style=" width:592px;height:400px; background-color: #bf7fff;">4ページ</div> 8 <div style=" width:592px;height:400px; background-color: #7f7fff;">5ページ</div> 9 <div style=" width:592px;height:400px; background-color: #7fbfff;">6ページ</div> 10 <div style=" width:592px;height:400px; background-color:#7fffff;">7ページ</div> 11 <div style=" width:592px;height:400px; background-color: #7fffbf;">8ページ</div> 12 <div style=" width:592px;height:400px; background-color:#7fff7f;">9ページ</div> 13 <div style=" width:592px;height:400px; background-color: #bfff7f;">10ページ</div> 14 <div style=" width:592px;height:400px; background-color: #ffff7f;">11ページ</div> 15 <div style=" width:592px;height:400px; background-color:#ffbf7f;">12ページ</div> 16 <div style=" width:592px;height:400px; background-color:#000;">13ページ</div> 17</span> 18</div> 19 20<input type="button" onclick="selected();" value=" 起動 " id="btn2"/> 21<select id="divno"> 22<option value="0" disabled >選択</option> 23<option value="1" selected>1ページ</option> 24<option value="2" >2ページ</option> 25<option value="3">3ページ</option> 26<option value="4">4ページ</option> 27<option value="5">5ページ</option> 28<option value="6">6ページ</option> 29<option value="7">7ページ</option> 30<option value="8">8ページ</option> 31<option value="9">9ページ</option> 32<option value="10">10ページ</option> 33<option value="11">11ページ</option> 34<option value="12">12ページ</option> 35</select>

JS

1var x, y; // box の座標 2 3 // コンボボックス 4 function selected() { 5 const objBox = document.getElementById("box"); 6 const cssStyle = window.getComputedStyle(objBox); 7 y = parseInt(cssStyle.top.match(/(.*)px/)[1]); 8 9 let anim = ''; 10 let divnofrom = (y / -400); // 現在の表示位置 11 let divnoto = document.getElementById('divno').selectedIndex; // 移動先の表示位置 12 let move = 0; // 移動距離 13 if (2 > divnoto){ 14 move = (divnofrom - divnoto + 1); 15 anim = 'moveUp' + move; 16 }else if (divnofrom < divnoto){ 17 move = (divnoto - divnofrom); 18 anim = 'moveDown' + move; 19 }else if (divnofrom > divnoto){ 20 move = (divnofrom - divnoto); 21 anim = 'moveUp' + move; 22 } 23 24 if (anim !== '') { 25 objBox.style.animationDuration = move + 's'; // アニメの実行速度設定 26 objBox.style.animationName = anim; // アニメ開始 27 btnsDisabled(true); // ボタン無効化 28 } 29 } 30 31 // animation 終了時の処理 32 document.addEventListener('animationend', () => { 33 let divnofrom = (y / -400); // 現在の表示位置 34 let divnoto = document.getElementById('divno').selectedIndex; // 移動先の表示位置 35 36 const objBox = document.getElementById("box"); 37 const cssStyle = window.getComputedStyle(objBox); 38 const arr = cssStyle.transform.match(/((.*))/)[1].split(","); // 文字列 matrix(a, b, c, d, cx, cy) を分解 39 y += parseInt(arr[5]); // transform.y の値を加える 40 41 if (2 > divnoto){ 42 objBox.setAttribute("rel" , "endmode0"); // この行を追加 43 }else if (divnofrom < divnoto){ 44 objBox.setAttribute("rel" , "endmode1"); // この行を追加 45 }else if (divnofrom > divnoto){ 46 objBox.setAttribute("rel" , "endmode2"); // この行を追加 47 } 48 49 objBox.style.transform = ''; // アニメした transform を消す 50 objBox.style.top = y + 'px'; 51 objBox.style.animationName = ''; // animationName を消す。こうしないと、次回に同じ方向のアニメが効かない。 52 objBox.style.animationDuration = ''; 53 objBox.style.animationFillMode = ''; 54 btnsDisabled(false); // ボタン有効化 55 56 }); 57 58 59 // 矢印ボタンの有効化/無効化 60 function btnsDisabled(arg) { 61 let btns = document.getElementsByTagName("input"); 62 for (let i = 0; i < btns.length; i++) { 63 btns[i].disabled = arg; 64 } 65 document.getElementById('divno').disabled = arg; // コンボボックス 66 }

css

1 2*[rel="endmode0"]{ 3animation-name: endmove0; 4animation-duration: 2s; 5 animation-timing-function: linear; 6 animation-fill-mode: forwards; 7} 8*[rel="endmode1"]{ 9animation-name: endmove1; 10animation-duration: 1s; 11 animation-timing-function: linear; 12 animation-fill-mode: forwards; 13} 14*[rel="endmode2"]{ 15animation-name: endmove2; 16animation-duration: 1s; 17 animation-timing-function: linear; 18 animation-fill-mode: forwards; 19} 20 21div.parent { 22 position: relative; 23 width: 592px; 24 height: 400px; 25 border: 1px solid #ddd; 26 overflow: hidden; 27} 28span.child { 29 position: absolute; 30 width : 592px; 31 height: 5600px; 32 left: 0px; 33 top:-400px; 34 animation-iteration-count: 1; 35 animation-timing-function: linear; 36 animation-fill-mode: forwards; 37} 38 39@keyframes endmove0 { 40 50% { transform:translateY(-420px); } 41 100% { transform:translateY(-400px); }} 42@keyframes endmove1 { 43 0% { transform:translateY(0px); } 44 5% { transform:translateY(-20px); } 45 100% { transform:translateY(0px);}} 46@keyframes endmove2 { 47 0% { transform:translateY(0px); } 48 5% { transform:translateY(20px); } 49 100% { transform:translateY(0px);}} 50 51 52@keyframes moveDown1 { 530% { transform:translateY(0px); } 54 100% { transform:translateY(-400px); }} 55@keyframes moveDown2 { 56 100% { transform:translateY(-800px); }} 57@keyframes moveDown3 { 58 100% { transform:translateY(-1200px); }} 59@keyframes moveDown4 { 60 100% { transform:translateY(-1600px); }} 61@keyframes moveDown5 { 62 100% { transform:translateY(-2000px); }} 63@keyframes moveDown6 { 64 100% { transform:translateY(-2400px); }} 65@keyframes moveDown7 { 66 100% { transform:translateY(-2800px); }} 67@keyframes moveDown8 { 68 100% { transform:translateY(-3200px); }} 69@keyframes moveDown9 { 70 100% { transform:translateY(-3600px); }} 71@keyframes moveDown10 { 72 100% { transform:translateY(-4000px); }} 73@keyframes moveDown11 { 74 100% { transform:translateY(-4400px); }} 75@keyframes moveDown12 { 76 100% { transform:translateY(-4800px); }} 77 78 79@keyframes moveUp1 { 80 100% { transform:translateY(400px); }} 81@keyframes moveUp2 { 82 100% { transform:translateY(800px); }} 83@keyframes moveUp3 { 84 100% { transform:translateY(1200px); }} 85@keyframes moveUp4 { 86 100% { transform:translateY(1600px); }} 87@keyframes moveUp5 { 88 100% { transform:translateY(2000px); }} 89@keyframes moveUp6 { 90 100% { transform:translateY(2400px); }} 91@keyframes moveUp7 { 92 100% { transform:translateY(2800px); }} 93@keyframes moveUp8 { 94 100% { transform:translateY(3200px); }} 95@keyframes moveUp9 { 96 100% { transform:translateY(3600px); }} 97@keyframes moveUp10 { 98 100% { transform:translateY(4000px); }} 99@keyframes moveUp11 { 100 100% { transform:translateY(4400px); }} 101@keyframes moveUp12 { 102 100% { transform:translateY(4800px); }}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こんばんは。

animationendイベントが、endmove0終了時にも発火していますが、これは想定されていますか?

とりあえず、以下のように変更をしてどのようになるか試してみてください。

js

1 btnsDisabled(false); // ボタン有効化 2 3 },{once:true}); // 1回限りに変更

本格的に対応するにはanimationNameプロパティを参照して分岐する必要があると思います。

AnimationEvent.animationName - Web API | MDN

投稿2020/12/14 09:14

Lhankor_Mhy

総合スコア35871

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

vfxl9827

2020/12/14 11:29 編集

ご対応ありがとうございます。 >>nimationendイベントが、endmove0終了時にも発火していますが、これは想定されていますか?<< 上記の点は想定しております。moveDownXまたはmoveUpX実行後endmodeXを実行して終了したのち,再度新たにリストを選択して,moveDownXまたはmoveUpXを実行...と繰り返すためには,animationendにてアニメーションで使った『objBox.style.』を空にしないと繰り返し上書きして動作しないため必要と考えております。 上記のonce:trueを付け加えて実行したところやはり一度のみの実行になりますので質問した『「1ページ(赤)」→「0ページ(黒)」→「1ページ(赤)」』は解決されましたが,ほかのページの移動や次の動作で不具合があります。 無知でご迷惑をおかけすることがあるかと思いますが,大変恐縮ではございますがご教示のほど願います。 ※コマンドの動きの特性※(質問欄にも記述しました) ・現在位置が[1ページ~13ページ]の状態で[2ページ~13ページ]を選択して実行した場合は途中のページを通過しながら直接移動。 ・現在位置が[2ページ~13ページ]の状態で[1ページ]を選択して実行した場合は途中のページを通過し,更に一旦「1ページ」を通過してから「0ページ(黒)」まで巻き上げてから「1ページ」に巻き戻るという動作をする。 ・現在位置が[1ページ]の状態で[1ページ]を選択して実行した場合は「0ページ(黒)」まで巻き上げてから「1ページ」に巻き戻るという動作をする。 ・再選択可能。 ・意図的にすべての動作において止まるたびに一瞬少し過ぎてから戻るように動くアニメーションをする。
Lhankor_Mhy

2020/12/14 13:08

>再度新たにリストを選択して,moveDownXまたはmoveUpXを実行...と繰り返すためには,animationendにてアニメーションで使った『objBox.style.』を空にしないと繰り返し上書きして動作しないため必要と考えております。 リスト再選択時でいいように思えます。
vfxl9827

2020/12/15 06:30

色々調べたところ, animationend内の const arr = cssStyle.transform.match(/((.*))/)[1].split(","); // 文字列 matrix(a, b, c, d, cx, cy) を分解 y += parseInt(arr[5]); // transform.y の値を加える objBox.style.top = y + 'px'; の3っつにおいて計算の不具合を起こしているみたいです。ここについて教えてください。
Lhankor_Mhy

2020/12/15 06:45

まさにおっしゃるとおりの原因だと思います。 回答にも書きましたが、解決するためには animationName をチェックして分岐する必要があるのではないかと思います。 具体的に言うと、animation-fill-mode: forwards としているため、transform:translateY(-400px) と top: -200px の双方が効いているのが原因だと思います。topは次の動作のために残しておかなくてはいかないでしょうから、その他の方法で調整をする必要があるのでは。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問