详情
评论
问答

子比主题 – 随机弹窗评论

效果图

子比主题 – 随机弹窗评论

部署教程

将下方代码放置在主题目录下的function.php或者新建一个func.php文件

<?php
// 设置显示范围,'home' = 仅首页,'all' = 全站
$comment_popup_scope = 'home'; // 或 'all'

// 加载弹窗样式
function print_comment_popup_css_simple() {
    global $comment_popup_scope;
    if ($comment_popup_scope === 'home' && !is_front_page()) return;
    ?>
    <style>
      #wniui-popup-window {
        min-width: 300px;
        max-width: 500px;
        bottom: 20px;
        right: 20px;
        position: fixed;
        z-index: 1002;
        color: #363636;
        padding: 8px 16px;
        border-radius: 12px;
        transition: opacity 0.3s ease, transform 0.3s ease;
        background-color: rgba(255, 255, 255, 0.85);
        border: 1px solid #e3e8f7;
        max-height: 300px;
        opacity: 0;
        transform: translateY(20px);
        display: flex;
        flex-direction: column;
        justify-content: flex-start;
        cursor: pointer;
      }
      #wniui-popup-window:hover {
        border: 1px solid #425AEF;
      }
      #wniui-popup-window.wniui-show {
        opacity: 1;
        transform: translateY(0);
      }
      .wniui-popup-header {
        position: relative;
        display: flex;
        align-items: center;
      }
      .wniui-popup-title {
        font-size: 14px;
        font-weight: bold;
        background: #363636;
        color: #fff;
        padding: 4px 8px;
        border-radius: 4px;
        margin-right: 8px;
        transition: .3s;
      }
      .wniui-popup-title:hover {
        background-color: #423AEF;
      }
      .wniui-popup-author {
        font-size: 14px;
        font-weight: 600;
        color: #363636;
        display: flex;
        justify-content: flex-start;
        align-items: center;
        cursor: pointer;
      }
      .wniui-popup-avatar {
        width: 25px;
        height: 25px;
        border-radius: 50%;
        margin-right: 6px;
        background-color: #f5f6f7;
      }
      .wniui-popup-window-divider {
        width: 100%;
        height: 1px;
        background: #e3e8f7;
        margin: 5px 0;
      }
      .wniui-popup-window-content {
        font-size: 15px;
        word-wrap: break-word;
        max-width: 450px;
        white-space: normal;
        text-overflow: ellipsis;
      }
      .wniui-popup-window-content p {
        margin: 0;
        padding: 0;
        line-height: 1.5;
      }
      @media screen and (max-width: 768px) {
        #wniui-popup-window {
          display: none !important;
        }
      }
      .wniui-popup-author span:hover {
        color: #425AEF;
        transition: .3s;
      }
      svg#popup-link:hover path {
        fill: #425AEF;
        transition: .3s;
      }
    </style>
    <?php
}
add_action('wp_head', 'print_comment_popup_css_simple');

// 弹窗HTML输出
function print_comment_popup_html_simple() {
    global $comment_popup_scope;
    if ($comment_popup_scope === 'home' && !is_front_page()) return;
    ?>
    <div id="wniui-popup-window" class="wniui-show-popup-window" style="cursor: pointer;">
      <div class="wniui-popup-header">
        <span class="wniui-popup-title">热评</span>
        <span class="wniui-popup-author"></span>
        <svg id="popup-link" style="transition: .3s; cursor: pointer;display: flex; position: absolute;right:0px;" t="1740280523955" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
          p-id="22033" xmlns:xlink="http://www.w3.org/1999/xlink" width="30" height="30">
          <path
            d="M512.1 137.8c-206.4 0-373.7 167.3-373.7 373.7s167.3 373.7 373.7 373.7 373.7-167.3 373.7-373.7-167.3-373.7-373.7-373.7zM721 508.5L589.2 647c-9.9 10.4-27.4 3.4-27.4-11v-90.9h-1.4c-130.9 0-239.1 58.4-259.2 134.7h-2.3c12.8-133.2 125-237.4 261.5-237.4 0.5 0 0.9 0.1 1.4 0.1V359c0-14.4 17.5-21.4 27.4-11L721 486.6c5.8 6.2 5.8 15.8 0 21.9z"
            fill="#231815" p-id="22034"></path>
        </svg>
      </div>
      <div class="wniui-popup-window-divider"></div>
      <div class="wniui-popup-window-content"></div>
    </div>
    <?php
}
add_action('wp_footer', 'print_comment_popup_html_simple');

