返回

Vue移动端取色器失效:EyeDropper API 兼容性解决方案

vue.js

移动浏览器上取色器失效问题解析

在Vue 3组合式API项目中,使用 EyeDropper API 尝试实现颜色选取功能时,可能遭遇在桌面浏览器运行正常,但在移动浏览器上失效的问题。这类问题主要由移动浏览器对 EyeDropper API 支持度不足或实现方式差异造成。本文分析问题根源,并提供解决方案。

问题的根本原因

EyeDropper API 是一项较新的Web API,它允许用户从屏幕上的任意像素选择颜色。尽管大多数桌面浏览器(例如Chrome、Edge、Safari)都支持这个API,但部分移动浏览器,特别是旧版本或一些特定的浏览器,尚未完全支持此功能。 某些移动浏览器即使提供了该API的入口,但在行为或结果方面可能与预期不同。简而言之,问题根本在于兼容性。

解决方案与代码示例

解决方案一:Feature Detection 与回退方案

首先要确认浏览器是否支持 EyeDropper API 。若不支持,则采用回退方案,使用其它颜色选择方案,如<input type="color">,或引入第三方颜色选择组件。

  1. 检测API是否存在 : 确保 window 对象具有 EyeDropper 属性。
  2. 提供回退 : 如果检测为 false ,不调用EyeDropper API, 而是显示其他组件或方式让用户选择颜色。
<template>
    <button @click="openColorPicker">选择颜色</button>
     <input type="color"  ref="fallbackColorInput" style="display:none" @input="handleFallbackColorChange"/>
  <div v-if="selectedColor" >当前颜色:{{selectedColor}}</div>
</template>

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

const selectedColor = ref('');
const fallbackColorInput = ref(null)

const openColorPicker = async () => {
  if (!window.EyeDropper) {
     fallbackColorInput.value.click(); //调用<input type='color'的弹框
     return
    
  }
  
  try{
    const eyeDropper = new window.EyeDropper();
    const result = await eyeDropper.open();
     selectedColor.value = result.sRGBHex
  } catch(error){
    console.error('Error picking the color:', error);
  }

};
const handleFallbackColorChange=()=>{
     selectedColor.value = fallbackColorInput.value.value;
     fallbackColorInput.value.value=null;

}
</script>

此方法优点:

  • 保证了用户在不支持 EyeDropper API 的浏览器上仍然可以选取颜色。
  • 提升用户体验,减少应用功能因兼容性问题造成的不可用。

安全提示:

  • 用户从 input 组件选取颜色时, 需要注意处理输入的值,进行合法性检查。

解决方案二:第三方库增强兼容性

某些开源JavaScript库对EyeDropper API进行兼容性处理, 或提供了功能相近的组件。考虑使用这些库来处理移动浏览器上的颜色选取需求,而不是自己手动进行兼容性处理。

  1. 选择合适的库 :根据项目需求和库的成熟度,选取合适的第三方库。 例如 vanilla-pickeriro.js 等。
  2. 集成和配置 :参考库文档进行安装配置,实现颜色选取功能。
    vanilla-picker 为例,首先需要安装
npm install vanilla-picker

然后,将库整合进 Vue 3 代码。

<template>
    <button ref="pickerBtn">选择颜色</button>
     <div v-if="selectedColor" >当前颜色:{{selectedColor}}</div>
</template>
<script setup>
import { onMounted,ref } from 'vue';
import Picker from 'vanilla-picker'

const selectedColor = ref('');
const pickerBtn = ref(null);
onMounted(() => {
     new Picker({
      parent: pickerBtn.value,
        popup: "bottom", 
    }).onDone((color) => {
        selectedColor.value =  color.hex
      
    })
    });
</script>

此方法优点:

  • 简化兼容性代码编写工作。
  • 可能提供额外的特性和自定义选项,满足更复杂的场景。
  • 由维护者跟进浏览器兼容性,减少开发者维护工作量。

安全提示:

  • 在使用第三方库时, 优先选择更新频率高、社区活跃的开源库。
  • 阅读库的文档和使用说明, 了解其行为,特别是安全性部分。

解决方案三:考虑其它用户输入方法

如果用户选取的颜色来源不是固定的,用户有可能想自己设置,而非简单的从屏幕像素点中获取, 可以同时提供多样的色彩选取方式。比如, 提供预定义颜色选择、输入颜色值的文本框等多种用户选择颜色的渠道。

<template>
  <div >
      <div class="color-select-area" >
      <button @click="pickColor('red')" style="background-color:red">red</button>
      <button  @click="pickColor('blue')" style="background-color:blue">blue</button>
    </div>

     <input type="text" v-model="customColor" placeholder="自定义颜色 例如:#ffffff"  />
     <button  @click="saveColor"  >保存自定义颜色</button>
     <button  @click="openColorPicker" >屏幕取色</button>
     <div v-if="selectedColor" >当前颜色:{{selectedColor}}</div>
  </div>
</template>

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

const selectedColor = ref('');
const customColor = ref('')


const pickColor = (color) =>{
   selectedColor.value = color
}
const saveColor=()=>{
    selectedColor.value = customColor.value;
}
const openColorPicker=async () => {
  if (!window.EyeDropper) {
   alert('您的浏览器不支持 EyeDropper API ,请尝试其他取色方法');
     return

  }
  try{
    const eyeDropper = new window.EyeDropper();
    const result = await eyeDropper.open();
    selectedColor.value = result.sRGBHex
  }catch(error){
     console.log('取色出错',error)
  }
};

</script>

<style scoped>
.color-select-area {
    display: flex;
}
.color-select-area button {
    padding: 5px;
    margin-left: 5px;
    border:none;
    cursor: pointer;

}
</style>

此方法优点:

  • 为用户提供了多样选择颜色的方式。
  • 提升了应用的用户友好度和可访问性。
  • 能适应不同设备和用户的使用习惯。

安全提示:

  • 要对用户输入的颜色字符串进行校验,避免接受不合法的输入。

总结

在Web开发中处理API兼容性问题非常常见。面对移动浏览器不支持 EyeDropper API 的情况,需要考虑多个方案,以便兼顾不同设备的差异,为用户提供更稳定友好的体验。选用合适的方案应该综合考虑项目需求、维护成本及目标用户的设备分布情况, 做出最优选择。