没有名字就是名字

没有名字就是名字 查看完整档案

北京编辑  |  填写毕业院校  |  填写所在公司/组织填写个人主网站
编辑
_ | |__ _ _ __ _ | '_ \| | | |/ _` | | |_) | |_| | (_| | |_.__/ \__,_|\__, | |___/ 该用户太懒什么也没留下

个人动态

没有名字就是名字 提出了问题 · 10月21日

axios可以修改默认baseUrl吗?或者有什么别的方案

需求就是当默认的host访问失败之后,需要换一个host,
我重新设置了axios.defaults.baseURL = 'http://baidu.com',
但是没生效,还是用的默认的

关注 3 回答 2

没有名字就是名字 赞了回答 · 10月19日

解决js对象如何优雅的取一个深度的值?

如果是我,我会这么做。let student = obj&&obj.school&&&obj.school.class1&&obj.school.class1.student
希望对你有帮助

关注 12 回答 9

没有名字就是名字 提出了问题 · 10月18日

求一个iView动态切换主题的方案

如题
vue+iView
类似这样
image.png

而不是写死几套颜色

关注 1 回答 0

没有名字就是名字 赞了回答 · 10月15日

解决js数据对比的问题

let arr = [];
// 拍平treeData
function unfoldTreeData(treeData) {
  treeData.forEach(element => {
    if (element.children) {
      unfoldTreeData(element.children);
      arr.push(element.label)
    } else {
      arr.push(element.label)
    }
  })
  return arr
}

let newTreeData = unfoldTreeData(treeData);
// 根据key为label过滤比较
const newPermission =  permission.filter(e=>{
    return !newTreeData.includes(e.label)
})

console.log(newPermission)

关注 2 回答 1

没有名字就是名字 提出了问题 · 10月14日

解决js两个树结构数据合并去重

// 这是个树节点,可能有很深
const treeData = [{
  label: '一级导航',
  path: 'path-1'
},{
  label: '二级导航',
  path: 'path-2',
  children: [{
    label: '二级导航1',
    path: 'path-2-1'
  },{
    label: '二级导航2',
    path: 'path-2-2'
  }]
}]

// 这个本来也是树节点,我给拍平了
const permission = [{
  label: '啦啦啦1',
  route: 'path-1'
},{
  label: '啦啦啦2',
  route: 'path-2'
},{
  label: '啦啦啦3',
  route: 'path-3'
},{
  label: '啦啦啦4',
  route: 'path-4'
},{
  label: '啦啦啦5',
  route: 'path-5',
  children: [{
      label: '啦啦啦5-1',
      route: 'path-5-1',
  }]
}]

// 最终处理后的结果应该是这样的
// 用treeData的label跟permission的path比

const result = [{
  label: '一级导航',
  path: 'path-1',
  meta: {
    label: '啦啦啦1'
  }
},{
  label: '二级导航',
  path: 'path-2',
  meta: {
    label: '啦啦啦2'
  }
  children: []
},{
  label: '三级导航',
  path: 'path-3',
  meta: {
    label: '啦啦啦3'
  },
  component: '如果之前的treeData上没有这个节点,需要加一个component的value,值先随便写'
},{
  label: '四级导航',
  path: 'path-4',
  meta: {
    label: '啦啦啦4'
  },
  component: '如果之前的treeData上没有这个节点,需要加一个component的value,值先随便写'
},{
  label: '五级导航',
  path: 'path-5',
  meta: {
    label: '啦啦啦5'
  },
  component: '如果之前的treeData上没有这个节点,需要加一个component的value,值先随便写'
  children: [{
      label: '五级导航1',
      path: 'path-5-1',
      meta: {
        label: '啦啦啦5-1'
    },
  component: '如果之前的treeData上没有这个节点,需要加一个component的value,值先随便写'
  }]
}]

背景:路由地址是后台管理的,路由是后台添加的(如果添加本地没有的路由,就用统一的默认模板)treeData是前端vue里的路由,permission是后台返回的路由,然后需要两个对比
1,如果treeData里有,permission里没有的,就在treeData的meta添加hidden:true或者删除掉
2,如果treeData里没有,permistion里有,则把permistion里的对象塞到treeData里
3,如果treeData里path===permission的route,则给treeData的当前对象添加meta对象,并且把permission的name赋值给meta里的label

关注 2 回答 2

没有名字就是名字 提出了问题 · 10月14日

解决js数据对比的问题

