You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

347 lines
10 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/**
* 业务流程设计区块交互脚本
* Business Process Block Interactive Script
*/
(function($) {
'use strict';
/**
* 业务流程Tab切换类
*/
class BusinessProcessTabs {
constructor(container) {
this.container = $(container);
this.tabs = this.container.find('.process-tab');
this.images = this.container.find('.process-image');
this.currentIndex = 0;
this.isAnimating = false;
this.init();
}
/**
* 初始化
*/
init() {
this.bindEvents();
this.setupIntersectionObserver();
this.preloadImages();
// 设置初始状态
this.setActiveTab(0, false);
}
/**
* 绑定事件
*/
bindEvents() {
// Tab点击事件
this.tabs.on('click', (e) => {
e.preventDefault();
const index = this.tabs.index($(e.currentTarget));
this.switchTab(index);
});
// 键盘导航支持
this.tabs.on('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
const index = this.tabs.index($(e.currentTarget));
this.switchTab(index);
}
});
// 触摸滑动支持(移动端)
if ('ontouchstart' in window) {
this.setupTouchEvents();
}
// 窗口大小改变时重新计算
$(window).on('resize', this.debounce(() => {
this.handleResize();
}, 250));
}
/**
* 设置触摸事件(移动端滑动支持)
*/
setupTouchEvents() {
let startX = 0;
let startY = 0;
let isScrolling = false;
this.container.on('touchstart', (e) => {
const touch = e.originalEvent.touches[0];
startX = touch.clientX;
startY = touch.clientY;
isScrolling = false;
});
this.container.on('touchmove', (e) => {
if (isScrolling) return;
const touch = e.originalEvent.touches[0];
const deltaX = touch.clientX - startX;
const deltaY = touch.clientY - startY;
// 判断是否为水平滑动
if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > 30) {
isScrolling = true;
e.preventDefault();
if (deltaX > 0 && this.currentIndex > 0) {
// 向右滑动切换到上一个tab
this.switchTab(this.currentIndex - 1);
} else if (deltaX < 0 && this.currentIndex < this.tabs.length - 1) {
// 向左滑动切换到下一个tab
this.switchTab(this.currentIndex + 1);
}
}
});
}
/**
* 切换Tab
*/
switchTab(index) {
if (index === this.currentIndex || this.isAnimating || index < 0 || index >= this.tabs.length) {
return;
}
this.setActiveTab(index, true);
}
/**
* 设置活动Tab
*/
setActiveTab(index, animate = true) {
if (this.isAnimating && animate) return;
this.isAnimating = animate;
this.currentIndex = index;
// 更新Tab状态
this.tabs.removeClass('active').eq(index).addClass('active');
// 更新图片显示
if (animate) {
this.animateImageTransition(index);
} else {
this.images.removeClass('active').eq(index).addClass('active');
this.isAnimating = false;
}
// 更新ARIA属性
this.updateAccessibility(index);
// 触发自定义事件
this.container.trigger('tabChanged', [index, this.tabs.eq(index)]);
}
/**
* 图片切换动画
*/
animateImageTransition(index) {
const currentImage = this.images.filter('.active');
const nextImage = this.images.eq(index);
// 如果没有当前活动图片,直接显示新图片
if (currentImage.length === 0) {
nextImage.addClass('active');
this.isAnimating = false;
return;
}
// 淡出当前图片
currentImage.animate({ opacity: 0 }, 250, () => {
currentImage.removeClass('active');
// 淡入新图片
nextImage.addClass('active').css('opacity', 0).animate({ opacity: 1 }, 250, () => {
this.isAnimating = false;
});
});
}
/**
* 更新无障碍访问属性
*/
updateAccessibility(index) {
this.tabs.each((i, tab) => {
const $tab = $(tab);
$tab.attr('aria-selected', i === index ? 'true' : 'false');
$tab.attr('tabindex', i === index ? '0' : '-1');
});
this.images.each((i, image) => {
const $image = $(image);
$image.attr('aria-hidden', i === index ? 'false' : 'true');
});
}
/**
* 预加载图片
*/
preloadImages() {
this.images.each((index, element) => {
const $img = $(element).find('img');
if ($img.length && $img.attr('data-src')) {
const img = new Image();
img.onload = () => {
$img.attr('src', $img.attr('data-src')).removeAttr('data-src');
};
img.src = $img.attr('data-src');
}
});
}
/**
* 设置交叉观察器(用于动画触发)
*/
setupIntersectionObserver() {
if (!window.IntersectionObserver) return;
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
this.container.addClass('animate-in');
observer.unobserve(entry.target);
}
});
}, {
threshold: 0.2,
rootMargin: '0px 0px -50px 0px'
});
observer.observe(this.container[0]);
}
/**
* 处理窗口大小改变
*/
handleResize() {
// 重新计算布局相关的尺寸
this.container.removeClass('animate-in');
// 延迟重新添加动画类
setTimeout(() => {
this.container.addClass('animate-in');
}, 100);
}
/**
* 防抖函数
*/
debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
/**
* 自动播放功能
*/
startAutoPlay(interval = 5000) {
this.stopAutoPlay();
this.autoPlayTimer = setInterval(() => {
const nextIndex = (this.currentIndex + 1) % this.tabs.length;
this.switchTab(nextIndex);
}, interval);
}
/**
* 停止自动播放
*/
stopAutoPlay() {
if (this.autoPlayTimer) {
clearInterval(this.autoPlayTimer);
this.autoPlayTimer = null;
}
}
/**
* 销毁实例
*/
destroy() {
this.stopAutoPlay();
this.tabs.off('click keydown');
this.container.off('touchstart touchmove');
$(window).off('resize');
this.container.removeClass('animate-in');
}
}
/**
* 初始化所有业务流程区块
*/
function initBusinessProcessBlocks() {
$('.business-process-block').each(function() {
const $block = $(this);
// 避免重复初始化
if ($block.data('business-process-initialized')) {
return;
}
const instance = new BusinessProcessTabs(this);
$block.data('business-process-instance', instance);
$block.data('business-process-initialized', true);
// 如果设置了自动播放,启动自动播放
const autoPlay = $block.data('auto-play');
const autoPlayInterval = $block.data('auto-play-interval') || 5000;
if (autoPlay) {
instance.startAutoPlay(autoPlayInterval);
// 鼠标悬停时暂停自动播放
$block.on('mouseenter', () => instance.stopAutoPlay());
$block.on('mouseleave', () => instance.startAutoPlay(autoPlayInterval));
}
});
}
/**
* 页面加载完成后初始化
*/
$(document).ready(function() {
initBusinessProcessBlocks();
});
/**
* 支持动态加载的内容
*/
$(document).on('DOMNodeInserted', function(e) {
const $target = $(e.target);
if ($target.hasClass('business-process-block') || $target.find('.business-process-block').length) {
setTimeout(initBusinessProcessBlocks, 100);
}
});
/**
* 自定义器预览支持
*/
if (typeof wp !== 'undefined' && wp.customize) {
wp.customize.bind('ready', function() {
// 当自定义器设置改变时重新初始化
wp.customize.bind('change', function() {
setTimeout(initBusinessProcessBlocks, 500);
});
});
}
/**
* 导出到全局作用域(用于外部调用)
*/
window.BusinessProcessTabs = BusinessProcessTabs;
window.initBusinessProcessBlocks = initBusinessProcessBlocks;
})(jQuery);