フロントエンドにアニメーション遷移効果を実装する方法

フロントエンドにアニメーション遷移効果を実装する方法

導入

アニメーションの概念は非常に幅広く、さまざまな分野に関係します。ここでは、ゲーム分野の Animate はもちろんのこと、フロントエンド Web アプリケーション レベルに範囲を絞ります。まずは最も単純なものから始めましょう。

現在、ほとんどの Web アプリケーションは、Vue、React などのフレームワークに基づいて開発されています。これらはすべて、データ駆動型のビューに基づいています。そこで、これらのフレームワークが存在しなかったときにアニメーションやトランジション効果をどのように実装したかと、データ駆動型を使用してそれらを実現する方法を比較してみましょう。

従来のトランジションアニメーション

アニメーション効果はエクスペリエンスにおいて非常に重要な役割を果たしますが、多くの開発者にとっては非常に弱いリンクとなる可能性があります。 CSS3 の登場以降、多くの初心者にとって最もよく使用されるアニメーション遷移は CSS3 の機能であると考えられます。

CSS トランジションアニメーション

CSSでトランジションアニメーションを開始するのは非常に簡単です。トランジション属性を記述するだけです。デモはこちらです

<div id="app" class="normal"></div>
。普通 {
  幅: 100ピクセル;
  高さ: 100px;
  背景色: 赤;
  遷移: すべて 0.3 秒;
}
.normal:hover {
  背景色: 黄色;
  幅: 200ピクセル;
  高さ: 200px;
}

効果は依然として非常に良好です。CSS3 トランジションは基本的にほとんどのアニメーション要件を満たしています。満たされない場合は、実際の CSS3 アニメーションもあります。

アニメーション-CSS

有名な CSS アニメーション ライブラリ。使用している人なら誰でも知っています。

CSS3 トランジションでも CSS3 アニメーションでも、クラス名を切り替えるだけで使用できます。コールバック処理をしたい場合は、ブラウザも ontransitionend や onanimationend などのアニメーション フレーム イベントを提供しており、JS インターフェイスを通じてリッスンできます。

var el = document.querySelector('#app')
el.addEventListener('transitionstart', () => {
  console.log('遷移開始')
})
el.addEventListener('transitionend', () => {
  console.log('遷移終了')
})

さて、これが CSS アニメーションの基礎です。ほとんどのアニメーション遷移要件は JS カプセル化によっても実現できますが、CSS でサポートされている属性アニメーションしか制御できないという制限があり、制御は比較的弱いです。

jsアニメーション

結局のところ、js はカスタム コーディング プログラムなので、アニメーションを強力に制御し、CSS ではサポートされていないさまざまな効果を実現できます。 では、js でアニメーションを実装するための基礎は何でしょうか?
簡単に言えば、アニメーションとは、タイムライン上の要素のプロパティを継続的に更新し、ブラウザにそれを再描画させることで、視覚的にアニメーションになることです。では、早速例を挙げてみます。

 <div id="app" class="normal"></div>
// Tween は単なるイージング関数です var el = document.querySelector('#app')
var time = 0、begin = 0、change = 500、duration = 1000、fps = 1000 / 60;
関数 startSport() {
  var val = Tween.Elastic.easeInOut(時間、開始、変更、継続時間);
  el.style.transform = 'translateX(' + val + 'px)';
  時間 <= 継続時間の場合
    時間 += fps
  } それ以外 {
    console.log('アニメーションが終了し、再開します')
    時間 = 0;
  }
  タイムアウトを設定する(() => {
    スポーツを始める()
  }, fps)
}
スポーツを始める()

タイムライン上のプロパティを継続的に更新するには、setTimeout または requestAnimation を使用します。 Tweenイージング関数は補間の概念に似ています。一連の変数を与えると、その間隔内の任意の時点で値を取得できます。これは純粋な数式であり、ほぼすべてのアニメーションフレームワークで使用されています。詳しく知りたい場合は、Zhang XinxuのTween.jsを参照してください。

さて、このミニマリスト デモは、js アニメーションのコア基盤でもあります。プログラムを通じて遷移値の生成プロセスを完全に制御していることがわかります。他のすべての複雑なアニメーション メカニズムはこのパターンに従います。

従来のフレームワークと Vue/React フレームワークの比較

