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.
527 lines
16 KiB
527 lines
16 KiB
<?php
|
|
/**
|
|
* About 页面导航区块
|
|
* 显示可自定义的导航菜单
|
|
*/
|
|
|
|
// 防止直接访问
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
// 获取短代码参数(如果通过短代码调用)
|
|
global $about_nav_shortcode_atts;
|
|
$shortcode_atts = (is_array($about_nav_shortcode_atts)) ? $about_nav_shortcode_atts : array();
|
|
|
|
// 配置类
|
|
if (!class_exists('AboutNavConfig')) {
|
|
class AboutNavConfig {
|
|
public $menu_id;
|
|
public $element_id;
|
|
public $css_class;
|
|
|
|
public function __construct($atts = array()) {
|
|
// 从短代码参数或自定义器获取设置
|
|
$this->menu_id = !empty($atts['menu_id']) ? $atts['menu_id'] : get_theme_mod('about_nav_menu_id', '');
|
|
$this->element_id = !empty($atts['id']) ? $atts['id'] : 'nenghui-about-nav';
|
|
$this->css_class = !empty($atts['class']) ? $atts['class'] : '';
|
|
}
|
|
|
|
public function get_menu_items() {
|
|
if (empty($this->menu_id)) {
|
|
return array();
|
|
}
|
|
|
|
// 验证菜单ID是否为有效的数字
|
|
$menu_id = intval($this->menu_id);
|
|
if ($menu_id <= 0) {
|
|
return array();
|
|
}
|
|
|
|
// 检查菜单是否存在
|
|
$menu = wp_get_nav_menu_object($menu_id);
|
|
if (!$menu || is_wp_error($menu)) {
|
|
return array();
|
|
}
|
|
|
|
// 获取菜单项
|
|
$menu_items = wp_get_nav_menu_items($menu_id);
|
|
|
|
if (!$menu_items || is_wp_error($menu_items) || !is_array($menu_items)) {
|
|
return array();
|
|
}
|
|
|
|
// 过滤掉无效的菜单项
|
|
$menu_items = array_filter($menu_items, function($item) {
|
|
return $item && !empty($item->title);
|
|
});
|
|
|
|
// 处理菜单项数据
|
|
$processed_items = array();
|
|
foreach ($menu_items as $item) {
|
|
$processed_items[] = array(
|
|
'id' => $item->ID,
|
|
'title' => $item->title,
|
|
'url' => $item->url,
|
|
'target' => $item->target,
|
|
'classes' => implode(' ', $item->classes),
|
|
'is_current' => $this->is_current_page($item->url)
|
|
);
|
|
}
|
|
|
|
return $processed_items;
|
|
}
|
|
|
|
private function is_current_page($url) {
|
|
// 安全地获取当前URL
|
|
$request_uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
|
|
if (empty($request_uri)) {
|
|
return false;
|
|
}
|
|
|
|
$current_url = home_url($request_uri);
|
|
$parsed_url = parse_url($url);
|
|
$parsed_current = parse_url($current_url);
|
|
|
|
// 确保解析结果是数组
|
|
if (!is_array($parsed_url) || !is_array($parsed_current)) {
|
|
return false;
|
|
}
|
|
|
|
// 比较路径
|
|
if (isset($parsed_url['path']) && isset($parsed_current['path'])) {
|
|
return rtrim($parsed_url['path'], '/') === rtrim($parsed_current['path'], '/');
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 初始化配置
|
|
$config = new AboutNavConfig($shortcode_atts);
|
|
$menu_items = $config->get_menu_items();
|
|
|
|
// 获取自定义器设置
|
|
$nav_bg_color = get_theme_mod('about_nav_bg_color', '#ffffff');
|
|
$nav_text_color = get_theme_mod('about_nav_text_color', '#333333');
|
|
$nav_active_color = get_theme_mod('about_nav_active_color', '#007cba');
|
|
$nav_style = get_theme_mod('about_nav_style', 'horizontal');
|
|
$nav_position = get_theme_mod('about_nav_position', 'top');
|
|
|
|
// 如果没有菜单项,显示提示信息
|
|
if (!is_array($menu_items) || empty($menu_items)) {
|
|
$debug_info = '';
|
|
if (defined('WP_DEBUG') && WP_DEBUG) {
|
|
// 获取所有可用菜单进行调试
|
|
$all_menus = wp_get_nav_menus();
|
|
$available_menus = array();
|
|
if (is_array($all_menus)) {
|
|
foreach ($all_menus as $menu) {
|
|
$available_menus[] = $menu->term_id . ':' . $menu->name;
|
|
}
|
|
}
|
|
$debug_info = '<br><small>调试信息: 当前菜单ID = ' . esc_html($config->menu_id) .
|
|
'<br>可用菜单: ' . esc_html(implode(', ', $available_menus)) . '</small>';
|
|
}
|
|
echo '<div class="about-nav-notice">请在自定义器中设置 About 导航菜单' . $debug_info . '</div>';
|
|
return;
|
|
}
|
|
?>
|
|
|
|
<nav id="<?php echo esc_attr($config->element_id); ?>"
|
|
class="about-nav-section nenghui-about-nav nav-<?php echo esc_attr($nav_style); ?> nav-position-<?php echo esc_attr($nav_position); ?> <?php echo esc_attr($config->css_class); ?>"
|
|
style="background-color: <?php echo esc_attr($nav_bg_color); ?>"
|
|
data-aos="fade-up">
|
|
<div class="about-nav-container" data-aos="fade-up" data-aos-delay="200">
|
|
<ul class="about-nav-menu" data-aos="fade-up" data-aos-delay="400">
|
|
<?php foreach ($menu_items as $item): ?>
|
|
<li class="about-nav-item <?php echo $item['is_current'] ? 'active' : ''; ?>">
|
|
<a href="<?php echo esc_url($item['url']); ?>"
|
|
class="about-nav-link <?php echo esc_attr($item['classes']); ?>"
|
|
style="color: <?php echo esc_attr($nav_text_color); ?>"
|
|
<?php echo !empty($item['target']) ? 'target="' . esc_attr($item['target']) . '"' : ''; ?>>
|
|
<?php echo esc_html($item['title']); ?>
|
|
</a>
|
|
</li>
|
|
<?php endforeach; ?>
|
|
</ul>
|
|
</div>
|
|
</nav>
|
|
|
|
<style>
|
|
/* About 导航区块样式 */
|
|
.nenghui-about-nav {
|
|
width: 100%;
|
|
border-bottom: 1px solid #eee;
|
|
position: relative;
|
|
z-index: 100;
|
|
}
|
|
|
|
.about-nav-container {
|
|
width: 80%;
|
|
max-width: 1200px;
|
|
margin: 0 auto;
|
|
padding: 0;
|
|
}
|
|
|
|
.about-nav-menu {
|
|
list-style: none;
|
|
margin: 0;
|
|
padding: 0;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.about-nav-item {
|
|
margin: 0;
|
|
padding: 0;
|
|
position: relative;
|
|
}
|
|
|
|
.about-nav-link {
|
|
display: block;
|
|
padding: 20px 30px;
|
|
text-decoration: none;
|
|
font-size: 16px;
|
|
font-weight: 500;
|
|
transition: all 0.3s ease;
|
|
border-bottom: 3px solid transparent;
|
|
position: relative;
|
|
}
|
|
|
|
.about-nav-link:hover {
|
|
color: <?php echo esc_attr($nav_active_color); ?> !important;
|
|
text-decoration: none;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.about-nav-item.active .about-nav-link {
|
|
color: <?php echo esc_attr($nav_active_color); ?> !important;
|
|
border-bottom-color: <?php echo esc_attr($nav_active_color); ?> !important;
|
|
}
|
|
|
|
/* 垂直样式 */
|
|
.nenghui-about-nav.nav-vertical .about-nav-menu {
|
|
flex-direction: column;
|
|
align-items: stretch;
|
|
}
|
|
|
|
.nenghui-about-nav.nav-vertical .about-nav-item {
|
|
width: 100%;
|
|
border-bottom: 1px solid #f0f0f0;
|
|
}
|
|
|
|
.nenghui-about-nav.nav-vertical .about-nav-item:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.nenghui-about-nav.nav-vertical .about-nav-link {
|
|
border-bottom: none;
|
|
border-left: 3px solid transparent;
|
|
}
|
|
|
|
.nenghui-about-nav.nav-vertical .about-nav-item.active .about-nav-link {
|
|
border-left-color: <?php echo esc_attr($nav_active_color); ?> !important;
|
|
border-bottom-color: transparent !important;
|
|
background: rgba(0, 124, 186, 0.05);
|
|
}
|
|
|
|
/* 下拉菜单样式 */
|
|
.nenghui-about-nav.nav-dropdown {
|
|
position: relative;
|
|
}
|
|
|
|
.nenghui-about-nav.nav-dropdown .about-nav-menu {
|
|
position: relative;
|
|
}
|
|
|
|
.nenghui-about-nav.nav-dropdown .about-nav-item:hover .about-nav-submenu {
|
|
display: block;
|
|
}
|
|
|
|
/* 位置样式 */
|
|
.nenghui-about-nav.nav-position-top {
|
|
position: sticky;
|
|
top: 0;
|
|
}
|
|
|
|
.nenghui-about-nav.nav-position-sidebar {
|
|
position: fixed;
|
|
left: 0;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
width: auto;
|
|
border-bottom: none;
|
|
border-right: 1px solid #eee;
|
|
box-shadow: 2px 0 5px rgba(0,0,0,0.1);
|
|
}
|
|
|
|
.nenghui-about-nav.nav-position-sidebar .about-nav-container {
|
|
width: auto;
|
|
}
|
|
|
|
.nenghui-about-nav.nav-position-sidebar .about-nav-menu {
|
|
flex-direction: column;
|
|
}
|
|
|
|
.nenghui-about-nav.nav-position-bottom {
|
|
position: fixed;
|
|
bottom: 0;
|
|
left: 0;
|
|
right: 0;
|
|
border-top: 1px solid #eee;
|
|
border-bottom: none;
|
|
box-shadow: 0 -2px 5px rgba(0,0,0,0.1);
|
|
}
|
|
|
|
/* 响应式设计 */
|
|
@media (max-width: 768px) {
|
|
.about-nav-container {
|
|
width: 95%;
|
|
}
|
|
|
|
.about-nav-menu {
|
|
flex-direction: column;
|
|
align-items: stretch;
|
|
}
|
|
|
|
.about-nav-item {
|
|
width: 100%;
|
|
border-bottom: 1px solid #f0f0f0;
|
|
}
|
|
|
|
.about-nav-item:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.about-nav-link {
|
|
padding: 15px 20px;
|
|
border-bottom: none;
|
|
border-left: 3px solid transparent;
|
|
}
|
|
|
|
.about-nav-item.active .about-nav-link {
|
|
border-left-color: #007cba;
|
|
border-bottom-color: transparent;
|
|
background: #f8f9fa;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 480px) {
|
|
.about-nav-link {
|
|
padding: 12px 15px;
|
|
font-size: 14px;
|
|
}
|
|
}
|
|
|
|
/* 提示信息样式 */
|
|
.about-nav-notice {
|
|
padding: 20px;
|
|
text-align: center;
|
|
color: #666;
|
|
background: #f9f9f9;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
margin: 20px 0;
|
|
}
|
|
|
|
/* 加载动画 */
|
|
.nenghui-about-nav {
|
|
opacity: 0;
|
|
animation: fadeInNav 0.5s ease forwards;
|
|
}
|
|
|
|
@keyframes fadeInNav {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(-10px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
/* 高对比度模式支持 */
|
|
@media (prefers-contrast: high) {
|
|
.about-nav-link {
|
|
border-bottom-width: 2px;
|
|
}
|
|
|
|
.about-nav-item.active .about-nav-link {
|
|
border-bottom-width: 4px;
|
|
}
|
|
}
|
|
|
|
/* 减少动画模式支持 */
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.about-nav-link {
|
|
transition: none;
|
|
}
|
|
|
|
.nenghui-about-nav {
|
|
animation: none;
|
|
opacity: 1;
|
|
}
|
|
}
|
|
</style>
|
|
|
|
<script>
|
|
// About 导航功能脚本
|
|
(function() {
|
|
'use strict';
|
|
|
|
// 等待 DOM 加载完成
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const aboutNav = document.querySelector('.nenghui-about-nav');
|
|
if (!aboutNav) return;
|
|
|
|
// 平滑滚动到锚点
|
|
const navLinks = aboutNav.querySelectorAll('.about-nav-link');
|
|
navLinks.forEach(function(link) {
|
|
link.addEventListener('click', function(e) {
|
|
const href = this.getAttribute('href');
|
|
|
|
// 如果是锚点链接,添加平滑滚动
|
|
if (href && href.startsWith('#')) {
|
|
e.preventDefault();
|
|
const target = document.querySelector(href);
|
|
if (target) {
|
|
const offsetTop = target.offsetTop - aboutNav.offsetHeight - 20;
|
|
window.scrollTo({
|
|
top: offsetTop,
|
|
behavior: 'smooth'
|
|
});
|
|
|
|
// 更新活动状态
|
|
updateActiveState(this);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
// 更新活动状态
|
|
function updateActiveState(activeLink) {
|
|
navLinks.forEach(function(link) {
|
|
link.parentElement.classList.remove('active');
|
|
});
|
|
activeLink.parentElement.classList.add('active');
|
|
}
|
|
|
|
// 滚动时更新活动状态(针对锚点导航)
|
|
let ticking = false;
|
|
function updateActiveOnScroll() {
|
|
if (!ticking) {
|
|
requestAnimationFrame(function() {
|
|
const scrollTop = window.pageYOffset;
|
|
const navHeight = aboutNav.offsetHeight;
|
|
|
|
navLinks.forEach(function(link) {
|
|
const href = link.getAttribute('href');
|
|
if (href && href.startsWith('#')) {
|
|
const target = document.querySelector(href);
|
|
if (target) {
|
|
const targetTop = target.offsetTop - navHeight - 50;
|
|
const targetBottom = targetTop + target.offsetHeight;
|
|
|
|
if (scrollTop >= targetTop && scrollTop < targetBottom) {
|
|
updateActiveState(link);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
ticking = false;
|
|
});
|
|
ticking = true;
|
|
}
|
|
}
|
|
|
|
// 监听滚动事件
|
|
window.addEventListener('scroll', updateActiveOnScroll, { passive: true });
|
|
|
|
// 键盘导航支持
|
|
aboutNav.addEventListener('keydown', function(e) {
|
|
const focusedElement = document.activeElement;
|
|
const navItems = Array.from(aboutNav.querySelectorAll('.about-nav-link'));
|
|
const currentIndex = navItems.indexOf(focusedElement);
|
|
|
|
switch(e.key) {
|
|
case 'ArrowLeft':
|
|
case 'ArrowUp':
|
|
e.preventDefault();
|
|
const prevIndex = currentIndex > 0 ? currentIndex - 1 : navItems.length - 1;
|
|
navItems[prevIndex].focus();
|
|
break;
|
|
|
|
case 'ArrowRight':
|
|
case 'ArrowDown':
|
|
e.preventDefault();
|
|
const nextIndex = currentIndex < navItems.length - 1 ? currentIndex + 1 : 0;
|
|
navItems[nextIndex].focus();
|
|
break;
|
|
|
|
case 'Home':
|
|
e.preventDefault();
|
|
navItems[0].focus();
|
|
break;
|
|
|
|
case 'End':
|
|
e.preventDefault();
|
|
navItems[navItems.length - 1].focus();
|
|
break;
|
|
}
|
|
});
|
|
|
|
// 自定义器实时预览支持
|
|
if (typeof wp !== 'undefined' && wp.customize) {
|
|
// 监听背景色变化
|
|
wp.customize('about_nav_bg_color', function(value) {
|
|
value.bind(function(newval) {
|
|
aboutNav.style.backgroundColor = newval;
|
|
});
|
|
});
|
|
|
|
// 监听文字颜色变化
|
|
wp.customize('about_nav_text_color', function(value) {
|
|
value.bind(function(newval) {
|
|
navLinks.forEach(function(link) {
|
|
link.style.color = newval;
|
|
});
|
|
});
|
|
});
|
|
|
|
// 监听激活状态颜色变化
|
|
wp.customize('about_nav_active_color', function(value) {
|
|
value.bind(function(newval) {
|
|
// 更新 CSS 变量或直接更新样式
|
|
const activeLinks = aboutNav.querySelectorAll('.about-nav-item.active .about-nav-link');
|
|
activeLinks.forEach(function(link) {
|
|
link.style.color = newval;
|
|
link.style.borderBottomColor = newval;
|
|
});
|
|
});
|
|
});
|
|
|
|
// 监听样式变化
|
|
wp.customize('about_nav_style', function(value) {
|
|
value.bind(function(newval) {
|
|
aboutNav.className = aboutNav.className.replace(/nav-\w+/g, '');
|
|
aboutNav.classList.add('nav-' + newval);
|
|
});
|
|
});
|
|
|
|
// 监听位置变化
|
|
wp.customize('about_nav_position', function(value) {
|
|
value.bind(function(newval) {
|
|
aboutNav.className = aboutNav.className.replace(/nav-position-\w+/g, '');
|
|
aboutNav.classList.add('nav-position-' + newval);
|
|
});
|
|
});
|
|
}
|
|
});
|
|
})();
|
|
</script>
|