// 这是个树节点
const treeData = [{
      label: '单级导航',
      arr: []
    },{
      label: '一级导航',
      arr: [],
      children: [{
        label: '二级导航',
        arr: []
      },{
        label: '二级导航2',
        arr: []
      }]
    }]
 const permission = [{
      label: '一级导航',
      href: ''
    },{
      label: '二级导航',
      href: ''
    },{
      label: '四级导航',
      href: ''
    },{
      label: '三级导航',
      href: ''
    },{
      label: '五级导航',
      href: ''
    }]
    

请问我怎么对比treeData跟data,如果data里的label不存在于treData里的话,就return出去,这里不能保证treeData跟data的长度是相同或者哪个更长的

关注 2 回答 1

没有名字就是名字 赞了文章 · 10月9日

《前端每日实战》第174号作品:日历

image

中秋国庆长假休完,又要投入到工作中了,做一个日历纪念一下吧。

效果预览

按下右侧的“点击预览”按钮可以在当前页面预览,点击链接可以全屏预览。

https://codepen.io/comehope/pen/mdEyWEv

源代码下载

每日前端实战系列的全部源代码请从 github 下载:

https://github.com/comehope/front-end-daily-challenges

代码解读

这个日历的开发流程是,定义 DOM 结构之后,进行页面整体布局,绘制出日历薄的模样,然后分别布局上部的当前日期和下部的日期表格。完成静态布局之后,再通过脚本来动态生成日期元素,实现一个显示实时日期的动态日历。

一、定义 DOM 结构

dom 的整体结构是一个名为 .container 的容器中包含2个元素,.today 是当前日期,.calendar 是日期表格。

<div class="container">
    <header class="today">
    </header>
    <main class="calendar">
    </main>
</div>

.today 当前日期部分包含2个元素,.month 显示当前月,.day显示当前日。

<header class="today">
    <div class="day">9</div>
    <div class="month">October</div>
</header>

.calcendar 日期表格部分包含一个表头行 .days 和一个表格 .dates。表头按英文习惯以周日为每周的第一天;表格共6行,一共显示42天,可以适应任何月份。
表格中的日期通过类名区分为上月日期 previous-month、当前日期 current-day、下月日期 next-month

<main class="calendar">
    <div class="days">
        <span>Sun</span>
        <span>Mon</span>
        <span>Tue</span>
        <span>Wed</span>
        <span>Thu</span>
        <span>Fri</span>
        <span>Sat</span>
    </div>
    <div class="dates">
        <span class="previous-month">27</span>
        <span class="previous-month">28</span>
        <span class="previous-month">29</span>
        <span class="previous-month">30</span>
        <span>1</span>
        <span>2</span>
        <span>3</span>
        <span>4</span>
        <span>5</span>
        <span>6</span>
        <span>7</span>
        <span>8</span>
        <span class="current-day">9</span>
        <span>10</span>
        <span>11</span>
        <span>12</span>
        <span>13</span>
        <span>14</span>
        <span>15</span>
        <span>16</span>
        <span>17</span>
        <span>18</span>
        <span>19</span>
        <span>20</span>
        <span>21</span>
        <span>22</span>
        <span>23</span>
        <span>24</span>
        <span>25</span>
        <span>26</span>
        <span>27</span>
        <span>28</span>
        <span>29</span>
        <span>30</span>
        <span>31</span>
        <span class="next-month">1</span>
        <span class="next-month">2</span>
        <span class="next-month">3</span>
        <span class="next-month">4</span>
        <span class="next-month">5</span>
        <span class="next-month">6</span>
        <span class="next-month">7</span>
    </div>
</main>

二、页面整体和日历容器布局

先用线性渐变设置页面背景色为灰白过渡色。