これまでの例では、CSS トランジションでも JS トランジションでも、DOM 要素を直接取得し、DOM 要素に対して属性操作を実行します。
Vue と React はどちらも仮想 DOM の概念を導入しています。データがビューを駆動します。DOM を操作せず、データのみを制御するようにします。では、データ レベルでアニメーションを駆動するにはどうすればよいでしょうか。

Vue フレームワークでのトランジションアニメーション

まずは文書を読んでみてください

Vue トランジションアニメーション

使い方については説明しません。Vue が提供するトランジション コンポーネントがアニメーション トランジション サポートをどのように実装しているかを分析しましょう。

遷移コンポーネント

まず、遷移コンポーネントのコード(パス「src/platforms/web/runtime/components/transition.js」)を確認します。
コアコードは次のとおりです。

// 補助関数、propsデータをコピーするエクスポート関数 extractTransitionData (comp: Component): Object {
 定数データ = {}
 const オプション: ComponentOptions = comp.$options
 // 小道具
 for (const キー in options.propsData) {
  データ[キー] = comp[キー]
 }
 // イベント。
 定数リスナー: ?Object = options._parentListeners
 for (const キー in リスナー) {
  data[camelize(キー)] = listeners[キー]
 }
 データを返す
}

エクスポートデフォルト{
 名前: 'transition'、
 プロパティ: transitionProps、
 abstract: true, // 抽象コンポーネント。DOM にレンダリングされないことを意味し、開発に役立ちます render (h: Function) {
  // スロットを通じて実際のレンダリング要素の子要素を取得します
  子: any = this.$slots.default とします。
  
  定数モード: 文字列 = this.mode

  定数rawChild: VNode = children[0]

  // 一意のキーを追加する
  // コンポーネントインスタンス。このキーは保留中の離脱ノードを削除するために使用されます
  // 入力中。
  定数 id: 文字列 = `__transition-${this._uid}-`
  子.key = getKey(id)
    : 子.キー
  // props を通じて渡されたデータを保存するため、transition 属性をデータに挿入します。const data: Object = (child.data || (child.data = {})).transition = extractTransitionData(this)
  const oldRawChild: VNode = this._vnode
  定数 oldChild: VNode = getRealChild(oldRawChild)

  
   // 動的な遷移にとって重要です!
   const oldData: オブジェクト = oldChild.data.transition = extend({}, data)
 // 遷移モードを処理する
   if (mode === 'out-in') {
    // プレースホルダーノードを返し、終了時にキューの更新を行う
    this._leaving = true
    mergeVNodeHook(oldData, 'afterLeave', () => {
     this._leaving = false
     this.$forceUpdate()
    })
    プレースホルダー(h, rawChild)を返す
   } それ以外の場合 (モード === 'in-out') {
    遅延させる
    const performLeave = () => { delayedLeave() }
    mergeVNodeHook(データ、'afterEnter'、performLeave)
    mergeVNodeHook(データ、'enterCancelled'、performLeave)
    mergeVNodeHook(oldData、'delayLeave'、leave => { delayedLeave = leave })
   }
  rawChildを返す
 }
}

ご覧のとおり、このコンポーネント自体の機能は比較的単純です。スロットを通じてレンダリングする必要がある要素の子要素を取得し、transition の props 属性データを、ライフサイクルへの後続の挿入のために data の transition 属性にコピーします。ライフサイクル管理には mergeVNodeHook が使用されます。

モジュール/移行

次に、ライフサイクル関連のパスを確認します。
src/プラットフォーム/web/ランタイム/モジュール/transition.js
まずデフォルトのエクスポートを見てみましょう。

関数 _enter (_: 任意、vnode: VNodeWithData) {
 (vnode.data.show !== true) の場合 {
  入力(vnode)
 }
}
デフォルトの inBrowser をエクスポートしますか? {
 作成: _enter、
 アクティブ化: _enter、
 削除 (vnode: VNode、rm: 関数) {
  (vnode.data.show !== true) の場合 {
   退出(vnode, rm)
  } 
 }
} : {}

ここではブラウザ環境を分析しているため、inBrowser は true と見なされます。
次に、enter 関数と leave 関数を見てみましょう。まずは enter 関数を見てみましょう。

エクスポート関数 addTransitionClass (el: any, cls: string) {
 const transitionClasses = el._transitionClasses || (el._transitionClasses = [])
 (遷移クラスのインデックス(cls)<0)の場合){
  遷移クラス.push(cls)
  クラスを追加します(el, cls)
 }
}

