wingmeng / front-end-quiz

前端小测试答题收集
0 stars 0 forks source link

DOM基础测试39:缩略图查看与拖动排序 #35

Open wingmeng opened 4 years ago

wingmeng commented 4 years ago

题目:

image


我的回答:

> Demo <

//zxx: 拖不动,除了拖到最后

wingmeng: 多谢张老师,昨晚太困了 js 逻辑没写完 :cry: ,今早才补完的

.img-list {
  display: flex;
  flex-wrap: wrap;
  width: 260px;
  background: #fff;
  border: 1px solid #ccc;
  transition: all .2s;
}

.img-list.is-dragenter {
  background: #ffd;
  border-color: #333;
}

.img-list > img {
  max-width: 33.3333%;
  padding: 2px;
  box-sizing: border-box;
  cursor: move;
}

.img-preview img {
  display: block;
  max-width: 100%;
}
.img-preview::backdrop {background: rgba(0, 0, 0, .6);}
<div class="img-list" id="imgList">
  <img src="https://cdn.pixabay.com/photo/2014/12/30/13/19/girls-583917_960_720.jpg" alt="海边女孩">
  <img src="https://cdn.pixabay.com/photo/2019/10/21/10/33/garden-4565700_960_720.jpg" alt="花园">
  <img src="https://cdn.pixabay.com/photo/2019/10/27/18/48/chinatown-4582511_960_720.jpg" alt="都市">
  <img src="https://cdn.pixabay.com/photo/2016/12/03/14/20/woman-1879905_960_720.jpg" alt="金发女郎">
  <img src="https://cdn.pixabay.com/photo/2019/10/08/18/13/matterhorn-4535693_960_720.jpg" alt="山峰">
  <img src="https://cdn.pixabay.com/photo/2017/04/22/10/15/sport-2250970_960_720.jpg" alt="运动">
  <img src="https://cdn.pixabay.com/photo/2013/06/10/09/23/morocco-123978_960_720.jpg" alt="沙漠">
</div>
const viewImgList = {
  init(selector) {
    this.el = document.querySelector(selector);
    this.dialog = null;
    this.bindClick();
    this.bindDrag();
  },
  bindClick() {
    // 图片点击事件
    this.el.addEventListener('click', e => {
      if (e.target.tagName.toLowerCase() === 'img') {
        this.togglePreview(e.target.src);
      }
    });

    // 任意位置点击
    window.addEventListener('click', e => {
      if (!this.el.contains(e.target)) {
        this.togglePreview(false);
      }
    });
  },
  bindDrag() {
    let imgElm = null;
    const isInside = elm => elm === this.el || this.el.contains(elm);

    // 拖动开始
    this.el.addEventListener('dragstart', e => {
      e.target.style.opacity = 0;
      imgElm = e.target;
    });

    // 拖动结束
    this.el.addEventListener('dragend', e => e.target.style.opacity = '');

    // 放置目标
    document.addEventListener('dragover', e => {
      if (isInside(e.target)) {
        e.preventDefault();

        if (e.target === this.el) {
          this.el.appendChild(imgElm);
        } else {
          const compareValue = imgElm.compareDocumentPosition(e.target);

          if (compareValue === 2) {  // 目标图片在前
            e.target.before(imgElm);  // 添加到目标图片前面
          } else if (compareValue === 4) {  // 目标对象在后
            e.target.after(imgElm);  // 添加到目标图片后面
          }
        }
      }
    });

    // 进入目标区域
    document.addEventListener('dragenter', e => {
      this.el.classList[isInside(e.target) ? 'add' : 'remove']('is-dragenter');
    });

    // 允许放置
    this.el.addEventListener('drop', e => {
      e.preventDefault();
      this.el.classList.remove('is-dragenter');
    });
  },
  togglePreview(src) {
    if (src) {
      this.buildDialog(src);
      this.dialog && !this.dialog.open && this.dialog.showModal();          
    } else {
      this.dialog && this.dialog.close();
      this.destoryDialog();
    }
  },
  buildDialog(imgSrc) {
    const dialog = document.createElement('dialog');
    const img = new Image();

    dialog.className = 'img-preview';
    img.src = imgSrc;
    this.dialog = dialog;
    dialog.appendChild(img);
    document.body.appendChild(dialog);
  },
  destoryDialog() {
    this.dialog && document.body.removeChild(this.dialog);
    this.dialog = null;
  }
};

viewImgList.init('#imgList');