body {
    margin: 0;
    height: 100vh;
    background-image: linear-gradient(to bottom, #eee, #ccc);
}

设置容器尺寸,用相对单位 em,并使容器居于页面正中。
为使容器可见,暂为容器填充白色背景。

body {
    display: flex;
    align-items: center;
    justify-content: center;
}

.container {
    width: 32em;
    height: 38em;
    font-size: 14px;
    background-color: white;
}

效果如下图:
image

注释掉刚才临时定义的 background-color 属性,改为用锐利渐变填充,实现上部黄棕色、下部白色的效果。因为黄棕色 sandybrown 是日历主色,后面还会用到,所以把它定义成变量。
再把日历四周设为圆角,底部加双层阴影,模拟多张日历纸叠加的效果。

.container {
    /* background-color: white; */
    --main-color: sandybrown;
    background-image: linear-gradient(to bottom, var(--main-color) 50%, white 50%);
    border-radius: 1em;
    box-shadow: 
        0 2px 1px rgba(0, 0, 0, 0.2),
        0 3px 1px white;
}

效果如下图:
image

接下来绘制一个细节:环扣,它用来连接日历的上、下两部分。使用2个伪元素来绘制,这样不用显式地增加 DOM 元素,纯用 CSS 实现装饰效果。两个环扣的样式相同,所以大部分代码是共享的,仅它们所处的位置不同,一个在日历左侧,一个在日历右侧。

.container {
    position: relative;
}

.container::before,
.container::after {
    content: '';
    position: absolute;
    width: 0.6em;
    height: 2.3em;
    background-color: white;
    top: calc(50% - 2.3em / 2);
    border-radius: 0.3em;
    box-shadow: 
        0 3px 1px rgba(0, 0, 0, 0.3),
        0 -1px 1px rgba(0, 0, 0, 0.2);
}

.container::before {left: 2em;}
.container::after {right: 2em;}

效果如下图:
image

至此,一个接近真实场景中的日历的轮廓绘制完成了,接下来布局日历上显示的文字内容。

三、上部当前日期布局

因为整个日历分成上下两部分,所以先令当前日期 .today 占据上部的50%空间,这样表格 .calendar 自然就被挤到下部了。

.today {
    height: 50%;
}

效果如下图:
image

因为整个日历都使用同一种字体,所以把字体样式定义在容器中,采用无衬线字体。
.today 的布局很简单,用的都是字号、颜色、行间距等基本属性。

.container {
    font-family: sans-serif;
}

.today {
    padding: 3em;
    box-sizing: border-box;
    color: white;
}

.today .day {
    font-size: 8em;
    line-height: 1em;
    font-weight: bold;
}

.today .month {
    font-size: 4em;
    line-height: 1em;
    text-transform: lowercase;
}

效果如下图:
image

四、下部日期表格布局

表格包括表头和表体两部分,设置好它们的宽度,然后用 flex 布局令其垂直居中排列。

.calendar {
    padding-top: 3.5em;
    display: flex;
    flex-direction: column;
    align-items: center;
}

.calendar .days,
.calendar .dates {
    width: 28em;
}

表头和表格都是一行7列,这里采用 grid 布局实现。

.calendar .days,
.calendar .dates {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    line-height: 2em;
    text-align: center;
}

效果如下图:
image

表格已经成形,剩下的细节是为文字上色。
表格里一共有5种语义元素:表头、当前日期、本月日期、上月日期、下月日期,这些不同语义的元素都靠 CSS 类名来区分。表头和当前日期用主色,本月日期用深灰色,上月日期和下月日期用浅灰色。

.calendar .days {
    color: var(--main-color);
    font-weight: bold;
    text-transform: uppercase;
}

.calendar .dates {
    color: dimgray;
}

.calendar .dates .previous-month,
.calendar .dates .next-month {
    color: lightgray;
}

.calendar .dates .current-day {
    color: var(--main-color);
    font-weight: bold;
}

效果如下图:
image

最后,再增加一个鼠标悬停特效,当在日期上悬停时令背景变灰、文字变白,并用 transition 实现平滑过渡。

.calendar .dates span:hover {
    background-color: lightgray;
    color: white;
}

.calendar .dates span {
    transition: 0.3s;
}

至此,整个日历的静态布局全部完成了。

五、动态脚本

程序的入口是一个名为 init 的函数,其中声明了一个 Calendar 类的实例,再调用它的 render() 方法来渲染页面。

function init() {
    let calendar = new Calendar(new Date())
    calendar.render()
}

window.onload = init

Calendar 类接收一个日期参数,以此来初始化年、月、日数据。render() 方法分别调用了 renderDay()renderMonth() 来渲染当前日期和当前月份。因为 Date 对象返回的月份属性是数字,为了把它显示成英文月份名称,就定义了一个存放月份名称的数组。

let Calendar = function(date) {
    let year = date.getFullYear()
    let month = date.getMonth()
    let day = date.getDate()

    function renderDay() {
        document.querySelector('.day').textContent = day
    }

    function renderMonth() {
        const MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
        document.querySelector('.month').textContent = MONTHS[month]
    }

    this.render = function() {
        renderDay()
        renderMonth()
    }
}

接下来要渲染日期表格了。
我们先引入一个日历库 calendar-dates(github 地址:https://dance2die.github.io/calendar-dates/),它负责计算日期、星期、月份之间的关系,为给定的年月输出对应的日历数据。通过 import 语句导入该库文件。

import CalendarDates from 'https://cdn.jsdelivr.net/npm/calendar-dates@2.6.1/dist/calendardates.esm.js'

image

注意,对于使用了 import 语句的脚本,在 <script> 标签中需增加 type="module" 属性。

<script data-original="script.js" type="module"></script>

然后,在 Calendar 类中定义一个 renderDates() 函数来渲染日历列表。如何获得日历可以参考官方文档,这里就不多说了,我觉得有点别扭的是必须用 async/await 的方式来调用。每个日期有 datetype 属性,date 就是日期数值,type 有3个值:previouscurrentnext,分别代表上月、本月、下月,我们就用这2个属性来处理日期元素的样式。
最后,别忘了要在 render() 里调用一下 renderDates() 函数。

async function renderDates() {
    const calendarDates = new CalendarDates();
    const domList = document.querySelector('.dates')
    domList.innerHTML = ''
    for (const meta of await calendarDates.getDates(new Date(year, month))) {
        let span = document.createElement('span')
        span.textContent = meta.date
        span.className = (meta.type == 'current')
            ? (meta.date == day)
                ? 'current-day'
                : ''
            : meta.type + '-month'
        domList.append(span)
    }
}

this.render = function() {
    renderDay()
    renderMonth()
    renderDates()
}

大功告成!

关于我

张偶,网络笔名 @comehope,20世纪末触网,被 Web 的无穷魅力所俘获,自此始终战斗在 Web 开发第一线。

《前端每日实战》专栏是我近年来实践项目式学习方法的笔记,以项目驱动学习,展现从灵感闪现到代码实现的完整过程,亦可作为前端开发的练手习题和开发参考。

拙作《CSS3 艺术》一书于2020年1月由人民邮电出版社出版,全彩印刷,使用100多个生动美观的实例,系统地剖析了 CSS 与视觉效果相关的重要语法,并含有近10小时的视频演示讲解。京东/天猫/当当有售。

查看原文

赞 23 收藏 9 评论 1

没有名字就是名字 赞了回答 · 9月24日

解决js递归添加层级深度标识

var data5 = [{
        label: '1',
        children: [{
          label: '2',
          children: [{
            label: '2-1'
          }, {
            label: '2-2'
          }]
        }, {
          label: '3',
          children: [{
            label: '3-1'
          }, {
            label: '3-2'
          }]
        }]
      }];

function dfs(list, level=1) {
  list.forEach(item => {
    if(item.children) dfs(item.children, level+1)
    item.level = level;
  })
  return list;
}

console.log(dfs(data5))

关注 3 回答 1

没有名字就是名字 提出了问题 · 9月24日

解决js递归添加层级深度标识

在线代码

访问后打开控制台看console

怎么根据递归的深度给数据添加深度标识
level1
level2
这样

关注 3 回答 1

没有名字就是名字 赞了回答 · 7月9日

解决TCP server 为什么一个端口可以建立多个连接?

TCP server 可以,TCP client 也可以。一个套接字只能建立一个连接,无论对于 server 还是 client。

注意报错消息是:

[Errno 106] (EISCONN) Transport endpoint is already connected

man 2 connect 说得很清楚了:

Generally, connection-based protocol sockets may successfully connect() only once; connectionless protocol sockets may use connect() multiple times to change their association.

就是说,TCP 套接字最多只能调用 connect 一次。那么,你的监听套接字调用 connect 了几次?


来点有意思的。

一个套接字不能连接两次,并不代表一个本地地址不能用两次,看!*加粗文字加粗文字*

>>> import socket
>>> s = socket.socket()
# since Linux 3.9, 见 man 7 socket
>>> s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
>>> s2 = socket.socket()
>>> s2.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
>>> s.bind(('127.0.0.1', 12345))
>>> s2.bind(('127.0.0.1', 12345))
# 都可以使用同一本地地址来连接哦
>>> s.connect(('127.0.0.1', 80))
>>> s2.connect(('127.0.0.1', 4321))
>>> netstat -npt | grep 12345
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp        0      0 127.0.0.1:4321          127.0.0.1:12345         ESTABLISHED 18284/python3
tcp        0      0 127.0.0.1:12345         127.0.0.1:4321          ESTABLISHED 4568/python3
tcp        0      0 127.0.0.1:80            127.0.0.1:12345         ESTABLISHED -
tcp        0      0 127.0.0.1:12345         127.0.0.1:80            ESTABLISHED 4568/python3

你们这些有女友的都弱爆了啦 :-(


更新:大家来玩 TCP: 一个人也可以建立 TCP 连接呢 - 依云's Blog

关注 29 回答 5

认证与成就

  • 获得 0 次点赞
  • 获得 28 枚徽章 获得 0 枚金徽章, 获得 6 枚银徽章, 获得 22 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2016-06-07
个人主页被 587 人浏览