// JS 输出和弹窗逻辑
function print_comment_popup_js_simple() {
    global $comment_popup_scope;
    if ($comment_popup_scope === 'home' && !is_front_page()) return;

    $api_url = esc_url(rest_url('myapi/v1/hot-comments'));
    $default_avatar = esc_url(get_template_directory_uri() . '/img/avatar-default.png');
    ?>
    <script>
      class CommentPopup {
        constructor(config) {
          this.config = {
            displayTime: 5000,
            fadeTime: 300,
            retryInterval: 3000,
            apiUrl: '<?php echo $api_url; ?>',
            defaultAvatar: '<?php echo $default_avatar; ?>',
            ...config
          };

          this.popupTimer = null;
          this.retryTimer = null;
          this.commentData = [];
          this.currentCommentUrl = '';

          this.popup = document.getElementById('wniui-popup-window');
          this.bindEvents();
        }

        async init() {
          try {
            await this.fetchComments();
            this.showRandomComment();
          } catch (error) {
            console.error('Failed to fetch comments:', error);
            this.scheduleRetry();
          }
        }

        async fetchComments() {
          const response = await fetch(this.config.apiUrl);
          if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
          }
          this.commentData = await response.json();
        }

        scheduleRetry() {
          this.retryTimer = setTimeout(() => this.init(), this.config.retryInterval);
        }

        showRandomComment() {
          if (this.commentData.length === 0) return;

          const post = this.commentData[Math.floor(Math.random() * this.commentData.length)];
          const content = this.sanitizeContent(decodeURIComponent(post.content));

          if (!content) return;

          const data = {
            avatar: post.avatar || this.config.defaultAvatar,
            author: post.author,
            content,
            postUrl: post.url,
            commentUrl: post.comment_url,
            authorUrl: post.user_url || '#'
          };

          this.updatePopup(data);
        }

        sanitizeContent(content) {
          return content.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
        }

        updatePopup(data) {
          clearTimeout(this.popupTimer);
          this.popup.classList.remove('wniui-show');
          this.currentCommentUrl = data.commentUrl;

          setTimeout(() => {
            this.renderPopupContent(data);
            this.popup.classList.add('wniui-show');
            this.scheduleNextComment();
          }, this.config.fadeTime);
        }

        renderPopupContent(data) {
          const authorElement = this.popup.querySelector('.wniui-popup-author');
          authorElement.innerHTML = `
            <img class="wniui-popup-avatar" src="${data.avatar}" alt="avatar" loading="lazy">
            <span onclick="window.location.href='${data.authorUrl}'">${data.author}</span>
          `;
          this.popup.querySelector('.wniui-popup-window-content').innerHTML = `<p>${data.content}</p>`;
        }

        scheduleNextComment() {
          this.popupTimer = setTimeout(() => {
            this.hidePopup();
            this.showRandomComment();
          }, this.config.displayTime);
        }

        hidePopup() {
          this.popup.classList.remove('wniui-show');
        }

        handlePopupClick = (event) => {
          if (event.target.closest('svg#popup-link') || !event.target.closest('.wniui-popup-author')) {
            if (this.currentCommentUrl) {
              window.location.href = this.currentCommentUrl;
            }
          }
        }

        bindEvents() {
          this.popup.addEventListener('click', this.handlePopupClick);

          let touchStartY = 0;
          this.popup.addEventListener('touchstart', (e) => {
            touchStartY = e.touches[0].clientY;
          });

          this.popup.addEventListener('touchmove', (e) => {
            const touchDiff = e.touches[0].clientY - touchStartY;
            if (touchDiff > 50) {
              this.hidePopup();
            }
          });
        }

        destroy() {
          clearTimeout(this.popupTimer);
          clearTimeout(this.retryTimer);
          this.popup.removeEventListener('click', this.handlePopupClick);
        }
      }

      const commentPopup = new CommentPopup({
        displayTime: 5000,
        fadeTime: 300,
        retryInterval: 3000
      });

      commentPopup.init();

      window.addEventListener('unload', () => {
        commentPopup.destroy();
      });
    </script>
    <?php
}
add_action('wp_footer', 'print_comment_popup_js_simple');

// 注册 REST API 路由,获取热评数据
function register_hot_comments_endpoint_simple() {
    register_rest_route('myapi/v1', '/hot-comments', array(
        'methods' => 'GET',
        'callback' => 'get_hot_comments_simple',
    ));
}
add_action('rest_api_init', 'register_hot_comments_endpoint_simple');

function get_hot_comments_simple() {
    $comments = get_comments(array(
        'number'  => 50,
        'status'  => 'approve',
        'orderby' => 'comment_date',
        'order'   => 'DESC',
    ));

    $data = [];

    if (empty($comments)) {
        return new WP_REST_Response([], 200);
    }

    foreach ($comments as $comment) {
        $avatar_html = zib_get_data_avatar($comment->comment_author_email);
        preg_match('/src=["\'](\/\/[^"\']+)["\']/', $avatar_html, $matches);
        $avatar_url = !empty($matches[1]) ? 'https:' . $matches[1] : '';
        if (!$avatar_url) {
            $avatar_url = get_template_directory_uri() . '/img/avatar-default.png';
        }

        $comment_url = get_comment_link($comment->comment_ID);
        $user_url = get_author_posts_url($comment->user_id);

        $data[] = [
            'post_id'     => $comment->comment_post_ID,
            'author'      => $comment->comment_author,
            'content'     => $comment->comment_content,
            'avatar'      => $avatar_url,
            'url'         => get_permalink($comment->comment_post_ID),
            'comment_url' => $comment_url,
            'user_url'    => $user_url,
        ];
    }

    return new WP_REST_Response($data, 200);
}

可以手动改首页还是全站展示

$comment_popup_scope = 'home'; // 仅首页
// 或
$comment_popup_scope = 'all';  // 全站显示

仅供学习研究使用,请在下载后24小时内删除! Ventura
© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容