Skip to content

场景应用

各种场景应用题。

一、炉石传说3D卡片

鼠标悬停于卡片之上时,触发3D旋转与缩放效果。

代码实现:

vue
<template>
  <div class="playing-card">
    <div class="playing-card-front"></div>
  </div>
</template>

<script setup>
import { onMounted, onUnmounted, ref } from 'vue';

// 引用卡片元素
const card = ref(null);
const cardFront = ref(null);

onMounted(() => {
  card.value = document.querySelector('.playing-card');
  cardFront.value = document.querySelector('.playing-card-front');

  const handleMouseMove = (e) => {
    if (!card.value ||!cardFront.value) return;
    const rect = card.value.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;
    const halfWidth = card.value.offsetWidth / 2;
    const halfHeight = card.value.offsetHeight / 2;
    const dx = (x - halfWidth) / halfWidth;
    const dy = (y - halfHeight) / halfHeight;
    cardFront.value.style.transform = `scale(1.1) rotateY(${dx * -20}deg) rotateX(${dy * 20}deg)`;
  };

  const handleMouseOut = () => {
    if (cardFront.value) {
      cardFront.value.style.transform = 'none';
    }
  };

  card.value.addEventListener('mousemove', handleMouseMove);
  card.value.addEventListener('mouseout', handleMouseOut);

  // 在组件销毁时移除事件监听器,避免内存泄漏
  onUnmounted(() => {
    if (card.value) {
      card.value.removeEventListener('mousemove', handleMouseMove);
      card.value.removeEventListener('mouseout', handleMouseOut);
    }
  });
});
</script>

<style scoped>
/* 整体页面布局 */
body {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  margin: 0;
  background-color: #f0f0f0;
}

/* 扑克卡片容器 */
.playing-card {
  width: 240px;
  height: 330px;
  border-radius: 10px;
  overflow: visible;
  perspective: 700px;
  cursor: pointer;
  position: relative;
}

/* 扑克卡片正面 */
.playing-card-front {
  width: 100%;
  height: 100%;
  background-image: url('/xiaoxiayan.png');
  background-size: cover;
  transform-style: preserve-3d;
  will-change: transform;
  transition: all 1s cubic-bezier(0.03, 0.98, 0.52, 0.99);
}
</style>

二、复制文本到剪切板

html
<!DOCTYPE html>
<html lang="en">

<body>
<button onclick="copyText('要复制的文本')">复制文本</button>
<script>
    function copyText(text) {
        navigator.clipboard.writeText(text).then(() => {
            console.log('已复制到剪切板');
        }, (err) => {
            console.error('复制失败:', err);
        });
    }
</script>
</body>

</html>
  • document.execCommand

原理:document.execCommand方法主要用于在文档的可编辑区域(如contenteditable属性为true的元素或textarea、input等表单元素)执行各种命令。在复制文本到剪贴板的场景中,它通过操作选中的文本来实现复制功能。 使用场景:在不支持navigator.clipboard.writeText的较旧浏览器中发挥作用,以提供一种相对兼容的方式来实现复制文本的功能。不过,这种方法存在一些局限性,并且在现代浏览器开发中逐渐被废弃。

html
   <!DOCTYPE html>
   <html lang="en">
   <body>
       <input type="text" id="textToCopy" value="要复制的文本">
       <button onclick="copyText()">复制文本</button>
       <script>
           function copyText() {
               var textToCopy = document.getElementById('textToCopy').value;
               var textarea = document.createElement('textarea');
               textarea.value = textToCopy;
               document.body.appendChild(textarea);
               textarea.select();
               try {
                   return document.execCommand('copy');
               } catch (err) {
                   console.error('复制失败:', err);
                   return false;
               } finally {
                   document.body.removeChild(textarea);
               }
           }
       </script>
   </body>
   </html>

三、对象扁平化

js
const obj = {
    a: 1,
    b: [1,2,3],
    c: {
      d: [2,3,4, {
        ok: true,
        fine:[100,200]
      }],
      e: {
        f: false,
        g: null
      }
    },
    h: undefined
  }

这样的对象扁平化为

json
{
  "a": 1,
  "b[0]": 1,
  "b[1]": 2,
  "b[2]": 3,
  "c.d[0]": 2,
  "c.d[1]": 3,
  "c.d[2]": 4,
  "c.d[3].ok": true,
  "c.d[3].fine[0]": 100,
  "c.d[3].fine[1]": 200,
  "c.e.f": false
}

去除掉 undefinednull

递归实现

js
function flatten(obj) {
  let res = {};

  function flat(obj, prefix) {
    if (!(typeof obj === 'object') && obj !== null && obj !== undefined) {
      res[`${prefix}`] = obj;
    } else {
      if (obj instanceof Array) {
        for (let i = 0; i < obj.length; i++) {
          flat(obj[i], `${prefix}[${i}]`);
        }
      } else {
        for (let key in obj) {
          if (prefix) {
            flat(obj[key], `${prefix}.${key}`)
          } else {
            flat(obj[key], key)
          }
        }
      }
    }
  }

  flat(obj, '');

  return res;
}