エクスポート関数removeTransitionClass(el: any, cls: string) {
 if (el._transitionClasses) {
  削除(el._transitionClasses、cls)
 }
 クラスを削除します(el, cls)
}
エクスポート関数 enter (vnode: VNodeWithData, toggleDisplay: ?() => void) {
 定数 el: 任意 = vnode.elm

 // 今すぐLeaveコールバックを呼び出す
 if (isDef(el._leaveCb)) {
  el._leaveCb.cancelled = true
  el._leaveCb()
 }
 // 前のステップでデータに注入された遷移データ const data = resolveTransition(vnode.data.transition)
 if (isUndef(データ)) {
  戻る
 }

 /* イスタンブールは無視します */
 if (isDef(el._enterCb) || el.nodeType !== 1) {
  戻る
 }

 定数{
  css、
  タイプ、
  入力クラス、
  クラスに入る、
  アクティブクラスを入力、
  表示クラス、
  表示されるクラス、
  アクティブクラスを表示、
  入る前、
  入力、
  入力後、
  キャンセルされました、
  前に現れる、
  現れる、
  出現後、
  表示キャンセル、
  間隔
 } = データ

 
 コンテキストをactiveInstanceにする
 transitionNode = activeInstance.$vnode とします。

 const isAppear = !context._isMounted || !vnode.isRootInsert

 if (isAppear && !appear && appear !== '') {
  戻る
 }
 // 適切なタイミングで注入するクラス名を取得します
 const startClass = isAppear && appearClass
  ?表示クラス
  :クラスを入力
 定数 activeClass = isAppear && appearActiveClass
  ?appearActiveClass
  :アクティブクラスを入力
 定数 toClass = isAppear && appearToClass
  ?クラスに現れる
  :クラスに入る

 定数 beforeEnterHook = isAppear
  ? (表示される前 || 入力する前)
  : 前に入る
 const enterHook = isAppear
  ? (typeof appear === 'function' ? appear : enter)
  : 入力
 定数 afterEnterHook = isAppear
  ? (afterAppear || afterEnter)
  :afterEnter
 const enterCancelledHook = isAppear
  ? (キャンセル表示 || キャンセル入力)
  :enterキャンセル

 定数明示的入力期間: 任意 = toNumber(
  isObject(期間)
   ? 期間.入力
   : 間隔
 )

 const expectsCSS = css !== false && !isIE9
 const userWantsControl = getHookArgumentsLength(enterHook)
 // 遷移終了後のコールバック処理、遷移時にクラスを削除する
 const cb = el._enterCb = once(() => {
  if (expectsCSS) {
   トランジションクラスの削除(el, toClass)
   トランジションクラスの削除(el, アクティブクラス)
  }
  cb.cancelledの場合{
   if (expectsCSS) {
    トランジションクラスの削除(el, 開始クラス)
   }
   キャンセルされたフックを入力 && キャンセルされたフックを入力(el)
  } それ以外 {
   afterEnterHook && afterEnterHook(el)
  }
  el._enterCb = null
 })


 // DOM に入るときに、遷移の開始クラスを追加します beforeEnterHook && beforeEnterHook(el)
 if (expectsCSS) {
  // トランジションが始まる前にデフォルトのスタイルを設定します addTransitionClass(el, startClass)
  トランジションクラスを追加します(el、アクティブクラス)
  // ブラウザは次のフレームをレンダリングし、デフォルトのスタイルを削除してtoClassを追加します
  // 終了イベントリスナーを追加します。コールバックは上記の cb です。
  次のフレーム(() => {
   トランジションクラスの削除(el, 開始クラス)
   キャンセルされた場合
    遷移クラスを追加します(el, toClass)
    if (!userWantsControl) {
     if (isValidDuration(explicitEnterDuration)) {
      setTimeout(cb、明示的なEnterDuration)
     } それ以外 {
      遷移終了時(el, タイプ, cb)
     }
    }
   }
  })
 }

 (vnode.data.show) の場合 {
  トグルディスプレイ && トグルディスプレイ()
  エンターフック && エンターフック(el, cb)
 }

 if (!expectsCSS && !userWantsControl) {
  関数
 }
}

Enter は、実際に遷移またはアニメーションの終了イベントを監視する whenTransitionEnds 関数を使用します。

