升级wp之后主题原来移动评论框的功能失效了,这个功能是原本wp默认主题都有的,例如twentytwenty。不知道是哪个版本的wp将js代码改了。所以YUAO主题使用的js失效了。
这个功能不难实现,只要你的评论模块结构和wp默认主题一致即可。然后照搬wp这个wp-inclues/js/comment-reply.min.js文件即可。但前提是你用wp_list_comments这个函数输出评论列表时,它的参数style要为div,(可以打开默认主题查看),如果你的wp_list_comments没有设置这个参数,或者是别的style的话,即便照搬了这段js,虽然也有效果,但已经不完美了。它会将你的评论框移到父级评论的最底下,若你没有子级评论时看不出区别,但若有好几条子级评论的话,似乎就不美了。因为它会移动到最下面,在子级评论之下。

怎么办?

有两种选择:1、将wp_list_comments参数改一致;2、自己写一段js实现此功能。
按1来改很容易,改了之后,前端看不出不好的地方,但我需要重写ajax评论的部分代码。
按2来我也需要写一些代码。
我不喜欢动ajax的代码,但又不会原生js的语法,所以只能用jq自己写一段了。

思路

虽然我看不懂wp源代码comment-reply.js里面的思路。但是基本动作没几个,所以自然就难不倒我了。
首先我需要在每条评论的下面构建一个空盒子放置评论框,以便在点击“回复”时能将评论框放进去,同时还要移除原有的评论框。
点击“取消回复”时,移除盒子里的评论框,然后将它放回原来的位置。
这期间唯一要注意的就是每条评论的父级id,回复时需要抓取这个id作为表单提交的依据,取消回复时还原这个id为0。0表示直接评论文章而非回复评论。

注意事项

思路通了就好办了。首先要改一改comments.php这个文件里面的评论结构。
修改评论列表函数,输出评论下面添加一个空盒子,用来装移动过来的评论框:

<?php echo  inlojv_get_comment_text() .'<div id="respond-box-'.get_comment_ID().'" class="respond-box"></div>'; ?>

其中inlojv_get_comment_text()是主题的自定义评论输出函数。一般用 get_comment_text() 或者 comment_text() 进行输出,重点在于后面添加一个div,并且附上评论id,待会有用。
给回复按钮添加id="#cancel-comment-reply-link" 以及class=".cancel-comment-reply-link"
其次是注意添加隐藏域,使用 <?php comment_id_fields(); ?> 这个隐藏域会输出两个id值,一个是文章id,另一个是父级id(也就是你将要回复这条评论的id值),这个隐藏域要放在评论框的form表单之内,我一般放在提交按钮之后,因为提交评论时要将这两个值交给后端处理。下面的js操作也需要用到父级id,所以这个隐藏域必不可少。

剩下的就是评论列表的html结构了,结构上按适合的方式去输出头像、日期、评论主体内容以及回复按钮即可。下面列举主要的html部分,重点看html的id和class名称。
先看图
reply
下面是该评论的html结构,我把头像、日期等碍眼的结构给删了。保留关键的部位。

<div id="comment_list">
	<ol class="comment-list">
		<li class="comment" id="comment-4560">
			<div id="div-comment-4560" class="comment-body">
				<div class="comment-content">
					<div class="reply">
						<a rel="nofollow" class="comment-reply-link" href="https://www.inlojv.com/5435.html?replytocom=4560#respond" data-commentid="4560" data-postid="5435" data-belowelement="div-comment-4560" data-respondelement="respond" data-replyto="回复给Tokin" aria-label="回复给Tokin">回复</a></div>
					<p class="f15 color-primary comttext">这个功能没上线么</p>
					<div id="respond-box-4560" class="respond-box"></div>
					<ul class="children">
						<li class="comment" id="comment-4562">
							<div id="div-comment-4562" class="comment-body">
								<div class="comment-content">
									<div class="reply">
										<a rel="nofollow" class="comment-reply-link" href="https://www.inlojv.com/5435.html?replytocom=4562#respond" data-commentid="4562" data-postid="5435" data-belowelement="div-comment-4562" data-respondelement="respond" data-replyto="回复给JV" aria-label="回复给JV">回复</a></div>
									<p class="f15 color-primary comttext">主要是评论列表的头像输出 在遍历时使用了file_get_content,次数多了就会很慢,没有找到解决方案,所以暂时关闭了这个功能。</p>
									<div id="respond-box-4562" class="respond-box"></div>
								</div>
							</div>
						</li>
					</ul>
				</div>
			</div>
		</li>
	</ol>
</div>

html里可以看到,两条评论下面都有respond-box这个盒子,用来装评论框表单form的。点击回复按钮之后如下图:
reply
通过调试模块可以看清楚form被装进去了,同时父级id的value值需要改变,这些动作都交给js去做。

js代码

/**
 * 点击“回复”移动评论回复框至当前评论之下 (作用同wp-inclues/js/comment-reply.min.js)
 * by inlojv.com 2020.09.26
 */
$(document).on('click', '.comment-reply-link', // 点击回复按钮
	function(event) {
		$('.respond-box .cancel-comment-reply-link').trigger('click'); // 触发一遍取消回复点击,用于轮换点击“回复”按钮
		$('.comment-content .respond-box').css('margin-bottom','30px');
		var get_parent_id = $(this).attr('href').match(/(\d+)#/); // 父级id链接
		var parent_id = get_parent_id[1]; // 获取父级id
		$('#comment_list .respond-box').empty(); // 移除其他盒子内的html
		var content = $('#respond').html(); // 获取form表单html
		$('#respond').empty();	 // 移除原回复框内部的html,但不移除外层div
		$('#respond-box-'+parent_id).html(content); // 填充html内容	
		$('#comment_parent').val(parent_id); // 为移动后表单隐藏域的父级value赋值
		$('.cancel-comment-reply-link').show(); // 显示取消回复按钮
		var store_content = $('#respond-box-'+parent_id).html() // 储存提交表单form			
 		setTimeout(function () {  // 延迟一下 执行定位	
			$("html, body").animate({scrollTop:$('#comment-'+parent_id).offset().top-190}, 400); 				
		}, 100);	
		event.preventDefault(); // 阻止默认点击事件,但不阻止冒泡
	}
);
	
$(document).on('click', '.cancel-comment-reply-link', // 点击取消回复按钮
	function(event) { 
		var respond_id = $('#comment_parent').val(); // 获取回复框的id(父级id)
		var content = $('#respond-box-'+respond_id).html(); // 获取form表单html
		$('#comment_list .respond-box').empty(); // 移除其他盒子内的html
		$('#respond').html(content).show(); // 将回复框放回原有位置
		$('.cancel-comment-reply-link').hide(); // 隐藏取消回复按钮
		$('#comment_parent').val(0); // 表单id值归零(直接评论的表单值为零)
		$('.comment-content .respond-box').css('margin-bottom','0');
		event.preventDefault(); // 阻止默认点击事件,但不阻止冒泡
	}
);

每一条都有注释,可以根据上面的js代码修改相应的结构即可。