工作积累(xkw)

前言:第一份工作中遇到的一些小问题,涉及的方面比较杂,内容简单基础,这里只做一个记录。

拿到一个项目首先要做的事情

  • 项目目录结构
  • package.json 查看项目依赖,使用的插件(devDependencies:开发环境使用 dependencies:生产环境使用)

vue

vue指令(v-if和v-show)
  • 都是用来控制元素的显示和隐藏的。

  • 区别:

    1.手段:v-if是通过控制dom节点的存在与否来控制元素的显隐;v-show是通过设置DOM元素的display样式,block为显示,none为隐藏;

    2.编译过程:v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-show只是简单的基于css切换;

    3.编译条件:v-if是惰性的,如果初始条件为假,则什么也不做;只有在条件第一次变为真时才开始局部编译(编译被缓存?编译被缓存后,然后再切换的时候进行局部卸载); v-show是在任何条件下(首次条件是否为真)都被编译,然后被缓存,而且DOM元素保留;

    4.性能消耗:v-if有更高的切换消耗;v-show有更高的初始渲染消耗;

  • 使用场景:
    基于以上区别,因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

  • 总结:
    v-if判断是否加载,可以减轻服务器的压力,在需要时加载,但有更高的切换开销;v-show调整DOM元素的CSS的dispaly属性,可以使客户端操作更加流畅,但有更高的初始渲染开销。如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

vue事件修饰符 按键修饰符(还能自定义呢)

@click.stop与@click.prevent
@click.stop 阻止事件冒泡
@click.prevent 阻止事件的默认行为,

<a href="http://www.baidu.com" @click.prevent="test4">百度一下</a>   //阻止a标签跳转,仅执行函数test4
<form  action="/xxx"   @submit.prevent="test5">   //阻止表单提交,仅执行函数test5
        <input type="submit" value="注册">
</form>

按键修饰符

@keyup.enter
//按下enter时,执行方法test7

<input type="text" @keyup.enter="test7">
methods: {
      test7 (event) {
        console.log(event.keyCode)
        alert(event.target.value)
      }
}
vue父子组件传参

牛客网总结: https://www.nowcoder.com/discuss/355165

components

components组件要放在data数据之前

vue中的{{ }} es6中的``(反引号模板字符串)和 ${}

vue中的{{ }} 将data中的数据渲染到页面上

<div id="app">
    <p>{{ message }}</p>
    <p>{{ mFour }}</p>
    <p>{{ mFive }}</p>
    <!--
    {{ }},用于输出对象属性和函数返回值,
    里面不仅可以写js变量,
    还可以写一些简单的表达式,比如三目运算符,累加等等,
    当里面写方法的时候,必须要在vue中申明
    -->
		{{age>60 ? "老人":"年轻人"}}
		{{fullName.split(" ")[1]}}
		{{getFullName()}}
</div>
	
<script>
new Vue({
  el: '#app',
  data: {
   message : 'Vue中定义的数据',
    age: 30,
    mFour: 5 + '' + 1,
		mFive: 5 > 3,
    fullName : "luwei 6"
  },
  methods : {
    getFullName : function(){
        //this指vm实例
        return this.firstName + "" + this.lastName;
    }
}
})
</script>

