1.计算指定时间距今多久
var date1=new Date('2017/02/08 17:00'); //开始时间 var date2=new Date(); //当前时间 var date3=date2.getTime()-date1.getTime() //时间差的毫秒数 //计算出相差天数 var days=Math.floor(date3/(24*3600*1000)) //计算出小时数 var leave1=date3%(24*3600*1000) //计算天数后剩余的毫秒数 var hours=Math.floor(leave1/(3600*1000)) //计算相差分钟数 var leave2=leave1%(3600*1000) //计算小时数后剩余的毫秒数 var minutes=Math.floor(leave2/(60*1000)) //计算相差秒数 var leave3=leave2%(60*1000) //计算分钟数后剩余的毫秒数 var seconds=Math.round(leave3/1000) console.log(" 相差 "+days+"天 "+hours+"小时 "+minutes+" 分钟"+seconds)
2.评论树核心代码
String.prototype.replaceAll = function(str, substr, replacement) { if(replacement === null) { replacement = ''; } str = str.replace(new RegExp(substr, 'gm'), replacement); return str; }; # 后端传给前端的数据必须是如下格式,即并非标准的json格式,元组直接当字典的键值。 var data = { "(1,'qqq',None,104)":{ "(2,'360','1',104)": { "(4,'baidu','2',104)": { "(44,'baidu','4',104)":{} } }, "(3,'ali','1',104)": {} }, "(5,'baidu',None,104)": { "(8,'baidu','5',104)": {} }, "(6,'baidu',None,104)": { "(7,'baidu','6',104)": {} } } var dataBuild = []; function getDataArray(d){for(var k in d){ var kd = k.split(","); for(var j = 0; j < kd.length; j++){ kd[j] = kd[j].replaceAll(kd[j],"\\(",""); kd[j] = kd[j].replaceAll(kd[j],"\\)",""); kd[j] = kd[j].replaceAll(kd[j],"'",""); } var newD = { id:parseInt(kd[0]), pid:kd[2] === 'None' ? 0 : parseInt(kd[2]), txt:k, margin:0, level:0, childs:"" } dataBuild.push(newD) if(JSON.stringify(d[k]) != "{}"){ getDataArray(d[k]); } }} getDataArray(data); var dataArray = []; function cacMargin(){ for (var i = 0; i < dataBuild.length; i++) { if(dataBuild[i].pid == 0){ dataBuild[i].margin = 0; dataBuild[i].level = 1; dataArray.push(dataBuild[i]); } var dataArrayChilds = []; for (var j = 0; j < dataBuild.length; j++) { if(dataBuild[i].id == dataBuild[j].pid && dataBuild[j].pid != 0){ dataBuild[j].margin = dataBuild[i].level * 30; dataBuild[j].level = dataBuild[i].level + 1; dataArrayChilds.push(dataBuild[j]); } } dataBuild[i].childs = dataArrayChilds; } } cacMargin(); var html_str = ''; function aa(dd){ for (var i = 0; i < dd.length; i++) { html_str += '<li mag='+dd[i].margin+'>'+dd[i].txt+'</li>'; if(dd[i].childs.length > 0){ aa(dd[i].childs) } } } aa(dataArray); console.log(html_str)
3.字符串替换和去除
#将代码放到<scripts>的头部,后面的代码直接引用即可。 String.prototype.replaceAll = function(str, substr, replacement) { if(replacement === null) { replacement = ''; } str = str.replace(new RegExp(substr, 'gm'), replacement); return str; }; String.prototype.trim = function() { return this.replace(/(^\s*)|(\s*$)/g, ""); }; #使用示例 kd[j] = kd[j].replaceAll(kd[j],"\\(",""); kd[j] = kd[j].replaceAll(kd[j],"\\)",""); kd[j] = kd[j].replaceAll(kd[j],"'",""); kd[j] = kd[j].trim();
4.多级评论完整示例
4.1 多级评论实现原理
评论表里设置一个值用来存储评论之间的关系,比如id为3的评论是评论id为1的评论的,那存储的时候就是“3 评论内容 1”,如果是评论新闻的而不是评论别人的评论的,最后一位就设置为None。
将评论表里的所有数据做成一个字典,每一条评论都是key,如果该评论有子评论就设置为该key的value,如果没有子评论,则value设置为空字典{}。然后循环读字典里的内容,然后再根据“根评论”还是“子评论”来缩进显示评论内容。
注:此处的key必须是元组格式的,字典不能作为key。
4.2 多级评论实现代码
setting.py常规配置(注册app);
urls.py,
url(r'^comment/', views.comment),
views.py,
from django.shortcuts import render import collections # Create your views here. def tree_search(d_dic, comment_obj): # 在comment_dic中一个一个的寻找其回复的评论 # 检查当前评论的 reply_id 和 comment_dic中已有评论的nid是否相同, # 如果相同,表示就是回复的此信息 # 如果不同,则需要去 comment_dic 的所有子元素中寻找,一直找,如果一系列中未找,则继续向下找 # d_dic{ # (1, '111', None): { # (5, '555', 1): {} # } # (2, '222', None): { # "(4, '444', 2)": { # "(6, '666', 4),": {} # } # } # (3, '333', None): {} # } # comment_obj # (6, '666', 4), for k, v_dic in d_dic.items(): # 如果key值的元组里的第一个元素与传入元组的第三个元素相等,就表示他俩是父子评论,比如(3,111,10)和(5,555,3),(5,555,3)就是(3,111,10)的子评论 if k[0] == comment_obj[2]: d_dic[k][comment_obj] = collections.OrderedDict() return else: if v_dic: # 在当前第一个跟元素中递归的去寻找父亲 tree_search(d_dic[k], comment_obj) def build_tree(comment_list): # collections.OrderedDict()的作用是创建一个有序空字典{};之所以要有序,是因为可以做到让评论有序的显示,不然的话,因为字典是无需的,所以取到的评论内容也是无需的,显示起来会有变化。 comment_dic = collections.OrderedDict() for comment_obj in comment_list: if comment_obj[2] is None: # 如果是根评论(元组的最后一位是None),添加到comment_dic[(1, '111', None)] = {} # { # (1, '111', None): {} # (2, '222', None): {} # (3, '333', None): {} # } comment_dic[comment_obj] = collections.OrderedDict() else: # (4, '444', 2), # 如果是子评论,则需要在 comment_dic 中找到其回复的评论 tree_search(comment_dic, comment_obj) return comment_dic def comment(request): # comment_list里存储的就当是数据库评论表里的条目,格式必须是元组的,因为元组格式可以作为字典的key。 comment_list = [ (1, '111', None), (2, '222', None), (3, '333', None), (4, '444', 2), (5, '555', 1), (6, '666', 4), (7, '777', 2), (8, '888', 4), ] comment_dict = build_tree(comment_list) #经过build_tree处理后,comment_list就变成下面的字典格式了,有子评论的话,子评论就是父评论的key对应的value;如果没有子评论,则该key对应的value就是一个空有序字典。 # dic = { # "(1 qqq None)":{ # "(2 360 1)": { # "(4 baidu 2)": {} # }, # "(3 ali 1)": {} # }, # "(5 baidu None)": { # "(8 baidu 5)": {} # }, # "(6 baidu None)": { # "(7 baidu 6)": {} # } # } # 将处理好的字典传入前端 return render(request, 'comment.html', {'comment_dict': comment_dict})
comment.html,
# 使用模板函数 {% load xx %} {% tree comment_dict %}
app01/templatetag/xx.py,
from django import template from django.utils.safestring import mark_safe register = template.Library() TEMP1 = """ <div class='content' style='margin-left:%s;'> <span>%s</span> """ def generate_comment_html(sub_comment_dic, margin_left_val): html = '<div class="comment">' for k, v_dic in sub_comment_dic.items(): # 因为是子评论了,所以需要加上margin_left_val(30)像素的偏移量,子子评论再加margin_left_val(30)的偏移量,以此类推。 html += TEMP1 % (margin_left_val, k[1]) # 只要有字典,就递归的往下执行generate_comment_html()函数 if v_dic: html += generate_comment_html(v_dic, margin_left_val) html += "</div>" html += "</div>" return html @register.simple_tag def tree(comment_dic): # 将comment_dic字典里的数据拼接成html传给前端 html = '<div class="comment">' for k, v in comment_dic.items(): # 因为是根评论,所以margin-left应该是0,所以这里传入(0,k[1]),k[1]是评论内容 html += TEMP1 % (0, k[1]) # 如果v不为空字典,则执行generate_comment_html() if v: html += generate_comment_html(v, 30) html += "</div>" html += '</div>' return mark_safe(html)
多级评论完整代码github地址:https://github.com/z843248880/morecomment
这些代码的功能虽小,但是能提高工作效率,此文会持续更新,记录知识的同时与大家共勉。