どのようにオリジナルのjsを使ってパチンコメッセージを書いてプラグインを注意させますか?


1.分析
メッセージがトリガされると、上から下へフェードアウトするプロセスがあります。
しばらく続けていると自動的に消えたり、ユーザーが手動でボタンをクリックしてください。
メッセージが消える時、下からフェードアウトする過程があります。
メッセージは、ポップアップを重畳することができ、最新のメッセージはメッセージリストの一番後ろに配置される。
前のメッセージが消えたら、後ろのメッセージが上にスライドする効果があります。
そしてメッセージ自体は3つの部分から構成されています。
メッセージアイコンは、異なる種類のメッセージを区別するために使用されます。
メッセージテキスト。
ボタンを閉じると、すべてのメッセージがボタンを閉じる必要があるわけではありません。
2.スタイルの実現
じゃ、私たちは元のjsであろうと、vueであろうと、まず、このメッセージの基本的なスタイルを書いてから、jsを通じてメッセージのポップアップとクローズをコントロールします。
だから、とりあえずここでhtmlとcssを書きます。

<!-- message.html -->
 <!--   css             ,  : https://www.iconfont.cn/ -->
<link rel="stylesheet" href="http://at.alicdn.com/t/font_1117508_wxidm5ry7od.css">
<link rel="stylesheet" href="./message.css" rel="external nofollow" >
<script src="./message.js"></script>
 <!--       ,             ,     id,                      -->
<div id="message-container">
 <div class="message">
 <!--      icon icon-success           font-class -->
 <div class="type icon icon-success"></div>
 <!--      -->
 <div class="text">         ~</div>
 <!--      -->
 <div class="close icon icon-close"></div>
 </div>
 <div class="message">
 <div class="type icon icon-error"></div>
 <div class="text">         ~</div>
 </div>
</div>
/* message.css */
 #message-container {
 position: fixed;
 left: 0;
 top: 0;
 right: 0;
 /*   flex    ,                ,          */
 display: flex;
 flex-direction: column;
 align-items: center;
}
#message-container .message {
 background: #fff;
 margin: 10px 0;
 padding: 0 10px;
 height: 40px;
 box-shadow: 0 0 10px 0 #eee;
 font-size: 14px;
 border-radius: 3px;
 /*           (  、  、    )         */
 display: flex;
 align-items: center;
}
#message-container .message .text {
 color: #333;
 padding: 0 20px 0 5px;
}
#message-container .message .close {
 cursor: pointer;
 color: #999;
}
 /*              ,            */
#message-container .message .icon-info {
 color: #0482f8;
}
#message-container .message .icon-error {
 color: #f83504;
}
#message-container .message .icon-success {
 color: #06a35a;
}
#message-container .message .icon-warning {
 color: #ceca07;
}
#message-container .message .icon-loading {
 color: #0482f8;
}
3.アニメーションの実現
次はこのメッセージのポップアップと動画の消失です。私達はやはりcssで実現します。
cssでカスタマイズしたアニメーションを実現するには、まず@keyframesでアニメーションルールを定義してからアニメーション属性を通してある要素に適用すればいいです。
アニメーションルールとは、アニメーションシーケンスのことであり、キーフレームの内部はcss属性を変更したいということであり、キーフレームの中にはほとんどのcss属性を書いてもいいです。アニメーションが適用されると、これらのcss属性は各キーフレームに応じて対応して変換されます。
まず@keyframesでアニメーションのルールを書きましょう。

/* message.css */
 /*            message-move-in ,      animation                。 */
@keyframes message-move-in {
 0% {
 /*       ,                 */
 /*                      0,                1,             */
 opacity: 0;
 /*   “    ”       “transform”        “translateY”          */
 /* translateY(-100%)        ,         “      ”   。 */
 transform: translateY(-100%);
 }
 100% {
 opacity: 1;
 /*         */
 transform: translateY(0);
 }
}
それから、私達はもう一つのmessage要素と同じクラスのmove-innを定義して、message-move-innというアニメルールをmove-innクラスに適用します。このように、私達はどのメッセージをポップアップさせる必要がありますか?

/* message.css */
 #message-container .message.move-in {
 /* animation                  https://developer.mozilla.org/zh-CN/docs/Web/CSS/animation */
 animation: message-move-in 0.3s ease-in-out;
}
あるメッセンジャーに一つのmove-inを追加するだけで、ポップアップ動画が実現することができます。
アニメを消すのも一つの方法です。ポップアップとは逆です。

