利用原生js实现简易照片墙

效果演示

基本布局

<ul id="pic">
        <li>
            <img data-index="0" src="./images/pic1.jpg" alt="">
        li>
        <li>
            <img data-index="1" src="./images/pic2.jpg" alt="">
        li>
        <li>
            <img data-index="2" src="./images/pic3.jpg" alt="">
        li>
        <li>
            <img data-index="3" src="./images/pic4.jpg" alt="">
        li>
        <li>
            <img data-index="4" src="./images/pic5.jpg" alt="">
        li>
        <li>
            <img data-index="5" src="./images/pic6.jpg" alt="">
        li>
        <li>
            <img data-index="6" src="./images/pic7.jpg" alt="">
        li>
        <li>
            <img data-index="7" src="./images/pic8.jpg" alt="">
        li>
        <li>
            <img data-index="8" src="./images/pic9.jpg" alt="">
        li>
        <li>
            <img data-index="9" src="./images/pic10.jpg" alt="">
        li>
    ul>

css样式

* {
            margin: 0;
            padding: 0;
        }

        html,
        body,
        ul {
            width: 100%;
            height: 100%;
        }

        #pic {
            position: relative;
            list-style: none;
        }

        #pic li {
            position: absolute;
            width: 180px;
            height: 250px;
            box-shadow: 0 0 10px #000;
            transition: all 1s;
        }

        #pic li img {
            width: 100%;
            height: 100%;
        }

        /* 这里主要是处理点击事件 */
        #pic li.active {
           /* 这里设置的优先级不够高 ,所以要加上!important
            因为在后面用js控制li的style行为时,相当于是添加了内联style,它的优先级只有!important才能超越*/
            left: 50% !important;
            top: 50% !important;
            transform: rotate(0deg) translate(-50%, -50%) scale(1.5, 1.5) !important;
            z-index: 99;
        }

js部分

  • 1、设置每张照片的位置
    • 首先计算出每张照片可以偏移的距离,然后利用Math.random()随机产生要设置的left、top距离;同理,每张图片旋转的角度也是通过设置产生随机数。
    • 具体实现过程如下
     var pic = document.getElementById('pic')
        // 获取所有li标签
        var allLis = pic.children
        // 求出屏幕中照片可设置的宽高位置
        var screenW = document.documentElement.clientWidth - 250
        var screenH = document.documentElement.clientHeight - 360
    
        for (let i = 0; i < allLis.length; i++) {
            // 取出单个li标签
            var oLi = allLis[i]
            // 随机分布
            oLi.style.left = Math.random() * screenW + 'px'
            oLi.style.top = Math.random() * screenH + 'px'
    
            // 随机角度
            oLi.style.transform = `rotate(${Math.random() * 360}deg)`
        }
    
  • 2、给每张照片添加点击事件
 			// 添加点击事件
            // oLi.onclick = function() {
            //     // 清空所有li的className
            //     for(let i = 0;i < allLis.length;i++) {
            //         allLis[i].className = ''
            //     }
            //     this.className = 'active'
            // }
                // 这里可以利用事件冒泡,实现事件代理,当照片很多的时候不用给每个li标签添加事件,从而达到优化
            pic.addEventListener('click', function (e) {
            	e = e || window.event
                if (e.target.nodeName.toLowerCase() == 'img') {
                    for (let j = 0; j < allLis.length; j++) {
                        console.log(j);
                        allLis[j].className = ''
                    }
                    // 这里利用的是html5的新属性,给每个img标签添加data-index属性
                    let index = e.target.getAttribute('data-index')
                    allLis[index].className = 'active'
                }
            })
  • 3、创建动态的li标签
    • 首先采用最原始的方法动态创建li标签
     for(let i = 0;i < 10;i++) {
            // 创建li标签
            var li = document.createElement('li')
            // 创建img标签
            var img = document.createElement('img')
            img.src = './images/pic'+ (i + 1) + '.jpg'
            img.setAttribute('data-index',i)
            li.appendChild(img)
            pic.appendChild(li)
        }
    
    • 还有一种比较简便的写法,就是利用es6的模板字符串
     for(let i = 0;i < 10;i++) {
            // 也可以使用es6中的模板字符串
            pic.innerHTML += ` 
  • ${i}" src="./images/pic${i+1}.jpg" alt="">
  • `
    }
    • 最后一种方法是利用文档碎片DocumentFragment,如果要创建非常多的li标签,该方法大大优化性能。
      官方文档对DocumentFragment的解释:
      利用原生js实现简易照片墙_第1张图片
