页面常见问题

2018-12-25  本文已影响7人  sweetBoy_9126
  1. 单屏页面,高度给100%,窗口缩小的情况下顶部内容会不显示
    解决办法:给一个最小高度。

  2. 让一张背景图模糊,不能直接在这个div设置filter:blur(5px),如果直接给设置了背景的div元素设置模糊,那么它里面的字什么的都会变模糊
    解决方法:给这个元素加一个伪元素,给这个伪元素使用模糊,这时候会有毛边,只需要定位的时候给left:-10px;right:-10px;top:-10px;bottom:-10px;把设置的宽和高去掉就可以。

<div class="cover">
  你好
</div>
.cover{
  position: relatvie;
}
.cover::before{
  content: '',
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: transparent url('') center center no-repeat;
  filter: blur(5px);
  background-size: cover
}

或者在最大的父元素里给一个没有子元素的div,设置绝对定位,背景图片和filter

<div class="contain">
  <div class="wrapper">
  </div>
  <div class="main">aaa</div>
</div>
.contain{
  width: 400px;
  height: 400px;
 position: relative;
}
.wrapper{
  position: absolute;
  left: -10px;
  top: -10px;
  bottom: -10px;
  right: -10px;
  display:block;
   background: url("http://pkl6kjvxu.bkt.clouddn.com/boy.jpg") no-repeat;
  filter: blur(5px);
  z-index: -4;
}
  1. 事件委托的使用
    只有可以冒泡的事件才能使用事件委托,因为这样子元素触发事件的时候才能通知父元素(也就是点击子元素会冒泡到父元素),而不支持冒泡的事件就无法使用事件委托
    jq的事件委托写法:
//on前面是需要监听的元素的父元素,后面是事件,和需要监听的元素,以及回调
$('ul').on('click','li',(e)=>{

})

4.在循环中有异步事件,如何在循环外获取最后一次异步操作的结果
比如:循环中我需要通过异步操作将每次获得的数据添加到一个数组中,这时我需要在数组外面拿到最后循环结束的结果,如果直接在循环外获取这个数组的值,因为有异步操作所以一开始拿到的会是初始的空数组,而点开这个空数组才是我们的值。
解决方法:
因为是循环也就是会有多个异步事件,所以我们需要创建多个promise,我们需要一开始声明一个promises为空的数组,然后在循环里对这个promises进行push,push里面就是你要进行的异步操作,之所以需要使用多个promise就是因为如果单纯只是使用一个基本类型的promise赋值,每次循环后面的都会把前面的覆盖掉,所以最后通过.then判断的只是最后一次的promise执行的结果,这里通过数组,把所有的promise事件都添加到数组里,然后再循环外使用Promise.all(promises).then()就可以进行循环里所有promise都执行完之后的操作了

let arr = []
let songsId = [1,2,3]
let promises = []
songsId.map(songId=>{
  var song = AV.Object.createWithoutData('Song', songId);
  // 修改属性
 song.set('dependent', this.playlist);
 // 保存到云端
 promises.push(song.save().then(data=>{
     //异步操作直接push进promises数组里
     arr.push(data)
 }))
})
Promise.all(promises)then(()={
  console.log(arr)
})

5.在对dom元素重新渲染的过程中,如果dom元素是一开始就存在于页面中,那么你后期对它里面添加东西,可能不会同步更新,只能刷新页面后才可以,原因是有一部分内容存在了内存里,有一部分留在了dom里,解决方法,将需要添加的元素的父级元素也动态添加,比如通过一个template
如:

<div class="right">
        <h1>已有歌单</h1>
        <div class="list">
            <ul class="list-main"></ul> 
        </div>
    </div>
render(data){
    let {playlists} = data
    playlists.map(playlist=>{
        let {id, name, summary, cover} = playlist
        console.log(name)
        let $li = $(`
        <li>
            ${name}
            <div class="edit">
                <button class="edit-playlist">编辑专辑</button>
                <button class="edit-songs">编辑歌曲</button>
                <button class="delete-playlist">删除专辑</button>
            </div>
        </li>`).attr('data-playlist-id',id)
        this.$el.find('ul').append($li)
    })   
}

上面的代码,比如你更改了playlists,然后重新调用了一下render,一开始是playlists:[{name:1},{name:2}],后来更改为playlists:[{name:3},{name:2}]后,你会发现dom里显示的还是1,2,但是你在上面打印的name却是最新的3,2,原因就是你的这新的ul留在了内存中,但并未在dom里,解决方法,就是让他的父级ul也动态加载,然后每次重新渲染一下它的父级

