YouTube - Proper Description

Forces the video description to live below the video with a reliable open/close toggle. Updated for modern YouTube DOM (no yt.msgs_ dependency).

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

You will need to install an extension such as Tampermonkey to install this script.

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

作者のサイトでサポートを受ける。または、このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name         YouTube - Proper Description
// @description  Forces the video description to live below the video with a reliable open/close toggle. Updated for modern YouTube DOM (no yt.msgs_ dependency).
// @namespace    http://tampermonkey.net/
// @icon         https://cdn-icons-png.flaticon.com/64/2504/2504965.png
// @supportURL   https://github.com/5tratz/Tampermonkey-Scripts/issues
// @version      0.0.6
// @author       5tratz
// @match        *://www.youtube.com/watch*
// @license      MIT
// @grant        none
// @run-at       document-end
// ==/UserScript==

(function () {
  'use strict';

  function waitFor(selector) {
    return new Promise(resolve => {
      const el = document.querySelector(selector);
      if (el) return resolve(el);

      const mo = new MutationObserver(() => {
        const el = document.querySelector(selector);
        if (el) {
          mo.disconnect();
          resolve(el);
        }
      });
      mo.observe(document, { childList: true, subtree: true });
    });
  }

  function init() {
    waitFor('#meta ytd-video-secondary-info-renderer ytd-expander').then(expander => {
      if (expander.dataset.fixed) return;
      expander.dataset.fixed = '1';

      const more = expander.querySelector('tp-yt-paper-button#more');
      const less = expander.querySelector('tp-yt-paper-button#less');

      if (!more || !less) return;

      // Custom toggle
      const toggle = document.createElement('div');
      toggle.style.cursor = 'pointer';
      toggle.style.marginTop = '8px';
      toggle.style.fontWeight = '500';
      toggle.style.color = 'var(--yt-spec-text-primary)';
      toggle.textContent = expander.hasAttribute('collapsed')
        ? more.textContent.replace('...', '').trim() || 'Show more'
        : less.textContent.replace('...', '').trim() || 'Show less';

      expander.appendChild(toggle);

      function update() {
        toggle.textContent = expander.hasAttribute('collapsed')
          ? more.textContent.replace('...', '').trim() || 'Show more'
          : less.textContent.replace('...', '').trim() || 'Show less';
      }

      toggle.addEventListener('click', () => {
        if (expander.hasAttribute('collapsed')) {
          expander.removeAttribute('collapsed');
          more.setAttribute('hidden', '');
          less.removeAttribute('hidden');
        } else {
          expander.setAttribute('collapsed', '');
          less.setAttribute('hidden', '');
          more.removeAttribute('hidden');
        }
        update();
      });

      new MutationObserver(update).observe(expander, {
        attributes: true,
        attributeFilter: ['collapsed']
      });

      update();
    });
  }

  // Initial load
  init();

  // SPA navigation support
  let lastUrl = location.href;
  setInterval(() => {
    if (location.href !== lastUrl) {
      lastUrl = location.href;
      if (location.pathname === '/watch') {
        setTimeout(init, 500);
      }
    }
  }, 500);
})();