// 采用文档碎片的方式,可以减少对dom的操作
        var fragment = document.createDocumentFragment()
       for(let i = 0;i < 10;i++) {
           var li = document.createElement('li')
           li.innerHTML = `${i}" src="./images/pic${i+1}.jpg" alt="">`
           fragment.appendChild(li)
       }
    //    只需要在最后一次添加到pic时,才操作dom,这也是一种优化

全部代码

DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="">
    <title>Documenttitle>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        html,
        body,
        ul {
            width: 100%;
            height: 100%;
        }

        #pic {
            position: relative;
            list-style: none;
        }

        #pic li {
            position: absolute;
            width: 180px;
            height: 250px;
            box-shadow: 0 0 10px #000;
            transition: all 1s;
        }

        #pic li img {
            width: 100%;
            height: 100%;
        }

        /* 这里主要是处理点击事件 */
        #pic li.active {
            /* 这里设置的优先级不够高 ,所以要加上!important*/
            left: 50% !important;
            top: 50% !important;
            transform: rotate(0deg) translate(-50%, -50%) scale(1.5, 1.5) !important;
            z-index: 99;
        }
    style>
head>

<body>
    <ul id="pic">
    ul>
    <script>
        var pic = document.getElementById('pic')
        // 创建动态li标签,在实际情况中,创建多少标签取决于从服务器中获取的照片数量,这里只是简单的实现
        // 采用文档碎片的方式,可以减少对dom的操作
        var fragment = document.createDocumentFragment()
       for(let i = 0;i < 10;i++) {
           var li = document.createElement('li')
           li.innerHTML = `${i}" src="./images/pic${i+1}.jpg" alt="">`
           fragment.appendChild(li)
       }
    //    只需要在最后一次添加到pic时,才操作dom,这也是一种优化
       pic.appendChild(fragment)
        // for(let i = 0;i < 10;i++) {
        //     // 创建li标签
        //     var li = document.createElement('li')
        //     // 创建img标签
        //     var img = document.createElement('img')
        //     img.src = './images/pic'+ (i + 1) + '.jpg'
        //     img.setAttribute('data-index',i)
        //     li.appendChild(img)
        //     pic.appendChild(li)
        //     // 也可以使用es6中的模板字符串
        //     pic.innerHTML += ` 
  • // //
  • `
    // } // 获取所有li标签 var allLis = pic.children // 求出屏幕中照片可设置的宽高位置 var screenW = document.documentElement.clientWidth - 250 var screenH = document.documentElement.clientHeight - 360 for (let i = 0; i < allLis.length; i++) { // 取出单个li标签 var oLi = allLis[i] // 随机分布 oLi.style.left = Math.random() * screenW + 'px' oLi.style.top = Math.random() * screenH + 'px' // 随机角度 oLi.style.transform = `rotate(${Math.random() * 360}deg)` // 添加点击事件 // oLi.onclick = function() { // // 清空所有li的className // for(let i = 0;i < allLis.length;i++) { // allLis[i].className = '' // } // this.className = 'active' // } // 这里可以利用事件冒泡,实现事件代理,当照片很多的时候不用给每个li标签添加事件,从而达到优化 pic.addEventListener('click', function (e) { e = e || window.event if (e.target.nodeName.toLowerCase() == 'img') { for (let j = 0; j < allLis.length; j++) { allLis[j].className = '' } let index = e.target.getAttribute('data-index') allLis[index].className = 'active' } }) }
    script> body> html>

    你可能感兴趣的:(笔记,javascript,css,html)