es6 模板字符串
模板字符串( template string )是增强版的字符串,用反引号( )标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。 ps:反引号别告诉我不知道是啥,键盘一左边的按键 在里面的变量写法不用再拼接了,只需要用${}来划定范围就行了,大括号内部可以放入任意的 JavaScript` 表达式,可以进行运算,以及引用对象属性、

let bianliang = 1111;
console.log(`输出的会是 ${bianliang}`);

输出结果:输出的会是 1111
是不是很赞!!!!
如果使用模板字符串表示多行字符串,所有的空格和缩进都会被保留在输出之中。

然后看看更带劲的,模板编译

var template = `
<ul>
<% for(var i=0; i < data.supplies.length; i++) { %>
<li><%= data.supplies[i] %></li>
<% } %>
</ul>
`;

上面代码在模板字符串之中,放置了一个常规模板。该模板使用<%...%>放置 JavaScript 代码,使用<%= ... %>输出 JavaScript 表达式。
这样就会循环的生成了一个列表,es6是不是太赞了

标签模板
模板字符串的功能,不仅仅是上面这些。它可以紧跟在一个函数名后面,该函数将被调用来处理这个模板字符串。这被称为 “ 标签模板 ” 功能( tagged template )。

alert`123`
//  等同于
alert(123);

标签模板其实不是模板,而是函数调用的一种特殊形式。 “ 标签 ” 指的就是函数,紧跟在后面的模板字符串就是它的参数。
但是,如果模板字符里面有变量,就不是简单的调用了,而是会将模板字符串先处理成多个参数,再调用函数。

vue使用data,methods中的数据

vue在方法里面调用data中的数据,用this.数据名。 在方法或者钩子函数中调用其他方法也用 this.方法名。

$event

在原生事件中,$event是事件对象

@click="changeIndex($event)"

changeIndex(e) {
    // e.target 是你当前点击的DOM元素
	// e.currentTarget 是你绑定事件的DOM元素(触发事件的DOM元素)
  console.log(e);
  let dataset = e.currentTarget.dataset;
    
}

**在自定义事件中,$event是传递过来的数据 **
相当于 arguments

vue在父组件内修改子组件的样式

参考链接:
https://blog.csdn.net/csdn_yudong/article/details/79087236
方法:

  • 去掉scoped
  • 混用全局样式和局部样式。
        <style>
        /* 全局样式 */
        </style>
        <style scoped>
        /* 本地样式 */
        </style>
  • 或者:采用深度选择器 >>>(sass无法正确解析 >>>,可以用 /deep/取代)
vue中的 $refs

可以用在普通dom元素身上(获取到的是dom元素)
用在子组件上:获取到的是组件实例,可以使用组件的所有方法,如果想获取子组件上面的某个节点可以使用,$el this.$refs.dataTable.$el.children[2];
使用时有一些坑,参考下面,写的很好
https://blog.csdn.net/wh710107079/article/details/88243638
坑2:的例子

<input v-model="item.text1" v-show="item.show_input" :ref="item.text1"></input>


this.$refs[`test-${item.text1}`][0].$refs['input'].focus()

使用:
给标签设置属性 ref="名称”
后序的方法中可以通过 this.$refs.名称拿到对应的标签(如果同名的 ref有好几个,那么就会返回一个数组),可以拿到标签身上的一系列内容,包括属性,offsetTop这些内容。

this.$nextTick(callback)

nextTick(),是将回调函数延迟在下一次dom更新数据后调用,简单的理解是:当数据更新了,在dom中渲染后,自动执行该函数,

Vue是异步执行dom更新的,一旦观察到数据变化,Vue就会开启一个队列,然后把在同一个事件循环 (event loop) 当中观察到数据变化的 watcher 推送进这个队列。如果这个watcher被触发多次,只会被推送到队列一次。这种缓冲行为可以有效的去掉重复数据造成的不必要的计算和DOm操作。而在下一个事件循环时,Vue会清空队列,并进行必要的DOM更新。
当你设置 vm.someData = ‘new value’,DOM 并不会马上更新,而是在异步队列被清除,也就是下一个事件循环开始时执行更新时才会进行必要的DOM更新。如果此时你想要根据更新的 DOM 状态去做某些事情,就会出现问题。。为了在数据变化之后等待 Vue 完成更新 DOM ,可以在数据变化之后立即使用 Vue.nextTick(callback) 。这样回调函数在 DOM 更新完成后就会调用。

使用场景:
1、Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中。

created(){
    let that=this;
    that.$nextTick(function(){  //不使用this.$nextTick()方法会报错
        that.$refs.aa.innerHTML="created中更改了按钮内容";  //写入到DOM元素
    });
}

2、当项目中你想在改变DOM元素的数据后基于新的dom做点什么,对新DOM一系列的js操作都需要放进Vue.nextTick()的回调函数中;通俗的理解是:更改数据后当你想立即使用js操作新的视图的时候需要使用它。

路由this.$router

vue页面跳转

// 跳转(在history中有记录)
this.$router.push('/recommend')
// 重定向:
this.$router.replace('/recommend')
// 返回上一个:
this.$router.go(-1);
 // 可以拿到url中的参数
 this.$route.path  和 this.$route.query
vue混入mixins

一般定义在 assets > js > mixins 中
使用:
在需要的地方

import customWxShareMixins from '~/assets/js/mixins/custom_wx_share.js';
mixins: [customWxShareMixins],
qrcodejs2插件生成二维码

https://www.cnblogs.com/duanzhenzhen/p/10711482.html

一个 canvas 在视网膜屏幕上可能显得太模糊。使用 window.devicePixelRatio 以确定应该添加多少额外的像素密度以允许更清晰的图像。
w3cschool.cn/fetch_api/fetch_api-atvq2nma.html

vue实现省市区三级联动

V-Distpicker插件

NUXT

中文文档 https://zh.nuxtjs.org/

技术胖的博客 https://jspang.com/detailed?id=37#toc23

首先要装好node环境和vue-cli,拿到项目npm install 或者 yarn进行下载第三方包完了之后,npm run dev即可启动项目

在windows下安装node-sass失败,提示\node-sass: Command failed,解决方案

yarn add node-sass@4.7.2 --dev --registry=https://registry.npm.taobao.org

出现这个问题的原因一般是网络问题,被墙了,这个时候我们不妨换个源试试
yarn config set registry https://registry.npm.taobao.org/ 通过该命令设置yarn的下载源

1、全局安装vue-cli
npm install -g @vue/cli
# OR
yarn global add @vue/cli

vue -V 检查版本
目录结构
Nuxt自动生产了项目目录,我们先来一个一个介绍一下。

|-- .nuxt                            // Nuxt自动生成,临时的用于编辑的文件,build
|-- assets                           // 用于组织未编译的静态资源入LESS、SASS 或 JavaScript
|-- components                       // 用于自己编写的Vue组件,比如滚动组件,日历组件,分页组件
|-- layouts                          // 布局目录,用于组织应用的布局组件,不可更改。
|-- middleware                       // 用于存放中间件
|-- pages                            // 用于存放写的页面,我们主要的工作区域
|-- plugins                          // 用于存放JavaScript插件的地方
|-- static                           // 用于存放静态资源文件,比如图片
|-- store                            // 用于组织应用的Vuex 状态管理。
|-- .editorconfig                    // 开发工具格式配置
|-- .eslintrc.js                     // ESLint的配置文件,用于检查代码格式
|-- .gitignore                       // 配置git不上传的文件
|-- nuxt.config.json                 // 用于组织Nuxt.js应用的个性化配置,已覆盖默认配置
|-- package-lock.json                // npm自动生成,用于帮助package的统一性设置的,yarn也有相同的操作
|-- package-lock.json                // npm自动生成,用于帮助package的统一性设置的,yarn也有相同的操作
|-- package.json                     // npm包管理配置文件

# 其中:pages是页面,nuxt中不用自己写路由,写在pages中的页面nuxt会自动给他加上路由的 而components是页面中的组件  layout(项目的公用结构)
Package.json文件  比如运行 yarn run dev的时候实际运行的就是 scripts配置项中dev后面的内容
 "scripts": {
     	# --inspect 表示debug环境, 默认端口9226 端口可以通过这种方式修改--inspect=9226,如果修改了端口那么在debug的时候不要忘记修改为同样的端口
        "dev-debug": "cross-env NODE_ENV=development nodemon --inspect=9226 server/index.js --watch server",
        "dev": "cross-env NODE_ENV=development nodemon server/index.js --watch server",
            ....
 }
生命周期

在这里插入图片描述

nuxt-link

nuxt-link的内容对SEO是友好的

 <nuxt-link :to="'/soft/'+item.softId+'.html'">
或者
	:to="detailUrl(index)"


    detailUrl(index) {
      return `/zj/info-${this.features[index].featureId}.html`;
    }
asyncData(context)

需要服务端渲染(SEO)的数据在asyncData中去写,另外asyncData中应该尽量精简,一些后台请求可以都拆出去。另外asyncData() 只能用在页面组件中,不能在子组件中使用。
context.query 和 context.params 分别可以返回url参数

nuxt注册全局组件或者方法

nuxt注册全局组件或者方法

nuxt中使用vuex

在store文件夹中新建文件

TKD
  head() {
    return {
      title: `${this.departmentText}${
        this.channelText
      }试题试卷/期中/期末/月考-学科网`,
      meta: [
        {
          hid: 'description',
          name: 'description',
          content: `学科网试卷频道为您提供${this.departmentText}${
            this.channelText
          }试题试卷精品资料,包含:期中、期末、月考、模拟、单元测试等各类试题,欢迎您使用学科网。`
        },
        {
          hid: 'keywords',
          name: 'keywords',
          content: `${this.departmentText}${this.channelText}试卷,${
            this.departmentText
          }${this.channelText}试题,${this.departmentText}${
            this.channelText
          }期中试卷,${this.departmentText}${this.channelText}期末试卷,${
            this.departmentText
          }${this.channelText}月考试卷`
        }
      ]
    };
  }

用这种方式拼接tkd规则的时候,别忘了检查 ${} 和文字之间 以及 ${} 与 ${}之间不要有换行,否则渲染到浏览器上面可能会有空格
在这里插入图片描述

JS

window.scrollTo(xpos,ypos)

项目中是要实现点击不同的试卷类型,滚动到对应的位置 (只有y轴上的变化)因此是: window.scrollTo(0,要滚动到的位置)

Element.getBoundingClientRect()

方法返回元素的大小及其相对于视口的位置。

比较两个对象或数组的值是否一样

比较两个对象或者数组是不相等的,因为比较的是地址,要想用两个相等内容的对象做判断条件可以用JSON.stringfy(对象名)=‘{ }’

数组shift方法

删除数组中第一个元素,并返回被删除的元素的值。 会改变原始数组。
unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度。

Object.assign()

用于对象的合并。将源对象的可枚举属性都复制到目标对象。第一个参数是目标对象,后面的参数是源对象。如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。
参考:https://www.jianshu.com/p/d5f572dd3776

拼接字符串注意事项
  • 保存的时候小心编辑器自动追加的东西
消除 定位元素脱离文档流 对后面元素的影响

使用js获取定位元素的高度,赋值给定位元素的父级元素。

js push和concat
array.push(item1,item2,item3...)
array.concat(item1,item2,item3...)

首先二者的参数都是无限的参数列表并且既可以是普通元素(任意类型),也可以数组元素。

不同的是:push的item会添加到末尾,并且都是以整体的形式添加到数组末尾,数组元素会直接以数组整体的形式存在 而 concat的元素会被打碎,非数组元素无法打碎,以整体形式加入,数组元素会被打碎,以单个元素的形式加入,并且数组元素和非数组元素可以混用,例如

var arr = [1,2,3];
arr = arr.concat(4,[5,6],7) 
//arr: [1,2,3,4,5,6,7]

push方法会直接修改原数组,返回值为加入元素后的新数组长度
concat方法不会修改原数组,而是连接之后返回一个新的数组,通常用arr = arr.concat(…)的形式来接收返回值,否则看不到修改效果。
let arr = [1,2,3]
array.push(...arr)array.concat(arr) 可以实现的效果是一样的

&& || 参与运算

首先是&&,先计算左边表达式,如果它的值为false或可被转换为false(null、NaN、0或undefined),那么返回左边表达式的值,否则返回右边表达式的值

然后是||,先计算左边表达式,如果它的值为true或不可被转换为false(null、NaN、0或undefined),那么返回左边表达式的值,否则返回右边表达式的值

删除对象中的键值对

delete options.title;

判断上一个页面

beforeRouteEnter(to, from, next) {
next(vm => {
fromPageName = from.name;
});
},

console.log console.dir
console.log prints the element in an HTML-like tree
console.dir prints the element in a JSON-like tree
  • console.log() 方法用于在 console 窗口中输入信息。在调试时,可以替代 alert() 或 document.write() 输入需要输出的内容
  • console.dir() 方法用来对一个对象进行检查(inspect),并以易于阅读和打印的格式显示。该方法对于输入 DOM 对象非常有用,因为 dir 方法会显示DOM对象的所有属性
    • 该特性是非标准的,so。。尽量不要在生产环境中使用它!
input输入框获取焦点时调起数字键盘

input输入框 type=“number” 或者 type=“tel” 在用户输入的时候后自动调起数字键盘

  • texterea输入框提示文字
<textarea placeholder="这是帮助文字" rows="2">
</textarea>
indexOf(searchvalue,fromindex)
// stringObject.indexOf(searchvalue,fromindex)
// 可返回某个指定的字符串值在字符串中首次出现的位置
// stringObject是字符串对象,searchvalue是指定的字符串值,fromindex(可有可无)指定开始匹配字符串值的位置,若无,表示从0位置开始。
// 获取一个字符串值在指定字符串第n次出现的位置
 function find(str,cha,num){
    var x=str.indexOf(cha);
    for(var i=0;i<num;i++){
        x=str.indexOf(cha,x+1);
    }
    return x;
 }
被卷去的头部
let scrollTop =
        window.pageYOffset ||
        document.documentElement.scrollTop ||
        document.body.scrollTop;
防抖和节流

防抖和节流

去抖函数 (util.debounce)

  /**
   * 返回一个去抖函数,在多次触发的时候,只执行一次
   * @param {*} func 待执行的function
   * @param {*} delay 超过delay的时间才执行,否则重新计时
   */
  debounce(func, delay) {
    let timer;
    return function debouncedFunc() {
      var context = this;
      var args = arguments;
      clearTimeout(timer);
      timer = setTimeout(function() {
        func.apply(context, args);
      }, delay);
    };
  },

ES6

解构赋值

请求后台数据,拿到后台响应后,通过解构来获得想要的数据,如果解构后没有拿到数据可以重命名一下,通过重命名来试试。

对promise的理解

对promise的理解

HTML

H5 role属性标签

role=“navigation”
HTML5的标签属性,可以用于标识一个普通的标签,使之语义化,方便浏览器对其具体功能进行识别。
例如div容器制作的导航栏,加上role=“navigation”,就可以让浏览器知晓这是一个导航容器而不是一个普通的容器,从而在面对一些特殊人群的时候可以做出正确的反应(例如盲人)……
当然,针对题目中的这种用法,其实用

CSS

css教程

html.cn/book/css/

一段文本溢出显示省略号
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
锚链接
    <a href="#top" class="backtop">
        返回顶部
    </a>
css三角形

盒子内容设置为空,不需要的边框颜色设置为透明 transparent

div {
    width: 0;
    height: 0;
    border: 40px solid;
    border-color: transparent transparent red;
}
局部样式scoped
box-shaow

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

 /* 顺序为: offset-x, offset-y, blur-size, spread-size, color */
box-shadow: 0px 10px 10px rgba(158,127,49,0.4);
// 颜色写在最后一项
// rgba()里面的透明度要写成0.几的形式 而不是百分比

需求

移动端适配布局

移动端布局,需要随着设备尺寸的不同做适配的就用rem做单位,(一般图片的宽度,布局容器的宽度都是百分百或者rem为单位,字号一般都是px做单位,字号固定的话,行高某些padding 也要用固定的,否则会很丑)
如上的列表页面的图片大小也是固定的,在款设备下用户看到更多的文字,窄设备下,限制文字行数为2行,多余的文字隐藏用省略号,但是图片的宽度仍然是不变的

  • tips: html根元素字体大小在浏览器中看
vscode cssrem插件使用

给vscode的rem插件(cssrem)设置root font-size (如果设计稿宽度是750px,cssrem根元素字体大小就设置为750/10 = 75)

rem对IE的支持不太好,如果网页只是在移动端,那么大胆使用

rem兼容性

https://www.cnblogs.com/webBlog-gqs/p/9139241.html

兼容安全距离的手机
padding-bottom: calc(100rpx + constant(safe-area-inset-bottom));
padding-bottom: calc(100rpx + env(safe-area-inset-bottom));
注意手机浏览器底端的切换网页的左右条
  • 为了网页内容不被遮挡,很多都需要能向下滚动,这就需要内容部分的height > 视口高度(window.innnerHeight)
  • 如果设置 页面内容区域的高度 = window.innnerHeight,那么页面刚好不能滚动
vue / wx 动态追加类名,动态追加style属性

vue

    :class="['classname1', current===1?'actice': '']"
    :style="{'height': navHeight+20+'px' , 'margin-top': '20px'}"

wx

    <view  class="btn {{showSectionModel?'active':''}}" style="top:{{!isFixedTop?topNavBarTotalHeight+top:59+topNavBarTotalHeight}}px;position:				{{isFixedTop?'fixed':'absolute'}};z-index:3000;visibility:{{showModel?'visible':'hidden'}};height:auto;overflow-x:hidden">

     </view>  
vue实现触底加载

可以这样写:

 methods: {
  scroll() {
   let isLoading = false;
   window.onscroll = () => {
       
    let bottomOfWindow = /*关于到滚动到什么地方开始加载数据的条件*/
    if (bottomOfWindow && isLoading == false) {
    
     isLoading = true;
     //axios请求后台数据
        
      isLoading = false;
     })
    }
   }
  }
 },

 mounted() {
  this.scroll()
 }
}

也可以在mounted钩子函数中用window.addEventLinstener('scroll',函数名);再在methods中添加一个相应的加载方法来实现。

mounted(){
    window.addEventListener('scroll', this.scrollHandleDebounce);
},
destroyed(){
    window.removeEventListener('scroll', this.scrollHandleDebounce, false);
},
methods: {
scrollHandleDebounce() {
 util.debounce(this.scrollHandle,300)()
}
// 触底加载
scrollHandle(){  
      let documentHeight = document.body.scrollHeight;
      // window.scrollY 偏移量(被卷去的头部)
      // window.outerHeight 窗口高度含边框,菜单栏; window.innerHeight 窗口高度不包含边框,菜单栏
      // scrollHeight 没有高度限制时 子元素的全部高度
      if (window.scrollY + window.outerHeight + 50 >= documentHeight) {
        this.lower();
      }
},
lower() {
			// isLoading代表加载中  hasNoMore代表没有下一页数据了
     if (this.isLoading || this.hasNoMore) {
        return;
      }
     // 发送axios请求之前
     this.isLoading = true;
     // 发送axios请求.then(() => {
     		
     		// 操作数据,并判断是不是最后一页数据
     		
     		//最后解除正在加载的状态
     		this.isLoading = false;
     })
      
}
}

/关于到什么地方开始加载数据的条件/相关方法:
首先了解scroll,client,offset三大家
https://blog.csdn.net/k491022087/article/details/52629743
关于document.documentElement和document.body 和各个浏览器
https://www.cnblogs.com/nanshanlaoyao/p/5964730.html

//滚动条在Y轴上的滚动距离
export function getScrollTop(){
  var scrollTop = 0, bodyScrollTop = 0, documentScrollTop = 0;
  if(document.body){
    bodyScrollTop = document.body.scrollTop;
  }
  if(document.documentElement){
    documentScrollTop = document.documentElement.scrollTop;
  }
  scrollTop = (bodyScrollTop - documentScrollTop > 0) ? bodyScrollTop : documentScrollTop;
  return scrollTop;
}


//文档的总高度
export function getScrollHeight(){
  var scrollHeight = 0, bodyScrollHeight = 0, documentScrollHeight = 0;
  if(document.body){
    bodyScrollHeight = document.body.scrollHeight;
  }
  if(document.documentElement){
    documentScrollHeight = document.documentElement.scrollHeight;
  }
  scrollHeight = (bodyScrollHeight - documentScrollHeight > 0) ? bodyScrollHeight : documentScrollHeight;
  return scrollHeight;
}


//浏览器视口的高度
export function getWindowHeight(){
  var windowHeight = 0;
  if(document.compatMode == "CSS1Compat"){
    windowHeight = document.documentElement.clientHeight;
  }else{
    windowHeight = document.body.clientHeight;
  }
  return windowHeight;
}

如果是触底滚动,那么条件就是: getScrollTop() + getWindowHeight() >= getScrollHeight()

下拉加载

mescroll插件。移动端实现上拉取加载 下拉刷新的
http://www.mescroll.com/
小程序上使用scroll-view组件

滚动列表

better-scroll插件
https://blog.csdn.net/lmhlmh_/article/details/80962295

https://zhuanlan.zhihu.com/p/27407024

  • better-scroll,一个页面内部可以有多个BScroll对象,只要给不同的名字this.scroll this.scroll2
  • better-scroll在谷歌浏览器的移动端预览模式下,首次加载时滑动失效,要再刷新一次才能触发效果,经过测试在真机没有问题,只是chrome浏览器会发生,可能是兼容问题
递归组件实现多级列表

https://www.cnblogs.com/fei-H/p/11359028.html

  • 无需在组件内部引入组件本身
  • 组件名称必须写
递归组件向外传递数据和事件

https://blog.csdn.net/SunShinessx/article/details/100860419?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase

  • 防止vue中bus.$on事件被多次绑定
    https://www.cnblogs.com/miny-simp/p/9834949.html
    使用方法2时,如果在同一个页面中多次使用同一个递归组件,并且需要通过递归组件触发父级页面中的不同方法,那么在监听事件之前要先销毁原来组件中事件名关联的事件
    if (this.showModel) {
      Bus.$off('taptreeitem');
      if (this.knowledgepointId) {
        Bus.$on('taptreeitem', this.knowTapItem);
        this.initScrollCol2();
      } else {
        Bus.$on('taptreeitem', this.sectionTapItem);
        this.initScrollCol();
      }
    }
前端H5移动端点击按钮复制文本到粘贴板
    // 复制链接
    copyUrl() {
      let textarea = document.createElement('textarea');
      textarea.id = 'copyTextarea';
      textarea.style.width = 0;
      textarea.style.height = 0;
      document.body.appendChild(textarea);
      let textarea2 = document.getElementById('copyTextarea');
      textarea2.innerHTML = this.urlCopy;

      if (navigator.userAgent.match(/(iPhone|iPod|iPad);?/i)) {
        const range = document.createRange();
        range.selectNode(document.getElementById('copyTextarea'));
        const selection = window.getSelection();
        if (selection.rangeCount > 0) selection.removeAllRanges();
        selection.addRange(range);
      } else {
        // 选中文本(select()方法对IOS部分版本无效)
        textarea.select();
      }

      document.execCommand('copy');
      document.body.removeChild(textarea);
      this.cancel();
      this.$showToast('复制成功');
    },
判断当前浏览器是否为微信浏览器
    // 判断浏览器环境 是否为微信自带浏览器
    isWeixinBrowser() {
      var agent = navigator.userAgent.toLowerCase();
      if (agent.match(/MicroMessenger/i) == 'micromessenger') {
        return true;
      } else {
        return false;
      }
    },
env.js
const env = {
  isDev: process.env.NODE_ENV === 'development',
  isProduct: process.env.NODE_ENV !== 'development',
  isClient: process.client,
  isServer: process.server
};
//生产环境自动屏蔽调试信息
//开发环境开启调试信息
console.debug = env.isDev ? console.debug : function() {};
// console.log = env.isDev ? console.log : function() {};
export default env;
weixin-js-sdk 说明文档

http://caibaojian.com/wxwiki/0030551f015f01ecaa56d20b88ee3c6cb32503bf.html

引入weixin-js-sdk自定义朋友圈分享
if (env.isClient) {
  var wx = require('weixin-js-sdk');
}
    // 自定义微信分享朋友圈和发送给好友 // 默认为1
    async customWxShare(url, type = 1) {
      // console.log('链接为', url);
      // 是否在微信浏览器
      if (this.isWeixinBrowser()) {
        if (type === 1) {
          var param = {
            title: '【就差你了!】学科网暑期特惠资源',
            img:
              'https://zxxkstatic.zxxk.com/mobile/v2/images/wxmini/summerActivity/card.png',
            desc: '',
            url: url
            // 'http://m.zxxk.com/activity/2020pintuan/'
          };
        } else if (type === 2) {
          // if (type === 1) {
          var param = {
            title: '不平凡的2020,我们当老师的是这样乘风破浪的',
            img:
              'https://zxxkstatic.zxxk.com/mobile/v2/images/m/h5-story/share-code.png',
            desc: '想了解我2020的“网红生涯”吗?快来看看吧。',
            url: url
            // 'http://m.zxxk.com/activity/2020pintuan/'
          };
          // }
        }
        //分享链接
        var appid = '';
        var timestamp = '';
        var token = '';
        var noncestr = '';
        this.showShareToFriends = true;
        // 获取活动详情 successCount
        let { data } = await this.$axios.get(
          api.summerActivity2020.bonusActivity
        );
        if (type === 1) {
          param.desc =
            '速来加入!25份资源仅需¥19.9~已有' +
            data.successCount +
            '人拼团成功';
        }
        this.$axios
          .get(
            'https://m.zxxk.com/api/v1/mp/get-share-info?url=' +
              window.location.href
          )
          .then(res => {
            let data2 = res.data;
            appid = data2.appId;
            timestamp = data2.timestamp;
            token = data2.token;
            noncestr = data2.nonceStr;

            if (this.isWeixinBrowser()) {
              wx.config({
                debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                appId: appid, // 必填,公众号的唯一标识
                timestamp: timestamp, // 必填,生成签名的时间戳
                nonceStr: noncestr, // 必填,生成签名的随机串
                signature: token, // 必填,签名,见附录1
                jsApiList: [
                  'updateAppMessageShareData', //1.4 分享到朋友
                  'updateTimelineShareData' //1.4分享到朋友圈
                ] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
              });
              wx.ready(() => {
                wx.updateAppMessageShareData({
                  title: param.title, // 分享标题
                  desc: param.desc, // 分享描述
                  link: param.url, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
                  imgUrl: param.img // 分享图标
                });
                wx.updateTimelineShareData({
                  title: param.title, // 分享标题
                  desc: param.desc, // 分享描述
                  link: param.url, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
                  imgUrl: param.img // 分享图标
                });
              });
            }
          });
      }
    }
轮播图
专题中的(中考,高考专题)

引入相关的css,js文件

html文件结构如下:
		<div class="content hidden">
			<div class="content-title" id="jingpin"></div>
			<div class="newSwiper">
				<div class="swiper-container">
					<div class="swiper-wrapper">
						<div class="swiper-slide"><img src="./images/swiper1.png" alt=""></div>
						<div class="swiper-slide"><img src="./images/swiper1.png" alt=""></div>
						<div class="swiper-slide"><img src="./images/swiper1.png" alt=""></div>
					</div>
					<!-- 如果需要导航按钮 -->
					<div class="swiper-button-prev"></div>
					<div class="swiper-button-next"></div>
					
				</div>
			</div>
        </div>

引入的swiper相关css文件中,swiper-container是相对定位,左右按钮swiper-button-prev 和 swiper-button-next是绝对定位,也就是相对于swiper-container的,如果要达到下面的效果

应该取消swiper-container 的相对定位,并给swiper-container增加一个父元素newSwiper,设置为相对定位,让左右按钮相对与newSwiper定位

.newSwiper {
  box-sizing: border-box;
  position: relative;
  margin-bottom: 65px;
  /* margin-top: 50px; */
}

.swiper-container {
  position: static!important;
  overflow: hidden;
  width: 84.66667%;
  margin: 0 auto;
}
.swiper-container .swiper-slide img {
  width: 92.1212%;
}
.swiper-slide {
  text-align: center;
}
.swiper-button-prev {
  left: 2.33333% !important;
  top: 50% !important;
  -webkit-transform: translateY(-50%) !important;
  transform: translateY(-50%) !important;
  margin-top: 0!important;
  width: 3.1496% !important;
  height: 30.6% !important;
  background-image: url('../images/arrow-left.png');
  background-size: 100% 100%;
}
.swiper-button-prev:hover{
  background-image: url('../images/left-active.png');
}
.swiper-button-prev:after,
.swiper-button-next:after{
  content: '' !important;
}
.swiper-button-next {
  right: 2.33333% !important;
  top: 50% !important;
  -webkit-transform: translateY(-50%) !important;
  transform: translateY(-50%) !important;
  margin-top: 0!important;
  width: 3.1496% !important;
  height: 30.6% !important;
  background-image: url('../images/arrow-right.png');
  background-size: 100% 100%;
}
.swiper-button-next:hover{
  background-image: url('../images/right-active.png');
}
    $(document).ready(function () {
        var myswiper = new Swiper ('.swiper-container', {
            loop: true, // 循环模式选项 
            slidesPerView : 3,
            centeredSlides : true,
            centeredSlidesBounds: true,   
        // 如果需要前进后退按钮
            navigation: {
              nextEl: '.swiper-button-next',
              prevEl: '.swiper-button-prev',
            }
          }) 
    })
Nuxt中 使用vue-awesome-swiper插件

vue-awesome-swiper是基于swiper的,安装不同版本的vue-awesome-swiper对应不同的swiper,所以swiper里面的属性多数能应用到vue-awesome-swiper中,也可以根据swiper文档来设置vue-awesome-swiper属性;
swiper官方文档:https://www.swiper.com.cn/api/index2.html;

参考gitHub,讲的很详细 https://github.com/surmon-china/vue-awesome-swiper

  • 服务端渲染(一般在nuxt项目中使用): 指令的形式。

    • 参考: https://www.cnblogs.com/duanzhenzhen/p/12362129.html
  • vue-awesome-swiper 基本使用及参数说明

    • 参考: https://blog.csdn.net/dwb123456123456/article/details/82701740
      // swiperOption: {
      // initialSlide: this.current,
      // observer: true,
      // observeParents: true,
      // observeSlideChildren: true,
      // autoplay: false,
      // circular: false,
      // on: {
      // slideChange: () => {
      // let swiper = this.mySwiper;
      // let activeIndex = swiper.activeIndex;
      // let year = this.year[activeIndex];
      // this.current = activeIndex;
      // this.scrollTop = 0;
      // this.typeCurrent = 0;

      // this.getPaperList(year);
      // }
      // }
      // },

弹出层后禁止弹出层后面的内容滚动

设置高度是100% 或者设置为height = 屏幕高度 然后overflow:hidden

a标签添加了链接 在网页源代码中可见 但是 阻止默认跳转
@click.prevent
<a :href="'#area_'+item.id"@click.prevent="jumpArea($event,index,item.id)">  </a>

node.js

node.js 和 pm2

node.js 文档 http://nodejs.cn/learn/introduction-to-nodejs
关于二者介绍的一篇文章 https://www.zhihu.com/question/41698682

命令

pm2 命令
pm2 ls (进程列表)
pm2 scale m-zxxk2.0 4 (搞四个进程,因为node是单线程的??)

  • 停止,重启这些命令既可以用自定义名称也可以用id
    在这里插入图片描述

ps -ef|grep nginx (查看nginx进程)包括master进程和worker进程

(命令拆解:
​ ps命令用于显示当前进程 (process) 的状态
ps:将某个进程显示出来
-A  显示所有程序
-e  此参数的效果和指定"A"参数相同。
-f  显示UID,PPIP,C与STIME栏位。
grep命令是查找
中间的|是管道命令 是指ps命令与grep同时执行
​ )
例子:https://www.cnblogs.com/feizifeiyu/p/8492550.html

https

https默认端口 443
配置证书https

sudo nginx 管理员权限打开nginx
which nginx which指令会在环境变量$PATH设置的目录里查找符合条件的文件(查看可执行文件的位置)。
我们要找的是Nginx配置文件的路径所以要转到/etc下面
1、/usr/bin下面的都是系统预装的可执行程序,系统升级有可能会被覆盖.

2、/usr/local/bin目录是给用户放置自己的可执行程序.

3、/usr/locat/etc 目录里面是程序的配置文件
首先把证书秘钥文件解压放在一个固定的地方(文件名中不要包含中文)然后去修改nginx配置文件
文件开头加上 user nobody;
(更改nginx的默认用户,因为那个 vendors.app.js 一直无法加载出来 看看下面这个文章)https://blog.csdn.net/m0_37477061/article/details/82979041?utm_source=blogxgwz4

server部分 监听的端口在原来的支持http的 listen 80;后面加上
js listen 443 ssl; ssl_certificate /Users/lichenxia/server/zxxk_certificate/zxxkxkw.com.crt(路径,mac中直接拖动文件到控制台就是路径); ssl_certificate_key /Users/lichenxia/server/zxxk_certificate/zxxkxkw.com.key(路径);
完了关闭nginx 管理员模式打开nginx

301 和 302
    301 redirect: 301 代表永久性转移(Permanently Moved)

    302 redirect: 302 代表暂时性转移(Temporarily Moved )

    ps:这里也顺带记住了两个比较相近的英语单词(permanently、temporarily),嘻哈!



    详细来说,301和302状态码都表示重定向,就是说浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址,这个地址可以从响应的Location首部中获取(用户看到的效果就是他输入的地址A瞬间变成了另一个地址B)——这是它们的共同点。他们的不同在于。301表示旧地址A的资源已经被永久地移除了(这个资源不可访问了),搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址;302表示旧地址A的资源还在(仍然可以访问),这个重定向只是临时地从旧地址A跳转到地址B,搜索引擎会抓取新的内容而保存旧的网址。

小程序

rpx

在移动端日常开发,多使用rem单位,因为它能够很好的解决屏幕适应问题。在小程序中,小程序框架提供了rpx(responsive pixel),可以根据屏幕宽度进行自适应。rpx其实是微信对于rem的一种应用的规定,或者说一种设计的方案。

小程序框架规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375(pt),共有750个物理像素(px),那么750rpx = 375pt = 750px。所以iPhone6下:1px = 1rpx =0.5pt;如果设计稿以iPhone6的分辨率(750x1334px)为基准。这样的情况下1rpx=1px。

onLoad,onReady和onShow等生命周期函数

0.onLoad - 生命周期函数–监听页面加载–页面加载时触发,且只发生一次,有些数据实时性要求不高可以onlaod里面触发对应的请求。
1.onReady - 生命周期函数–监听页面初次渲染完成–指的是“页面框架的显示”,而并非页面数据与节点加载渲染完成。页面初次渲染之后触发(只是初次,下一次页面渲染就没他什么事),只触发一次。你发送请求其实也可以把它当做onload毕竟也只是一次,但是你涉及到一些渲染的东西要注意了,设置页面标题之类的要在他之后再用。
2.onShow - 生命周期函数–监听页面显示–定义是页面显示,并不算是数据填充后的显示,而是“页面框架的加载”。切入前台触发,用我的话来讲就是这个页面出现一次,他就被调用一次包括你前进后退到这个页面。
分析:
微信小程序之所以这么设计应该是照顾到webkit内核压力的缘故,使得页面整个加载分为多个步骤,异步进行。
结论:
证明他们的执行顺序是:
onLoad >> onShow >> onReady
查询方法: wx.createSelectorQuery(),在页面响应事件中并不能查询到节点信息。
如有查询节点需求可以用延时方法或者操作事件来获取。
在这里插入图片描述

操纵dom节点

https://blog.csdn.net/qq_38128179/article/details/84661602

setTimeout(() => {
        wx.createSelectorQuery().select('#active_'+channelId).boundingClientRect(function (rect) {
          activeChannelWidth = rect.width;
          activeChannelLeft = rect.left;
          scrolljuli = activeChannelLeft - scrollLeft - scrennWidth/2 + activeChannelWidth/2;
          that.setData({
            scrollto: scrolljuli
          }) 
        }).exec()
        return scrolljuli;    
      },100)
子组件传值triggerEvent

https://blog.csdn.net/qq_40190624/article/details/87972265

页面栈
     // 获取当前小程序的页面栈
    let pages = getCurrentPages();
    
    // 可以使用pages.length 或者 pages[i].   做一些操作
   
    // 数组中索引最大的页面--当前页面
    let currentPage = pages[pages.length-1];
    // 获取当前页面的前一页面的路由
    let route = currentPage.route;
    // 如果上一页是发现页面直接跳转到同步首页 否则返回上一个页面
    if (route == 'pages/discover/discover') {
      wx.redirectTo({
        url: '/packages/synchronization/pages/index/index'
      })
    } else {
      console.log('返回上一个页面')
      wx.navigateBack({
        delta: 1
      })  

专题

serve工具包

npm安装的一个工具包 serve 就是启动了一个静态服务器 并把当前目录映射到服务器的访问路径里面,这样在终端中把当前路径切换到本地文件目录 输入serve,生成一个地址 就能给同事看了(同事需要配置一下nginx)

ie8以及以下不支持 array.foreach()

解决:在文档头部下面加入Js代码

if (typeof Array.prototype.forEach != 'function') {    Array.prototype.forEach = function(callback){      for (var i = 0; i < this.length; i++){        callback.apply(this, [this[i], i, this]);      }    };}
伪类

伪类顺序 L V H F A
注:写多个伪类的时候,必须按照 link–visited–hover–focus–active这个顺序

link表示链接在正常情况下(即页面刚加载完成时)显示的颜色。
visited表示链接被点击后显示的颜色。
hover表示鼠标悬停时显示的颜色。
focus表示元素获得光标焦点时使用的颜色,主要用于文本框输入文字时使用(鼠标松开时显示的颜色)。
active表示当所指元素处于激活状态(鼠标在元素上按下还没有松开)时所显示的颜色。

<style type="text/css">
    /*点击之前*/
    a:link {
        background-color: red;
    }
    /*点击之后状态*/
    a:visited {
        background-color: gray;
    }
    /*鼠标悬停状态*/
    a:hover {
        background-color: green;
    }
    /*点击状态*/
    a:active {
        background-color: blue;
    }
    /*改变文字的默认颜色以及消除下划线*/
    a{
        color: white;
        text-decoration: none;
    }
</style>
a 在新的页面打开一个链接
- target = '_blank' 浏览器总在一个新打开、未命名的窗口中载入目标文档。 - target = '_self ' 没有指定目标的 标签是默认目标,它使得目标文档载入并显示在相同的框架或者窗口中作为源文档。 - target = '_parent ' 文档载入父窗口或者包含来超链接引用的框架的框架集。如果这个引用是在窗口或者在顶级框架中,那么与 _self等效 - target = '_top ' 清除所有被包含的框架并将文档载入整个浏览器窗口。 #### 伪类选择器nth-child和nth-of-type ```javascript p:nth-child(odd) { /* background-color: pink; */ } p:nth-of-type(odd) { background-color: blue; } ``` p:nth-child 选择的是 p元素的父元素的第n个子元素,并且是p元素的元素(如果第n个元素不是p元素则不会选择);P:nth-of-type 选择的是p元素的父元素的 第n个p元素 #### 专题通用 css样式 ```js body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,button,textarea,p,blockquote,th,td{padding:0;margin:0;} img{border:0;vertical-align:middle;} ol,ul{list-style:none;} h1,h2,h3,h4,h5,h6{font-weight:normal;font-size:100%;} address,caption,cite,code,dfn,em,strong,th,var{font-weight:normal;font-style:normal;} button,input,select,textarea{font-size:100%;font:inherit;border:0;outline:0;} i{font-style: normal;} a{color:#333;text-decoration:none;} table{border-collapse:collapse;border-spacing:0;} .fl{float:left;} .fr{float:right;} .clearfix:before,.clearfix:after{content:"";display:table;} .clearfix:after{clear:both;} .clearfix{*zoom:1;} body{font:14px/1.5 "Microsoft YaHei",arial,simsun,sans-serif;color:#333;background: #f7f7f7;} .wrapper{margin:0 auto;width:1200px;} ``` #### jquery ```js

$(function () { });


#### 第一个子元素节点的 margin-top  会作用到父元素上
原因:css2中的规定
所有毗(pi)邻的两个或更多盒元素的margin将会合并为一个margin共享之。毗邻的定义为:同级或者嵌套的盒元素,并且它们之间没有非空内容、Padding或Border分隔。

解决:破坏毗邻的条件
1、父元素加padding
2、父元素加border
3、父元素加overflow:hidden;
4、父元素,或者子元素 加浮动或者绝对定位,(浮动或绝对定位不参与margin的折叠)
#### 首行缩进两个字符
text-indent: 2em;
#### css单位 vw vh vmix vmin
vw:相对于视口的宽度,视口被均分为100单位的vw
vh:  相对于视口的高度。视口被均分为100单位的vh
vmax: 相对于视口的宽度或高度中较大的那个。其中最大的那个被均分为100单位的vmax
vmin: 相对于视口的宽度或高度中较小的那个。其中最小的那个被均分为100单位的vmin
*均支持IE9+*

#### css背景
简写顺序
```js
background: rgba(0,0,0,.8) url('assets/images/loading.png') fixed no-repeat center / cover;
background:color img_url repeat attachment position / size
颜色, 地址,固定背景,平铺,位置,size

多背景 (第一个背景在在上面,最后一个背景在最下面)

.multi_bg_example {
  background: url(http://demos.hacks.mozilla.org/openweb/resources/images/logos/firefox-48.png),
        linear-gradient(to right, rgba(255, 255, 255, 0),  rgba(255, 255, 255, 1)),
        url(http://demos.hacks.mozilla.org/openweb/resources/images/patterns/flowers-pattern.jpg);
  background-repeat: no-repeat, no-repeat, repeat;
  background-position: bottom right, left, right;
}

背景渐变
使用线性函数(linear-gradient())或 径向(由 radial-gradient() 函数创建) 和圆锥 (由 conic-gradient 函数创建)
linear-gradient()默认是从上到下的渐变,可以指定渐变的颜色(无需局限于使用两种颜色,你想使用多少种颜色都可以! 默认情况下,所设置颜色会均匀分布在渐变路径中。)

.auto-spaced-linear-gradient {
  background: linear-gradient(red, yellow, blue, orange);
}

可以改变渐变的方向

.horizontal-gradient {
  background: linear-gradient(to right, blue, pink);
}

.diagonal-gradient {
  background: linear-gradient(to bottom right, blue, pink);
}

.angled-gradient {
  background: linear-gradient(70deg, blue, pink);
}
css3盒子阴影 box-shadow

在这里插入图片描述

需要适配多种尺寸屏幕的列表

列表结构一般是 subject > ul(清除浮动) > li(左浮动) > a (相对定位,媒体查询设置宽高)> … li 元素平分 ul,然后给 li 设置 padding 或者给 li 里面的 a 设置margin a元素的宽高,以及 a 元素内部元素的宽高都是写死的然后采用媒体查询来更换一些宽高。
使用媒体查询实现

.subject {
  position: relative;
  margin: ;
  padding: ;
  text-align: center;
}

.subject .resources-title {
  display: inline-block;
  position: absolute;
  top: px;
  left: 50%;
  transform: translate(-50%, 0);
  width: px;
  height: px;
  line-height: px;
  font-size: px;
}


.subject ul li {
  width: 50%;
  float: left;
  margin-bottom: 20px;
}
.subject ul li a {
  position: relative;
  width: 120px;
  height: 158px;
  background: url(../images/book1.png) center top no-repeat;
  background-size: 100%;
}

@media (min-width: 540px) {
  .subject {
    padding: ;
  }
  .subject .resources-title {
    width: px;
    height: px;
    line-height: px;
    font-size: px;
  }
 
  .subject ul li a {
    width: 142px;
    height: 187px;
  }
 
}

@media (min-width: 768px) {
  .subject ul li {
    width: 33.33%;
  }
}

@media (min-width: 992px) {
  .subject ul li {
    width: 25%;
  }
}

@media (min-width: 1200px) {
  .subject {
    width: 1200px;
    margin: 0 auto 50px;
    box-sizing: border-box;
  }
  .subject ul li {
    width: 20%;
  }
}
侧导航

使用锚点实现跳转

    <div class="sidebar">
        <img src="./images/topImg.png" alt="" class="img1">
        <div class="subnav">
            <a href="#december">202012</a>
            <a href="#november">202011</a>
            <a href="#december">202012</a>
            <a href="#november">202011</a>
            <a href="#december">202012</a>
            <a href="#november">202011</a>
            <a href="#december">202012</a>
        </div>
        <a href="#top" class="img2"><img src="./images/subbottom2.png" alt=""></a>
    </div>
    要跳转到的地方关联 id="december" id="november"  id="top" ....

锚链接实现平滑跳转

    $(".subnav a").click(function (e) {

        var $anchor = $(this);

        $("body,html").stop().animate({

            scrollTop: $($anchor.attr("href")).offset().top

        }, 1000);

        e.preventDefault();

    });

屏幕尺寸够用时 淡入 淡出;屏幕尺寸不够时不显示侧导航

css
.sidebar {
position: fixed;
right: 150px;
top: 50%;
margin-top: -254px;
display: none;
}
$(function () {
    $(window).scroll(function () {
        if ($(window).width() > 1200 && $(window).scrollTop() > 400) {
            $(".sidebar").fadeIn(1000);
        } else {
            $(".sidebar").fadeOut(1000);
        }
    });
});
底部和头部的链接

网页的头部logo 一般是一个链接 底部和版权声明放在一起的文字 也有很多是链接 做的时候要看一看
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值