エクスポート let transitionEndEvent = 'transitionend'
エクスポート let animationEndEvent = 'animationend'
エクスポート関数 whenTransitionEnds (
 el: 要素、
 予想される型: ?文字列、
 cb: 機能
){
 const { type, timeout, propCount } = getTransitionInfo(el, expectedType)
 if (!type) が cb() を返す
 const イベント: 文字列 = type === TRANSITION ? transitionEndEvent : animationEndEvent
 終了 = 0
 定数終了 = () => {
  el.removeEventListener(イベント、onEnd)
  cb()
 }
 定数onEnd = e => {
  (e.target === el)の場合{
   if (++ended >= propCount) {
    終わり()
   }
  }
 }
 タイムアウトを設定する(() => {
  if (終了 < propCount) {
   終わり()
  }
 }, タイムアウト + 1)
 el.addEventListener(イベント、onEnd)
}

さて、上のソースコードのコメント分析によると、次のことがわかります。

  • Vue はまず、dom className を操作するための addClass/removeClass などの一連の補助メソッドをカプセル化します。
  • そして、ライフサイクルのenterHookの後、enterClassのデフォルトの初期スタイルであるstartClassとactiveClassがすぐに設定されます。
  • 次に、ブラウザの次のフレーム nextFrame で、startClass が削除され、toClass が追加され、遷移アニメーションの終了イベント リスナーが追加されます。
  • 終了イベントをリッスンした後、cbが呼び出され、toClassとactiveClassが削除されます。

leave のプロセスは、className が逆に追加および削除されることを除いて、enter のプロセスと同じです。

結論:Vue のアニメーション遷移処理方法は、基本的に従来の DOM と同じですが、Vue のさまざまなライフサイクルに統合されて処理されます。本質的には、DOM が追加または削除されたときにも処理されます。

Reactのトランジションアニメーション

ああ、React のドキュメントをざっと見たところ、遷移アニメーションの処理は見つかりませんでした。ねえ、ネイティブでは公式にサポートされていないようです。

しかし、useState を通じて状態を保持したり、render で状態に応じて className を切り替えたりと、自分で実装することはできますが、複雑な場合はどうすればよいでしょうか。

幸運なことに、コミュニティでホイールプラグインの反応遷移グループを見つけました
そうですね、ソースコードを直接貼り付けるだけです。Vue の以前の分析では、これは非常に簡単に理解できましたが、さらに単純化されています。