/* message.css */
 @keyframes message-move-out {
 0% {
 opacity: 1;
 transform: translateY(0);
 }
 100% {
 opacity: 0;
 transform: translateY(-100%);
 }
}
 #message-container .message.move-out {
 animation: message-move-out 0.3s ease-in-out;
 /*              */
 animation-fill-mode: forwards;
}
animation-fill-mode:forwards;これは何ですか?アニメーションが終わるとデフォルトは元素の最初の状態に戻りますので、ここでは消えるとまた現れます。 
だから、animation-fill-mode:forwards;アニメが終わったらこの終了状態を維持するため、つまり表示しないということです。
4.jsプラグインの作成
じゃ、jsを書く前に、まず考えてみます。もしあなたがプラグインの使用者だったら、どうやってこのプラグインを使いますか?
私達のプラグインはとても簡単です。必要な時にメッセージをポップアップします。もしプラグインが私達に提供してくれるのが一種の種類だとしたら、Messageといいます。そして彼の内部にショーの方法があります。それではユーザーが実際にこのクラスを実施した後、彼のショーの方法を呼び出して、異なるパラメータが入ってきたらメッセージを呼び出すことができます。また、私たちが実践している対象は全体的に唯一であることができます。

<!-- message.html -->
<!--   ... -->
 <script>
// message         ,         。
const message = new Message();
message.show({
 type: 'success',
 text: '       ~'
});
</script>
だから、まずMessageの種類を書きます。そしてショーの方法を実現しなければなりません。

/* message.js */
 class Message {
 constructor() {
 }
 show({ type = 'info', text = '' }) {
 }
}
ここで私は直接にes 6のクラスのキーワードを使いましたが、実は彼の内部はまだ原型チェーンの形式です。クラスを使うと、より直感的にこのクラスを知ることができます。
私たちの第一部の分析によると、すべてのメッセージ要素はjsで作成される必要がありますので、お客様がhtmlコードを書く必要はありません。対象が実用化されているnew Message()の時に、メッセージ容器message-containerを作成し、その後、showメソッドを呼び出した時に直接メッセージをmessage-containerの中に挿入すればいいです。

/* message.js */
 class Message {
 /**
 *                 
 */
 constructor() {
 const containerId = 'message-container';
 //    html        message-container  
 this.containerEl = document.getElementById(containerId);
 if (!this.containerEl) {
 //     Element  ,       id message-container dom  
 this.containerEl = document.createElement('div');
 this.containerEl.id = containerId;
 //  message-container    html body  
 document.body.appendChild(this.containerEl);
 }
 }
 show({ type = 'info', text = '' }) {
 }
}
このように、私たちはconst message=new Message()を呼び出すと、domの中に自動的にMessage-containerノードを挿入します。
じゃ、一番重要なのは私達のショーの方法です。
メッセージノードを作成し、メッセージ・コンテナの末尾に追跡する。
時間を設定して、この時間が終わったら自動的にメッセージを削除します。
「閉じるボタン」のclickイベントを傍受して、ユーザが手動でメッセージを削除することができるようにする。
私たちは一歩ずつ来ます。
4.1メッセージノードを作成し、メッセージ・コンテナの末尾に追加する。

