LOGI

Typecho Mirages 主题,PJAX下,回复后,隐藏内容的自动刷新

当存在 回复可见 内容时,正常逻辑是回复后 重载 整个或局部页面。在未开启 PJAX 时,回复事件本身就会触发页面重载,而开启后,作者似乎忘了处理,不过在我的 PY 下,他同意会在下个版本加入,在此之前,先用 JS 打个不完美补丁吧。

使用步骤

将以下代码加入到 <head> 标签中。具体步骤为,依次进入 控制台 - 外观 - 设置外观 - 主题自定义扩展,将代码加入到 自定义 HTML 元素拓展 - 标签: head 头部 (meta 元素后),也可直接加入到主题对应的 header.php 中的 </head> 标签前。

[collapse title="当前版本"]

<script>
  // PJAX 下,若存在隐藏内容,回复后自动刷新
  document.addEventListener('DOMContentLoaded', initReplayHandler);
  function initReplayHandler() {
    // 顺便改下提示
    const comments = document.querySelector('#comments');
    if (!comments) return;
    const author = comments.querySelector('#author');
    const email = comments.querySelector('#mail');
    const url = comments.querySelector('#url');
    const textarea = comments.querySelector('#textarea');
    if (email && author && url && textarea) {
      author.placeholder = '昵称(必填)';
      email.placeholder = '回复通知邮箱(必填)';
      url.placeholder = '网站(选填)';
      textarea.placeholder = '听说认真评论的人最可爱哦!';
    }
    const commentForm = comments.querySelector('#comment-form');
    const reply2View = document.querySelector('.reply2view');
    if (commentForm && reply2View && reply2View.className === 'reply2view') {
      const submit = commentForm.querySelector('#submit');
      const template = (sec) => `评论提交成功,重载倒计时${sec}.`;
      submit.setAttribute('data-posted', template(3));

      commentForm.addEventListener('submit', () => {
        console.log('start to observe comment');

        let times = 0;
        (function waitStatus() {
          const status = comments.querySelector(
            '.comment-meta .comment-posted'
          );
          if (status) {
            console.log('comment success observed.');
            
            let rest = 3;
            (function countDown() {
              if (rest < 1) {
                $.pjax.reload('#body', {
                  scrollTo: reply2View.scrollTop,
                  timeout: 8000,
                });
                return;
              }
              status.innerHTML = template(rest--);
              setTimeout(countDown, 1000);
            })();
          } else if (++times < 100) {
            setTimeout(waitStatus, 200);
          }
        })();
      });
    }
  }
</script>

[/collapse]

[collapse title="原始版本"]

<script>
    // PJAX 下,若存在隐藏内容,回复后自动刷新
    document.addEventListener('DOMContentLoaded', initReplayHandler);
    function initReplayHandler() {
        // 顺便改下提示
        const comments = document.querySelector('#comments');
        if (!comments) return;
        const author = comments.querySelector('#author');
        const email = comments.querySelector('#mail');
        const url = comments.querySelector('#url');
        const textarea = comments.querySelector('#textarea');
        if (email && author && url && textarea) {
            author.placeholder = '昵称(必填)';
            email.placeholder = '回复通知邮箱(必填)';
            url.placeholder = '网站(选填)';
            textarea.placeholder = '听说认真评论的人最可爱哦!';
        }
        const commentForm = comments.querySelector('#comment-form');
        const reply2View = document.querySelector('.reply2view');
        if (commentForm && reply2View && reply2View.className === 'reply2view') {
            const submit = commentForm.querySelector('#submit');
            const template = sec => `评论提交成功,重载倒计时${sec}.`;
            submit.setAttribute('data-posted', template(3));
            const callback = (mutations, observer) => {
                mutations.forEach(mutation => {
                    mutation.addedNodes.forEach(node => {
                        let status = null;
                        if (typeof node.querySelector === 'function') {
                            status = node.querySelector('.comment-meta .comment-posted');
                        }
                        if (status) {
                            console.log('success observed.');
                            let countDown = 2;
                            const countDownWaiter = setInterval(() => {
                                if (countDown < 0) return;
                                status.innerText = template(countDown--);
                                if (countDown === 0) {
                                    $.pjax.reload({
                                        url: location.href,
                                        container: '#body',
                                        fragment: '#body',
                                        scrollTo: reply2View.scrollTop,
                                        timeout: 8000
                                    });
                                    console.log('observation finished.');
                                    clearInterval(countDownWaiter);
                                    observer.disconnect();
                                }
                            }, 800);
                        }
                    });
                });
            };
            const observer = new MutationObserver(callback);
            commentForm.addEventListener('submit', () => {
                console.log('start to observe...');
                observer.observe(comments, { childList: true, subtree: true });
            });
        }
    }
</script>

[/collapse]

此外还需单独加入回调函数。依次进入 控制台 - 外观 - 设置外观 - PJAX(BETA) - PJAX RELOAD,将 initReplayHandler(); 添加进入即可。

开头说过这是不完美方法,因为外部代码无法进入评论的 ajax success,此处使用 MutationObserver 监听,这将带来较大的时空开销。想看具体效果,那就回复试试吧!

[hide]

这里啥也没有!

[/hide]

当前页面是本站的「Google AMP」版。查看和发表评论请点击:完整版 »