<div class="right">
        <h1>已有歌单</h1>
        <div class="list">
            
        </div>
    </div>
template: `
    <ul class="list-main"></ul>  
`,
render(data){
    this.$el.find('.list').html(this.template)
    let {playlists} = data
    playlists.map(playlist=>{
        let {id, name, summary, cover} = playlist
        let $li = $(`
        <li>
            ${name}
            <div class="edit">
                <button class="edit-playlist">编辑专辑</button>
                <button class="edit-songs">编辑歌曲</button>
                <button class="delete-playlist">删除专辑</button>
            </div>
        </li>`).attr('data-playlist-id',id)
        this.$el.find('ul').append($li)
    })   
}

6.如何实现单页面里的tab栏每次刷新都定位到点击的位置,而不是初始位置?
实现方法:通过给页面url添加一个#,然后每点击一个tab栏对应的在#后面添加一个参数,每次通过location.hash来获取你#后面的内容,通过后面的参数来对应让哪一个tab里的内容显示

<div class="page tabs">
  <ol class="tabs-nav">
          <li data-tab-name="page-1"> <div class="text"> 推荐音乐 </div> </li>
          <li data-tab-name="page-2"><div class="text">热歌榜</div></li>
          <li data-tab-name="page-3"><div class="text">搜索</div></li>
   </ol>
  <ol class="tab-content noCollapse">
    <li class="page-1 active"></li>
    <li class="page-2 active"></li>
    <li class="page-3 active"></li>
  </ol>
</div>
{
    let view = {
        el: '.tabs',
        $el: null,
        init(){
            this.$el = $(this.el)
        }
    }
    let model = {}
    let controller = {
        tab: '',
        init(view, model){
            this.view = view
            this.model = model
            this.view.init()
            this.locationInit()
            this.bindEvent()
        },
        bindEvent(){
            this.view.$el.find('.tabs-nav').on('click','li',(e)=>{
                let $li = $(e.currentTarget)
                $li.addClass('active').siblings().removeClass('active')
                let tabName = $li.attr('data-tab-name')
                location.href = `index.html#tab=${tabName}`
                this.locationInit()
            })
        },
        locationInit(){
            let search = location.hash
            if(!search){
                location.href += `#tab=page-1`
            }
            this.tab = search.substring(1).split('=')[1]
            this.positionTab()
        },
        positionTab(){
            let tabs = ['page-1','page-2','page-3']
            tabs.map(tab=>{
                if(this.tab === tab){
                    this.view.$el.find(`.tab-content > .${tab}`).addClass('active')
                    this.view.$el.find(`.tabs-nav > li[data-tab-name=${tab}]`).addClass('active')
                }else{
                    this.view.$el.find(`.tab-content > .${tab}`).removeClass('active')
                    this.view.$el.find(`.tabs-nav > li[data-tab-name=${tab}]`).removeClass('active')
                }
            })
        }
    }
    controller.init(view, model)
}

7.对于事件监听,不管一开始有没有对应的监听事件触发,只要它执行过,后面就只要一触发对应的事件,监听里就会拿到,就像监听一个点击事件一样,一开始页面没有点击事件,但是执行了这个监听事件,后面你每次点击,他都会监听到得到相应的结果,所以在vue中你可以把所有的事件监听都写在created里,只要调用一次就可以

created(){
  this.eventBus.$on('new',(data)=>{
    console.log(data)
  })
}

8.冒泡需要时间,当你给一个点击事件添加一个点击的事件监听的时候,你只需点击一次就可以添加这个事件监听,同时执行它

<div id="app">
  <div @click="one">aaa</div>
</div>
  <script>
    let app = new Vue({
      el: '#app',
     methods: {
       one(){
         console.log(0)
         document.addEventListener('click',()=>{
           console.log(1)
         })
       }
     }
     
  })
  </script>

上面的代码,点击一次就可以打印出0和1,具体代码执行是,当你点击aaa触发one,然后开始冒泡,因为冒泡需要时间所以接着就会打印出0,然后给document添加一个监听,之后冒泡到docuemnt,执行了这个事件监听的函数,打印出了1(也就是先监听了docuemnt后冒泡到docuemnt)。所以如果想不让第一次就执行监听里的函数,那么就要给它加一个时间,让它在冒泡后执行

上一篇下一篇

猜你喜欢

热点阅读