class Message {
 //   ...
 show({ type = 'info', text = '' }) {
 //     Element  
 let messageEl = document.createElement('div');
 //     class,    move-in          
 messageEl.className = 'message move-in';
 //     html   
 messageEl.innerHTML = `
 <span class="icon icon-${type}"></span>
 <div class="text">${text}</div>
 <div class="close icon icon-close"></div>
 `;
 //    message-container  
 // this.containerEl              message-container  
 this.containerEl.appendChild(messageEl);
 }
私達は呼び出してみます。

<!-- message.html -->
<!--   ... -->
 <button class="btn">      </button>
 <script>
 // message         ,         。
 const message = new Message();
 document.querySelector('.btn').addEventListener('click', () => {
 message.show({
 type: 'success',
 text: '       ~'
 });
 });
 </script>

4.2メッセージを自動的に削除する時間を設定します。

// message.js
 class Message {
 //   ...
 show({ type = 'info', text = '', duration = 2000 }) {
 //   ...
 //  setTimeout       
 setTimeout(() => {
 // Element       remove  ,           dom    !
 messageEl.remove();
 }, duration);
 }
}
 メッセージは2秒後にdomツリーから自動的に削除されましたが、動画はありません。前の方にmove-out類が書いてありますか?このクラスはメッセージと同じクラスです。今はタイミングが終わったら、このクラスをメッセージ要素に応用すればいいです。

// message.js
 class Message {
 //   ...
 show({ type = 'info', text = '', duration = 2000 }) {
 //   ...
 //  setTimeout       
 setTimeout(() => { //    move-in           ,       ,       
 messageEl.className = messageEl.className.replace('move-in', ''); //     move-out 
 messageEl.className += 'move-out';
 //              ,          dom    。
 //        move-out     messageEl.remove,             
 messageEl.addEventListener('animationend', () => {
 // Element       remove  ,           dom    !
 messageEl.remove();
 });
 }, duration);
 }
}
4.3「閉じるボタン」のclickイベントを傍受して、ユーザが手動でメッセージを削除できるようにする。
時には、ユーザーが手動でオフするまでメッセージを表示してほしいです。まず、このクローズボタンを示すかどうかを制御するためにパラメータを追加します。

// message.js
 class Message {
 //   ...
 show({ type = 'info', text = '', duration = 2000, closeable = false }) {
 //     Element  
 let messageEl = document.createElement('div');
 //     class,    move-in          
 messageEl.className = 'message move-in';
 //     html   
 messageEl.innerHTML = `
 <span class="icon icon-${type}"></span>
 <div class="text">${text}</div>
 `;
 //         
 if (closeable) {
 //         
 let closeEl = document.createElement('div');
 closeEl.className = 'close icon icon-close';
 //         message    
 messageEl.appendChild(closeEl);
 //        click  ,         close  
 //                 close  
 closeEl.addEventListener('click', () => {
 this.close(messageEl)
 });
 }
 //    message-container  
 // this.containerEl              message-container  
 this.containerEl.appendChild(messageEl);
 //    duration  0         ,             
 if (duration > 0) {
 //  setTimeout       
 setTimeout(() => {
 this.close(messageEl);
 }, duration);
 } 
 }
 /**
 *       
 *             ,                ,                      
 * @param {Element} messageEl 
 */
 close(messageEl) {
 //    move-in           ,       ,       
 messageEl.className = messageEl.className.replace('move-in', '');
 //     move-out 
 messageEl.className += 'move-out';
 //              ,          dom    。
 //        move-out     messageEl.remove,             
 messageEl.addEventListener('animationend', () => {
 // Element       remove  ,           dom    !
 messageEl.remove();
 });
 }
}
私達は呼び出してみます。

<!-- message.html -->
<!--   ... -->
 <button class="btn">      </button>
 <script>
 // message         ,         。
 const message = new Message();
 document.querySelector('.btn').addEventListener('click', () => {
 message.show({
 type: 'warning',
 text: '         ',
 duration: 0, //       
 closeable: true, //      
 });
 });
 </script>

実はもう書いたのは大体同じです。でも、まだいくつかの問題があります。例えば、私達が2つ以上のメッセージを弾いた時、前のメッセージが消えたら、下のメッセージは直接上の位置にジャンプします。とても硬くて、何のスライドもありません。
cssのtransion属性によって、meesageの高さを小さくすることができます。このようにして、下の要素は変化によって徐々に上に移動します。

/* message.css */
/*   ... */
 #message-container .message {
 background: #fff;
 margin: 10px 0;
 padding: 0 10px;
 height: 40px;
 box-shadow: 0 0 10px 0 #ccc;
 font-size: 14px;
 border-radius: 3px;
 /*           (  、  、    )         */
 display: flex;
 align-items: center;
/*         , message      margin              */
 transition: height 0.2s ease-in-out, margin 0.2s ease-in-out;
} 
/*   ... */
そして、私たちはMessage類のclose方法で変更するだけです。

 close(messageEl) {
 //    move-in           ,       ,       
 messageEl.className = messageEl.className.replace('move-in', '');
 //     move-out 
 messageEl.className += 'move-out';
 // move-out                  0
 //      css    transition  ,          
 messageEl.addEventListener('animationend', () => {
 messageEl.setAttribute('style', 'height: 0; margin: 0');
 });
 //        transition         ,          dom    。
 messageEl.addEventListener('transitionend', () => {
 // Element       remove  ,           dom    !
 messageEl.remove();
 });
 }
締めくくりをつける
はい、基本的にはもう書きましたが、各ブラウザの互換性のために、Babelトランスコードを使って、発表したいなら、webpackでjsとcssを一緒に包装してもいいです。
しかし、私たちはまだ一つのシーンを考慮していません。現在のクローズメッセージはすべて対象の内部でcloseメソッドを呼び出して実現します。もし外部でメッセージのクローズを制御してほしいです。例えば、サーバーに要請した時に、loadingのメッセージをポップアップします。サーバーがデータを返した後、どうやってこのメッセージを閉じますか?
簡単です。皆さん自分で叶えてください。
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。