修复 Pinghsu 主题开启评论 PJAX 后报错问题
后知后觉 现有 11 评论

本博客所使用的主题在开启 PJAX 功能后在评论处回复可见报错。

前言

具体问题参见主题作者网站即可复现,如下:

Uncaught DOMException: Failed to execute 'appendChild' on 'Node': The new child element contains the parent.

或者参照 Typecho 博客 PJAX 报错 The new child element contains the parent

溯源

若未开启 HTML 压缩功能,可看见报错函数为:

            comment.appendChild(response);
            this.dom('cancel-comment-reply-link').style.display = '';
            if (null != textarea && 'text' == textarea.name) {
                textarea.focus();
            }
            return false;

解决

对应主题中的 comments.php 文件 70 行(原版主题)

<div id="<?php $this->respondId(); ?>" class="comment-container">
    <div id="comments" class="clearfix">
        <?php $this->comments()->to($comments); ?>
        <?php if($this->allow('comment')): ?>
            <span class="response">Responses<?php if($this->user->hasLogin()): ?> / You are <a href="<?php $this->options->profileUrl(); ?>" data-no-instant><?php $this->user->screenName(); ?></a> here, do you want to <a href="<?php $this->options->logoutUrl(); ?>" title="Logout" data-no-instant>logout</a> ?<?php endif; ?> <?php $comments->cancelReply(' / Cancel Reply'); ?></span>
        <form method="post" action="<?php $this->commentUrl() ?>" id="comment-form" class="comment-form" role="form" onsubmit ="getElementById('misubmit').disabled=true;return true;">
            <?php if(!$this->user->hasLogin()): ?>
            <input type="text" name="author" maxlength="12" id="author" class="form-control input-control clearfix" placeholder="Name (*)" value="" required>
            <input type="email" name="mail" id="mail" class="form-control input-control clearfix" placeholder="Email (*)" value="" <?php if ($this->options->commentsRequireMail): ?> required<?php endif; ?>>
            <input type="url" name="url" id="url" class="form-control input-control clearfix" placeholder="Site (http://)" value="" <?php if ($this->options->commentsRequireURL): ?> required<?php endif; ?>>
            <?php endif; ?>

            <textarea name="text" id="textarea" class="form-control" placeholder="Your comment here. Be cool. " required ><?php $this->remember('text',false); ?></textarea>

            <button type="submit" class="submit" id="misubmit">SUBMIT</button>
            <?php $security = $this->widget('Widget_Security'); ?>
            <input type="hidden" name="_" value="<?php echo $security->getToken($this->request->getReferer())?>">
        </form>

问题就在于此处,评论按钮产生新的子元素包含父元素,修改为:

<div class="comment-container">
    <div id="comments" class="clearfix">
        <?php $this->comments()->to($comments); ?>
        <?php if($this->allow('comment')): ?>
            <div id="<?php $this->respondId(); ?>">
            <span class="response" data-no-instant>Responses<?php if($this->user->hasLogin()): ?> / You are <a href="<?php $this->options->profileUrl(); ?>" data-no-instant><?php $this->user->screenName(); ?></a> here, do you want to <a href="<?php $this->options->logoutUrl(); ?>" title="Logout" data-no-instant>logout</a> ?<?php endif; ?> <?php $comments->cancelReply(' / Cancel Reply'); ?></span>
        <form method="post" action="<?php $this->commentUrl() ?>" id="comment-form" class="comment-form" role="form" onsubmit ="getElementById('misubmit').disabled=true;return true;">
            <?php if(!$this->user->hasLogin()): ?>
            <input type="text" name="author" maxlength="12" id="author" class="form-control input-control clearfix" placeholder="Name (*)" value="" required>
            <input type="email" name="mail" id="mail" class="form-control input-control clearfix" placeholder="Email (*)" value="" <?php if ($this->options->commentsRequireMail): ?> required<?php endif; ?>>
            <input type="url" name="url" id="url" class="form-control input-control clearfix" placeholder="Site (http://)" value="" <?php if ($this->options->commentsRequireURL): ?> required<?php endif; ?>>
            <?php endif; ?>

            <textarea name="text" id="textarea" class="form-control" placeholder="Your comment here. Be cool. " required ><?php $this->remember('text',false); ?></textarea>

            <button type="submit" class="submit" id="misubmit">SUBMIT</button>
            <?php $security = $this->widget('Widget_Security'); ?>
            <input type="hidden" name="_" value="<?php echo $security->getToken($this->request->getReferer())?>">
        </form></div>

此外在此文件约 58 行处

<span class="comment-reply"><?php $comments->reply('Reply'); ?></span>

改为

<span class="comment-reply" data-no-instant><?php $comments->reply('Reply'); ?></span>

或参照下图对比图进行修改(更直观一些)

修改示例

小贴士:经 @泽泽社长 指正,图中第 61 行处修改为修正点击回复按钮时刷新页面的的问题。

修改完成后点击回复时可见在其父节点上新增一个回复框,控制台再无报错信息。


附录

参考链接

本文撰写于一年前,如出现图片失效或有任何问题,请在下方留言。博主看到后将及时修正,谢谢!
禁用 / 当前已拒绝评论,仅可查看「历史评论」。
  1. avatarImg 软件小编

    请问博主菜单栏分类功能是如何实现的,可以开源修改后的主题吗

    Firefox 73.0 Windows 10
    IP 属地 未知
  2. avatarImg 老张说思路

    这个主题真的很漂亮,很有特色

    Chrome 79.0 macOS Catalina
    IP 属地 未知
  3. avatarImg

    很有用,感谢分享!

    Chrome 79.0 macOS Catalina
    IP 属地 未知
    1. avatarImg
      @娜

      我修改后发现底边的页脚出现了其他的标记,请问这个如何处理?

      Chrome 79.0 macOS Catalina
      IP 属地 未知
  4. avatarImg Jdeal

    已修改,很久前研究过评论框跟随问题,最后不了了之了,哈哈,没想到你这看到了,学习了,就是评论框跟随后的嵌在评论里面的样式有点不太喜欢,等有空再调整调整,再次感谢~

    Chrome 79.0 macOS High Sierra
    IP 属地 未知
    1. avatarImg
      @Jdeal

      客气了,我这也是借花献佛,感觉嵌入的框就是不太鲜明罢了,加个浅色的边框应该就可以解决了。

      Safari 13.0.4 macOS Catalina
      IP 属地 未知
  5. avatarImg zmmio

    你看下你登录后台,然后前端回复那里评论框还在不

    Chrome 79.0 Windows 10
    IP 属地 未知
    1. avatarImg
      @zmmio

      依然有啊,没有问题。怎么你改后存在 bug ?

      Chrome 79.0 macOS Catalina
      IP 属地 未知
      1. avatarImg zmmio
        @柒

        可能我添加得css出了问题,我去看下。我早上也在泽泽那边看到了这个,哈哈

        Chrome 79.0 Windows 10
        IP 属地 未知
        1. avatarImg
          @zmmio

          他那篇博客的主题下载地址放错了,我今天下载才发现,然后通知了泽泽,然后遗憾地发现那篇文章那么久了都没人发现。

          Chrome 79.0 macOS Catalina
          IP 属地 未知
          1. avatarImg zmmio
            @柒

            对,我也是今天收到他得邮件,然后下载来对比才知道,给个赞

            Chrome 79.0 Windows 10
            IP 属地 未知