jQuery + Php 实现类似 Medium 的文章页内容批注评论功能
还没时间做 WordPress 插件…
背景
偶然的机会,在准备做小半谈否 API 的时候,正在寻找用户人群时看到了利器 (liqi.io) 网站
他们使用了一款 2015年(貌似是)由一个国外开发者做的句子标记插件,实现了文章中点击句子即可标记并评论的功能
同样的 Medium 也有句子标记功能,还是蛮有用的
增加了互动,访客也能参与其中…
代码
没有来得及整理,先贴代码
//内容数据都保存在当前文章自定义字段 $stream_ids = get_post_meta($post->ID,'stream_ids',true); $stream_contents = get_post_meta($post->ID,'stream_contents',true); $stream_users = get_post_meta($post->ID,'stream_users',true); $stream_users = explode('######',$stream_users); $stream_ids = explode('######',$stream_ids); $stream_contents = explode('######',$stream_contents); $count1 = count($stream_ids); $count2 = count($stream_contents); $count3 = count($stream_users);
↑ 文章页头部获取标记内容
<?php if(wp_is_mobile()) { $is_wap = 1; } global $current_user; $user_id = $current_user -> ID; if(empty($user_id)){ $login = 0; }else{ $login = 1; } ?> <div class="new-single-comment-fixed" id="comment_fixed" style="<?php if(!empty($stream_contents[0]) && !$is_wap) echo 'display:unset' ?>"> <?php if($login){ ?> <input type="text" name="mark_comment" value="请输入批注,按下Enter发送" id="mark_comment" style="display:none"> <?php } ?> <div style="text-align: right;font-size: 1.4rem;padding-bottom: 10px;padding-right: 15px;display:none;" id="comment_btn"> <button style="background: #444;color: #fff;padding: 3px 20px;border-radius: 2px;" id="send_comment">确定</button> <button style="background: #eee;padding: 3px 20px;border-radius: 2px;margin-left: 10px;" id="cancel_comment">取消</button> </div> <div class="new-single-comment-div-list" style="<?php if(empty($stream_contents[0])) echo 'display:none' ?>"> <?php if($count1 == $count2 && $count2 == $count3){ for($i=0;$i<$count3;$i++){ ?> <div class="new-single-comment-div hover-mark-content" style="<?php if($count3 == 1 && $i == 0) echo 'margin-bottom: 0px;'; else echo 'margin-bottom: 20px;'; ?>" id="<?php echo $stream_ids[$i]; ?>"> <h4><?php echo get_avatar($stream_users[$i],96,'','user-avatar',array('width'=>120,'height'=>120,'rating'=>'X','class'=>array('new-single-comment-img'),'extra_attr'=>'title="user-avatar"','scheme'=>'https') ); ?><?php echo get_user_by('id',$stream_users[$i])->display_name; ?></h4> <span class="new-single-comment-p"><?php echo $stream_contents[$i]; ?></span> </div> <?php }} ?> </div> </div>
↑ 文章页展示评论区块
<script> $(function(){ var len = $('.new-single-content-pad p').length; //获取元素个数 for(var i = 1;i<len;i++){ //顺序操作 $('.new-single-content-pad p:eq('+i+')').attr('id','stream'+i); //更改id为顺序数字 $('.new-single-content-pad p:eq('+i+')').attr('onclick','add_comment('+i+');'); //更改id为顺序数字 } }); $(".new-single-content-pad p").hover(function(){ $(this).eq(0).css({'text-decoration':'underline dashed rgb(253, 188, 1)'}); },function(){ $(this).eq(0).css({'text-decoration':'none'}); }); $(".hover-mark-content").hover(function(){ var co_id = $(this).eq(0).attr('id'); $('#stream'+co_id).attr('style','background: rgba(253, 188, 1, 0.18); !important'); $('#stream'+(co_id - 1))[0].scrollIntoView(); },function(){ var co_id = $(this).eq(0).attr('id'); $('#stream'+co_id).attr('style','background: none; !important'); }); $(".new-single-comment-fixed input").focus(function(){ if($('#mark_comment').val()=='请输入批注,按下Enter发送'){ $('#mark_comment').val(''); } }); $(".new-single-comment-fixed input").blur(function(){ if($('#mark_comment').val()==''){ $('#mark_comment').val('请输入批注,按下Enter发送'); } }); $(".new-single-comment-fixed input").keydown(function(){ $('#comment_btn').css('display','block'); }); var last_p_id = 'none'; var add_comment = function(id){ if(last_p_id !== 'none'){ if(last_p_id !== id){ $('#stream'+last_p_id).attr('class',''); last_p_id = id; } }else{ last_p_id = id; } $('#mark_comment').css('display','unset'); $('#stream'+id).attr('class','new-p-under'); $('#comment_fixed').css('display','unset'); $('#mark_comment').css({'border-width':'0px','box-shadow':'inset 0 -55px rgb(253, 188, 1)','color':'rgb(255, 255, 255)','font-weight':'600'}); setTimeout("$('#mark_comment').css({'border-width':'5px','box-shadow':'inset 0 0px rgb(253, 188, 1)','color':'rgb(102, 102, 102)','font-weight':'400'});",500); $('#cancel_comment').attr('onclick','close_mark_comment('+id+');'); $('#send_comment').attr('onclick','send_mark_comment('+id+');'); } var close_mark_comment = function(id){ $('#mark_comment').val('请输入批注,按下Enter发送'); $('#comment_fixed').css('display','none'); $('#stream'+id).attr('class',''); $('#comment_btn').css('display','none'); } <?php if($login){ ?> var send_mark_comment = function(id){ var content = $('#mark_comment').val(); var post_id = <?php echo $post->ID; ?>; var user_id = <?php echo $user_id; ?>; var stream_id = id; if(content.indexOf("######") >= 0 || content == ''){ alert('批注内容为空'); }else{ var formdata = new FormData(); formdata.append('content',content); formdata.append('post_id',post_id); formdata.append('user_id',user_id); formdata.append('stream_id',stream_id); $.ajax({ url: '?action=send_post_mark_comment', //此处 action 需在后台注册钩子 type: "POST", data: formdata, cache: false, dataType: 'json', processData: false, contentType: false, success: function(data) { if(data.stats == '1'){ setTimeout('location.reload();',500); }else{ alert('系统错误'); } }, error: function(data){ alert('系统错误'); } }); } } <?php } ?> $("#mark_comment").bind("keydown", function(e) { // 兼容FF和IE和Opera var theEvent = e || window.event; var code = theEvent.keyCode || theEvent.which || theEvent.charCode; if (code == 13){ $('#send_comment').click(); } }); </script>
↑ 文章页核心功能 jQuery 代码
<script> $(function(){ <?php if($count1 == $count2){ for($i=0;$i<$count1;$i++){ ?> $('#stream<?php echo $stream_ids[$i]; ?>').attr('class','new-p-undered'); $('#stream<?php echo $stream_ids[$i]; ?>').html($('#stream<?php echo $stream_ids[$i]; ?>').html()+'<button class="underline-ps" co="<?php echo $stream_ids[$i]; ?>">PS</button>'); <?php }} ?> $(".underline-ps").hover(function(){ var coo_id = $(this).eq(0).attr('co'); console.log(coo_id); $('#'+coo_id).css({'background':'#f7f8f9','padding':'5px 20px 5px 20px'}); },function(){ var coo_id = $(this).eq(0).attr('co'); $('#'+coo_id).css({'background':'#fff','padding':'0px 20px 0px 20px'}); }); }); </script>
↑ 文章页处理标记内容 jQuery 代码
function send_post_mark_comment() { if(!empty($_POST['content']) && !empty($_POST['post_id']) && !empty($_POST['user_id']) && !empty($_POST['stream_id'])) { $content = addslashes($_POST['content']); $post_id = (int)$_POST['post_id']; $user_id = (int)$_POST['user_id']; $stream_id = (int)$_POST['stream_id']; if(get_post_status($post_id) !== false){ $old_ids = get_post_meta($post_id,'stream_ids',true); $old_contents = get_post_meta($post_id,'stream_contents',true); $old_users = get_post_meta($post_id,'stream_users',true); if(!empty($old_ids) && !empty($old_contents)){ $status = update_post_meta($post_id,'stream_ids',$old_ids.'######'.$stream_id); $status = update_post_meta($post_id,'stream_users',$old_users.'######'.$user_id); $status = update_post_meta($post_id,'stream_contents',$old_contents.'######'.$content); }else{ $status = update_post_meta($post_id,'stream_ids',$stream_id); $status = update_post_meta($post_id,'stream_users',$user_id); $status = update_post_meta($post_id,'stream_contents',$content); } if($status !== false){ echo json_encode(array('stats'=>'1')); }else{ echo json_encode(array('stats'=>'0')); } }else{ echo json_encode(array('stats'=>'0')); } die(); } } // 将接口加到 init 中 add_action('init', 'send_post_mark_comment');
↑ 提交评论 action 函数
.new-single-comment-btn{ float: right !important; border: 2px solid #959da5 !important; background-color: #fff !important; box-shadow: none !important; border-radius: 5px !important; padding: 12px 12px 11px 15px !important; text-align: center !important; text-shadow: none !important; color: #959da5 !important; margin: 0px !important; margin-top: -5px !important; } .new-single-comment-avatar{ width: 40px; height: 40px; margin-left: -2px; margin-right: 13px; border-radius: 50%; } .new-single-div-author{ position: absolute; right: 0px; top: -54px; padding: 6px 20px; font-family: sans-serif; font-size: 1.8rem; border-radius: 50px; box-shadow: 0 0.125rem 0.75rem 0 rgba(0,0,0,.08); } .new-p-under{ text-decoration: underline dashed rgb(253, 188, 1) !important; } .new-p-undered{ text-decoration: underline dashed rgb(253, 188, 1) !important; } .new-single-comment-fixed{ display: none; position: fixed; box-shadow: 0 1px 4px rgba(0,0,0,.2); border: none; transform: translateX(820px); margin-top: 22.1vh; width: 35vh; top: 0px; background: rgb(255, 255, 255); } .new-single-comment-fixed input{ border: none;font-size: 1.4rem;font-weight: 400;font-family: sans-serif;color: #666;height: 55px;padding-left: 20px; border-left: 5px solid rgb(253, 188, 1); } .new-single-comment-p{ font-size: 1.2rem !important; margin: 5px 0 !important; color: #888; text-decoration: none !important; } .new-single-comment-img{ width: 28px !important; min-width: 28px !important; height: 28px !important; margin: 0px !important; display: inline-block !important; border-radius: 50% !important; margin-right: 7px !important; margin-left: -5px !important; margin-top: -4px !important; } .underline-ps{ background: rgb(252, 188, 1); color: rgb(255, 255, 255); font-style: normal; font-size: 1rem; padding: 1px 10px; font-weight: 600; border-radius: 5px; margin-left: 5px; } .new-single-comment-div{ padding: 0px 20px 0px 20px; border-left: 5px solid rgb(238, 238, 238); transition: ease-in-out .2s; } .new-single-comment-div h4{ font-weight: 600; font-size: 1.9rem; color: #666; margin-bottom: 3px; } .new-single-comment-div-list{ padding: 10px 0px; padding-left: 0px; border-top: 1px solid #eee; max-height: 50vh; overflow: hidden; overflow-y: auto; transition: ease-in-out .2s; } .new-cap-tags{ margin-top: -20px; } .new-cap-tags a{ position: relative; display: inline-block; height: 30px; padding: 0 15px; font-size: 1.7rem; line-height: 30px; color: rgb(0, 132, 255) !important; vertical-align: top; border-radius: 100px; background: rgba(0, 132, 255, 0.1); } .new-single-comment-fixed-cap{ box-shadow: 0 1px 4px rgba(0,0,0,.2); border: none; background: rgb(255, 255, 255); transform: none !important; display: block !important; margin-top: 30px !important; margin-left: 44px !important; width: 100%; position: relative; }
↑ CSS部分
截图
后记
大概还不准备放在 Tony 主题 里 (感觉没啥必要)
之后可能会做成 WordPress 插件2333
相关推荐
zyyjay 2020-11-09
xuebingnan 2020-11-05
samtrue 2020-11-22
stefan0 2020-11-22
yifangs 2020-10-13
songshijiazuaa 2020-09-24
hebiwtc 2020-09-18
天步 2020-09-17
83911535 2020-11-13
whatsyourname 2020-11-13
zhouyuqi 2020-11-10
Noneyes 2020-11-10
mathchao 2020-10-28
王志龙 2020-10-28
wwwsurfphpseocom 2020-10-28
diskingchuan 2020-10-23
savorTheFlavor 2020-10-23