Skip to content

Commit

Permalink
Update OwO.min.js
Browse files Browse the repository at this point in the history
DOM操作:原生的 document.querySelector 和 document.querySelectorAll 被 jQuery 的选择器替代,使用 $() 来获取和操作 DOM 元素。
事件绑定:原生 addEventListener 被 jQuery 的 .on() 方法替代,简化了事件绑定。
元素的操作:比如 classList.add、classList.remove 变成了 jQuery 的 .addClass() 和 .removeClass(),style 也使用了 .css() 方法进行简化。
获取数据属性:原生的 getAttribute() 变成了 .data() 方法。
  • Loading branch information
riceshowerX authored Nov 29, 2024
1 parent 74a42af commit 54e76c5
Showing 1 changed file with 59 additions and 88 deletions.
147 changes: 59 additions & 88 deletions js/OwO.min.js
Original file line number Diff line number Diff line change
@@ -1,77 +1,66 @@
(() => {
// 表情面板的类
class OwO {
constructor(option) {
// 默认配置项
const defaultOption = {
logo: 'OwO表情', // Logo文字
container: document.getElementsByClassName('OwO')[0], // 面板容器
target: document.getElementsByTagName('textarea')[0], // 输入框目标
position: 'down', // 面板位置
width: '100%', // 宽度
maxHeight: '250px', // 最大高度
api: '/usr/themes/PureSuck/js/OwO.json' // 表情数据的 API 地址
logo: 'OwO表情',
container: $('.OwO')[0], // 使用jQuery选择器
target: $('textarea')[0], // 使用jQuery选择器
position: 'down',
width: '100%',
maxHeight: '250px',
api: '/usr/themes/PureSuck/js/OwO.json'
};
// 合并用户传入的配置和默认配置
Object.assign(defaultOption, option);
this.container = defaultOption.container;
this.target = defaultOption.target;

// 如果设置了面板位置为 'up',则为容器添加相应的样式
if (defaultOption.position === 'up') {
this.container.classList.add('OwO-up');
$(this.container).addClass('OwO-up');
}

// 发起请求,获取表情数据
this.fetchEmojiData(defaultOption.api).then(data => {
this.odata = data;
this.init(defaultOption); // 初始化表情面板
this.init(defaultOption);
}).catch(error => {
console.error('加载表情数据失败:', error);
});
}

// 获取表情数据
async fetchEmojiData(api) {
const cachedData = localStorage.getItem('owoEmojiData');
if (cachedData) {
return JSON.parse(cachedData); // 如果有缓存,直接返回缓存数据
}
if (cachedData) return JSON.parse(cachedData);

try {
const response = await fetch(api);
if (!response.ok) throw new Error(`HTTP 错误!状态:${response.status}`);
const data = await response.json();
localStorage.setItem('owoEmojiData', JSON.stringify(data)); // 缓存数据
localStorage.setItem('owoEmojiData', JSON.stringify(data));
return data;
} catch (err) {
throw new Error(err);
}
}

// 初始化面板
init(option) {
this.area = option.target;
this.packages = Object.keys(this.odata); // 获取表情包的所有类型
this.packages = Object.keys(this.odata);

// 拼接面板的HTML
let html = `
<div class="OwO-logo"><span>${option.logo}</span></div>
<div class="OwO-body" style="width: ${option.width}">`;

// 遍历表情包类型,生成相应的HTML
this.packages.forEach(pkg => {
const packageData = this.odata[pkg];
const maxHeight = `${parseInt(option.maxHeight) - 53}px`; // 动态计算最大高度
const packageWidth = packageData.width || ''; // 获取表情包的宽度
const maxHeight = `${parseInt(option.maxHeight) - 53}px`;
const packageWidth = packageData.width || '';

html += `
<ul class="OwO-items OwO-items-${packageData.type}" style="max-height: ${maxHeight};">`;
html += `<ul class="OwO-items OwO-items-${packageData.type}" style="max-height: ${maxHeight};">`;

packageData.container.forEach(item => {
const { text, input, icon } = item;
const isImage = packageData.type === 'image';
const imgWidth = packageWidth ? ` style="width: ${packageWidth};"` : '';
const inputValue = input || icon; // 使用 input 或 icon 作为表情插入值
const inputValue = input || icon;
html += `
<li class="OwO-item" title="${text}" data-input="${inputValue}">
${isImage ? `<img src="${icon}" alt="${text}" loading="lazy"${imgWidth}>` : icon}
Expand All @@ -81,12 +70,10 @@
html += `</ul>`;
});

// 拼接表情包选项卡和指示器
html += `
<div class="OwO-bar">
<ul class="OwO-packages">`;

// 遍历所有表情包,生成选项卡
this.packages.forEach(pkg => {
html += `<li><span>${pkg}</span></li>`;
});
Expand All @@ -97,91 +84,75 @@
</div>
</div>`;

// 将生成的 HTML 插入到容器中
this.container.innerHTML = html;

// 绑定Logo点击事件,用于展开/收起表情面板
this.logo = this.container.querySelector('.OwO-logo');
this.logo.addEventListener('click', () => this.toggle());

// 绑定表情点击事件,将表情插入到输入框
const body = this.container.querySelector('.OwO-body');
body.addEventListener('click', (e) => {
const target = e.target.closest('.OwO-item');
if (target) {
const cursorPos = this.area.selectionEnd; // 获取光标位置
const textToInsert = target.getAttribute('data-input'); // 获取表情数据
this.area.value = this.area.value.slice(0, cursorPos) + textToInsert + this.area.value.slice(cursorPos); // 插入表情
this.area.focus();
this.toggle(); // 收起面板
}
$(this.container).html(html);

this.logo = $(this.container).find('.OwO-logo');
this.logo.on('click', () => this.toggle());

$(this.container).find('.OwO-body').on('click', '.OwO-item', (e) => {
const target = $(e.target);
const cursorPos = this.area.selectionEnd;
const textToInsert = target.data('input');
this.area.value = this.area.value.slice(0, cursorPos) + textToInsert + this.area.value.slice(cursorPos);
this.area.focus();
this.toggle();
});

// 绑定表情包切换事件
this.packagesEle = this.container.querySelector('.OwO-packages');
this.packagesEle.addEventListener('click', (e) => {
const target = e.target.closest('li');
if (target) {
const index = Array.from(this.packagesEle.children).indexOf(target);
this.tab(index); // 切换到对应的表情包
}
this.packagesEle = $(this.container).find('.OwO-packages');
this.packagesEle.on('click', 'li', (e) => {
const index = $(e.target).closest('li').index();
this.tab(index);
});

this.tab(0); // 默认显示第一个表情包
this.tab(0);
}

// 切换表情面板的显示状态
toggle() {
this.container.classList.toggle('OwO-open');
$(this.container).toggleClass('OwO-open');
}

// 切换当前显示的表情包
tab(index) {
const itemsShow = this.container.querySelector('.OwO-items-show');
if (itemsShow) itemsShow.classList.remove('OwO-items-show'); // 移除已显示的表情包
this.container.querySelectorAll('.OwO-items')[index].classList.add('OwO-items-show'); // 显示对应的表情包

const packageActive = this.container.querySelector('.OwO-package-active');
if (packageActive) packageActive.classList.remove('OwO-package-active'); // 移除已激活的表情包选项
this.packagesEle.children[index].classList.add('OwO-package-active'); // 激活当前选中的表情包选项

const activeLink = this.packagesEle.children[index];
const indicator = this.container.querySelector('.OwO-indicator');
indicator.style.width = `${activeLink.offsetWidth}px`; // 设置指示器宽度
indicator.style.left = `${activeLink.offsetLeft}px`; // 设置指示器位置
$(this.container).find('.OwO-items-show').removeClass('OwO-items-show');
$(this.container).find('.OwO-items').eq(index).addClass('OwO-items-show');

$(this.container).find('.OwO-package-active').removeClass('OwO-package-active');
this.packagesEle.children().eq(index).addClass('OwO-package-active');

const activeLink = this.packagesEle.children().eq(index);
const indicator = $(this.container).find('.OwO-indicator');
indicator.css({
width: `${activeLink.outerWidth()}px`,
left: `${activeLink.position().left}px`
});
}
}

// 将 OwO 类暴露到全局或模块中
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
module.exports = OwO;
} else {
window.OwO = OwO;
}
})();

// 初始化评论区的表情面板
function initializeCommentsOwO() {
const container = document.getElementsByClassName('OwO')[0]; // 获取容器
const target = document.getElementsByClassName('OwO-textarea')[0]; // 获取输入框
const container = $('.OwO')[0];
const target = $('.OwO-textarea')[0];
if (container && target) {
const OwO_demo = new OwO({
logo: 'OωO表情', // Logo
container, // 容器
target, // 输入框
api: '/usr/themes/PureSuck/js/OwO.json', // 表情数据API
position: 'up', // 面板位置
width: '100%', // 宽度
maxHeight: '260px' // 最大高度
logo: 'OωO表情',
container,
target,
api: '/usr/themes/PureSuck/js/OwO.json',
position: 'up',
width: '100%',
maxHeight: '260px'
});

// 绑定按钮点击事件,打开/关闭表情面板
const owoButton = document.getElementById('owo-button');
if (owoButton) {
owoButton.addEventListener('click', () => OwO_demo.toggle());
const owoButton = $('#owo-button');
if (owoButton.length) {
owoButton.on('click', () => OwO_demo.toggle());
}
}
}

// 调用初始化函数
initializeCommentsOwO();

0 comments on commit 54e76c5

Please sign in to comment.