クラスTransitionはReact.Componentを拡張します。
 静的コンテキストタイプ = TransitionGroupContext

 コンストラクタ(props, context) {
  super(プロパティ、コンテキスト)
  親グループ = コンテキスト
  出現させる =
   親グループ && !parentGroup.isMounting ? props.enter : props.appear

  初期ステータス

  this.appearStatus = null

  もし(props.in){
   (現れる)場合{
    初期ステータス = 終了
    this.appearStatus = 入力中
   } それ以外 {
    初期ステータス = 入力済み
   }
  } それ以外 {
   props.unmountOnExit の場合 || props.mountOnEnter の場合 {
    初期ステータス = マウント解除
   } それ以外 {
    初期ステータス = 終了
   }
  }

  this.state = { ステータス: 初期ステータス }

  this.nextCallback = null
 }

 // DOMを初期化するときに、デフォルトの初期状態を更新します。componentDidMount() {
  this.updateStatus(true、this.appearStatus) は、
 }
 // データが更新されたら、対応する状態を更新します。componentDidUpdate(prevProps) {
  nextStatus = null とする
  if (prevProps !== this.props) {
   const { ステータス } = this.state

   if (this.props.in) {
    if (ステータス !== 入力中 && ステータス !== 入力済み) {
     nextStatus = 入力中
    }
   } それ以外 {
    if (ステータス === 入力中 || ステータス === 入力済み) {
     nextStatus = 終了
    }
   }
  }
  this.updateStatus(false、nextStatus) は、
 }

 updateStatus(マウント = false、nextStatus) {
  if (nextStatus !== null) {
   // nextStatus は常に ENTERING または EXITING になります。
   this.cancelNextCallback()

   if (nextStatus === ENTERING) {
    this.performEnter(マウント)
   } それ以外 {
    this.performExit()
   }
  } そうでない場合 (this.props.unmountOnExit && this.state.status === EXITED) {
   this.setState({ ステータス: マウント解除 })
  }
 }

 performEnter(マウント) {
  const { 入力 } = this.props
  const 出現 = this.context ? this.context.isMounting : マウント
  const [maybeNode, maybeAppearing] = this.props.nodeRef
   ? [登場]
   : [ReactDOM.findDOMNode(this)、出現]

  定数タイムアウト = this.getTimeouts()
  const enterTimeout = 表示される? timeouts.appear: timeouts.enter
  // ENTERアニメーションなし ENTEREDへ右にスキップ
  // これをマウントして実行する場合、appear を設定する必要があります
  if ((!マウント && !enter) || config.disabled) {
   this.safeSetState({ ステータス: ENTERED }, () => {
    this.props.onEntered(おそらくNode)
   })
   戻る
  }

  this.props.onEnter(おそらくノード、おそらく表示される)

  this.safeSetState({ ステータス: ENTERING }, () => {
   this.props.onEntering(おそらくノード、おそらく表示される)

   this.onTransitionEnd(enterTimeout, () => {
    this.safeSetState({ ステータス: ENTERED }, () => {
     this.props.onEntered(おそらくノード、おそらく表示される)
    })
   })
  })
 }

 終了する() {
  const { exit } = this.props
  定数タイムアウト = this.getTimeouts()
  const maybeNode = this.props.nodeRef
   ? 未定義
   : ReactDOM.findDOMNode(これ)

  // 終了アニメーションなし、EXITED へすぐにスキップ
  if (!exit || config.disabled) {
   this.safeSetState({ ステータス: EXITED }, () => {
    this.props.onExited(おそらくNode)
   })
   戻る
  }

  this.props.onExit(おそらくNode)

  this.safeSetState({ ステータス: 終了 }, () => {
   this.props.onExiting(おそらくNode)

   this.onTransitionEnd(timeouts.exit, () => {
    this.safeSetState({ ステータス: EXITED }, () => {
     this.props.onExited(おそらくNode)
    })
   })
  })
 }

 キャンセルネクストコールバック() {
  if (this.nextCallback !== null) {
   this.nextCallback.cancel()
   this.nextCallback = null
  }
 }

 safeSetState(nextState, コールバック) {
  // これは必要ないはずですが、奇妙な競合状態が発生します
  // テストではsetStateコールバックとアンマウントが実行される可能性があるため、常に
  // アンマウント後に保留中の setState コールバックをキャンセルできます。
  コールバック = this.setNextCallback(コールバック)
  this.setState(nextState, コールバック)
 }

 setNextCallback(コールバック) {
  アクティブ = true にする

  this.nextCallback = イベント => {
   (アクティブ)の場合{
    アクティブ = 偽
    this.nextCallback = null

    コールバック(イベント)
   }
  }

  this.nextCallback.cancel = () => {
   アクティブ = 偽
  }

  this.nextCallback を返す
 }
 // 遷移終了をリッスンする
 onTransitionEnd(タイムアウト、ハンドラー) {
  this.setNextCallback(ハンドラ)
  定数ノード = this.props.nodeRef
   ? this.props.nodeRef.current
   : ReactDOM.findDOMNode(これ)

  const タイムアウトまたはリスナーがない =
   タイムアウト == null && !this.props.addEndListener
  if (!node || タイムアウトまたはリスナーがない場合) {
   setTimeout(this.nextCallback, 0)
   戻る
  }

  if (this.props.addEndListener) {
   const [maybeNode, maybeNextCallback] = this.props.nodeRef
    ? [this.nextCallback]
    : [ノード、this.nextCallback]
   this.props.addEndListener(おそらくNode、おそらくNextCallback)
  }

  タイムアウトが null の場合
   setTimeout(this.nextCallback、タイムアウト)
  }
 }

 与える() {
  定数ステータス = this.state.status

  if (ステータス === マウント解除) {
   nullを返す
  }

  定数{
   子供たち、
   // `Transition` のフィルタープロパティ
   中: _in,
   マウントオンEnter: _マウントオンEnter、
   アンマウント時終了: _unmountOnExit,
   表示される: _表示される,
   入力: _enter,
   終了: _exit,
   タイムアウト: _timeout、
   終了リスナーを追加: _終了リスナーを追加、
   オンエンター: _オンエンター、
   入力時: _入力時、
   入力時: _onEntered,
   終了時: _onExit、
   終了時: _onExiting、
   終了時: _onExited,
   ノード参照: _nodeRef,
   ...子プロパティ
  } = this.props

  戻る (
   // ネストされた遷移を可能にする
   <TransitionGroupContext.Provider 値 = {null}>
    {typeof children === 'function'
     ? 子(ステータス、子プロパティ)
     : React.cloneElement(React.Children.only(children), childProps)}
   </TransitionGroupContext.Provider>
  )
 }
}

ご覧のとおり、React のさまざまなライフサイクル関数で処理される点を除けば、Vue と非常によく似ています。

この時点で、Vue トランジション コンポーネントと React トランジション グループ コンポーネントの両方が CSS 属性のアニメーションに重点を置いていることがわかります。

データ駆動型アニメーション

実際のシーンでは、CSS では処理できないアニメーションに必ず遭遇します。現時点では、2 つの解決策があります。

ref を通じて dom を取得し、従来の js ソリューションを採用します。
描画DOMのデータの状態を維持し、setStateを通じて状態クラスを継続的に更新して、ビューを自動的に更新します。

上記は、フロントエンドにアニメーショントランジション効果を実装する方法の詳細です。フロントエンドにアニメーショントランジション効果を実装する方法の詳細については、123WORDPRESS.COMの他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • Vueはリストスクロールの遷移アニメーションを実装します
  • Vue はルーティング遷移アニメーションのジッターの問題を解決します (詳細な例)
  • vueのトランジションアニメーションが正常に実装できない問題を解決する
  • vue-router はナビゲーション切り替え遷移アニメーション効果を実現します
  • vue-router を使用してページ切り替え時の遷移アニメーションを設定する
  • Vue コンポーネントの transition と transition-group を使用してトランジションアニメーションを実装します。
  • Vueはトランジションアニメーションを実装するためにトランジションを使用します
  • Vueアニメーションイベントとトランジションアニメーションの例の詳細な説明
  • Vue における基本的なトランジションアニメーションと実装原則の分析

<<:  MySQL パーティションテーブルの制限と制約の詳細な説明

>>:  Linux システムで複数のバージョンの PHP を共存させるソリューション (超シンプル)

推薦する

RHEL8 で静的 IP アドレスを設定するさまざまな方法の簡単な分析

Linux サーバーで作業している場合、ネットワーク カード/イーサネット カードに静的 IP アド...

Maven+Tomcat 基本イメージを構築する Docker の実装

序文Javaプログラミングでは、ほとんどのアプリケーションはMavenに基づいて構築されており、配信...

メニューノードのすべての子ノードを再帰的に検索する MySQL メソッド

背景プロジェクトにはメニューノードのすべてのノードをチェックする要件があります。オンラインでチェック...

Raspberry Pi 4b ubuntu19 サーバーへの docker-ce のインストール手順

Raspberry Pi モデルは 4b、1G RAM です。システムはubuntu19.10サーバ...

画像の下部の空白部分の問題を解決する

最近のプロジェクトに取り組んでいるとき、下の図に示すように、画像を参照すると常に下部に空白スペースが...

CSS3+ベジェ曲線でスケーラブルな入力検索ボックス効果を実現

では、早速レンダリングを見てみましょう。 コア コードはtransition: cubic-bezi...

フォーム入力ボックスに関するWebデザインのヒント

1. キャンセル ボタンが押されたときの破線ボックス<br /> 入力に属性値 hide...

Windows 10 Home EditionにDockerをインストールする方法を教えます

Redisの本やSpring Cloud Alibabaの本を執筆した際に、一部の分散コンポーネント...

MySQL 結合バッファの原理

目次1. MySQL 結合バッファ2. JoinBufferCacheストレージスペースの割り当て3...

Hadoop 2.Xの新機能、ごみ箱機能の説明

ごみ箱機能をオンにすると、削除されたファイルの元のデータをタイムアウトなしで復元できるため、誤って削...

MySQL 8.0.22 winx64 のインストールと設定のグラフィックチュートリアル

mysql 8.0.22 winx64のインストールと設定のグラフィックチュートリアルは参考までに、...

JSが5つ星の賞賛を獲得

この記事では、5つ星の評価を獲得するためのJSの具体的なコードを参考までに共有します。具体的な内容は...

Nginxの仕組みの詳細な説明

Nginxの仕組みNginx はコアとモジュールで構成されています。 Nginx 自体は実際にはほと...

VMware12 に CentOS8 をインストールする方法 (VM 仮想マシンに CentOS8 をインストールするチュートリアル)

数日前に CentOS8 がリリースされました。8 の最初のバージョンですが、今日は VM12 に ...

MySQLデータベース監視binlogを有効にする手順

序文多くの場合、ユーザーが自分のデータに対して実行する操作に基づいて何かを行う必要があります。たとえ...