/*
主站,子频道,定向站点共用
*/
(function() { scrollToAnchor(); toggleSearchForm(); scrollTop(); initScrollBar(); // 文档图片放大查看
imgZoom(); renderCodeBox(); dropdownClick(); fixAside(); // 侧边栏固定
function fixAside() {
if (SITE_SLUG === 'open') {
var headerHeight = $('.header').outerHeight() + $('.search-wrapper').outerHeight() + 32;
var offsetTop = $('.dropdown-menu-selector').height() || 0;
affixSidebar(headerHeight, offsetTop);
affix($('.breadcrumb'), headerHeight, 0);
} else {
var headerHeight = $('.header').outerHeight();
var offsetTop = 86;
affixSidebar(headerHeight, offsetTop);
}
} // 页面加载时的锚点定位
function initScrollBar() {
$(window).on('load', function() {
var hash = decodeURIComponent(window.location.hash);
if (!hash) return; // 兼容 toc 旧版本中的链接错误
if (hash.substr(0, 2) === '##') {
hash = hash.substr(1);
} if (hash !== '#' && $(hash).length) {
var top = $(hash).offset().top - $('.breadcrumb').outerHeight(); // 子站点需要计算头部高度
if (SITE_SLUG !== 'open') {
top -= $('.page-title').outerHeight();
}
setTimeout(function() {
$(window).scrollTop(top);
}, 0);
}
});
} function affix($el, headerHeight, offsetTop) {
$(window).on('load scroll resize', function () {
if (!$el.length) return; var scrollTop = window.scrollY || window.pageYOffset;
if (scrollTop > headerHeight) {
$el.css({
position: 'fixed',
top: offsetTop,
left: $el.offset().left,
right: $('body').width() - $el.offset().left - $el.width(),
})
} else {
$el.removeAttr('style')
}
});
} function affixSidebar(headerHeight, offsetTop) {
var footerHeight = $('.body-footer').outerHeight();
var $sidebar = $('.sidebar-wrapper');
var $breadcrumb = $('.breadcrumb'); $(window).on('load scroll resize', function () {
var scrollTop = window.scrollY || window.pageYOffset; // sidebar fixed 时跟底部保持的距离
var offsetBottom = document.body.scrollHeight - scrollTop - window.innerHeight - 32; var bottom = 0;
if (offsetBottom < footerHeight) {
bottom = footerHeight - offsetBottom;
} $sidebar.find('.sidebar').css({
'height': window.innerHeight - bottom - offsetTop,
}); // sidebar fixed
if (scrollTop > headerHeight) {
$sidebar.addClass('fixed');
} else {
$sidebar.removeClass('fixed');
}
});
} function dropdownClick() {
// dropdown trigger: click
$('body').on('click', '.dropdown .dropdown-trigger', function() {
var $dropdown = $(this).parent('.dropdown');
$dropdown.toggleClass('open'); if ($dropdown.hasClass('open') && $dropdown.hasClass('dropdown-menu-selector')) {
var $menu = $('#main-menu');
var $active = $menu.find('.menu-item .active');
if ($active.length) {
var top = $menu.scrollTop() + $active.position().top - 56;
if (top > 0) {
$menu.scrollTop(top);
}
}
}
});
$('html').on('click', function() {
$('.dropdown.open').removeClass('open');
});
$('html').on('click', '.dropdown', function(e) {
e.stopPropagation();
});
} function renderCodeBox() {
// copy code
var $codeBox = $('<div class="code-box" />');
var codeTemplate = '<span class="btn-copy-code">点击复制</span>';
$('code.language-js, code.language-javascript, code.language-jsx').each(function(index, item) {
$(item).parent('pre').wrap($codeBox).before(codeTemplate);
}) var clipboard = new Clipboard('.btn-copy-code', {
text: function(trigger) {
return trigger.nextElementSibling.textContent;
}
}); var clipboardTimer = null;
clipboard.on('success', (e) => {
$(e.trigger).text('复制成功!');
if (clipboardTimer) {
clearTimeout(clipboardTimer);
}
clipboardTimer = setTimeout(() => {
$(e.trigger).text('点击复制');
}, 1500);
});
} function imgZoom() {
var zoomDefaults = {
styles: {
zoomImage: {
cursor : 'zoom-out',
position : 'absolute',
transition : 'transform 300ms',
transform : 'translate3d(0, 0, 0) scale(1)',
transformOrigin : 'center center',
willChange : 'transform, top, left'
},
zoomContainer: {
position : 'fixed',
top : 0,
right : 0,
bottom : 0,
left : 0,
zIndex : 1024,
},
overlay: {
position : 'absolute',
top : 0,
right : 0,
bottom : 0,
left : 0,
backgroundColor : '#FFF',
opacity : 0,
transition : 'opacity 300ms',
},
btn: {
position : 'absolute',
bottom : 12,
right : 12,
padding : '4px 10px',
border : '1px solid #e9e9e9',
borderRadius : 2,
fontSize : 12,
color : '#999',
},
btnHover: {
color : '#666',
},
},
};
var zoomOriginImage = null;
var zoomTimer = null;
// zoom in
$('.markdown').on('click', 'img', function() {
zoomOriginImage = $(this).get(0); var $wrap = $('<div />');
$wrap.css(zoomDefaults.styles.zoomContainer); var $overlay = $('<div class="overlay" />');
$overlay.css(zoomDefaults.styles.overlay); var $img = $(this).clone();
$img.css(getImageStyle(zoomOriginImage, false)); var $btn = $('<a target="_blank" />');
$btn.attr('href', $img.attr('src')).text('查看原图');
$btn.css(zoomDefaults.styles.btn); $btn.hover(function() {
$(this).css(zoomDefaults.styles.btnHover);
}, function() {
$(this).css(zoomDefaults.styles.btn);
}); $wrap.append($overlay).append($img).append($btn);
$('#zoom-img').append($wrap); // transition
$overlay.css({
opacity: 1,
});
$img.css(getImageStyle($img.get(0), true));
}); // zoom out
$('#zoom-img').on('click', function() {
var $zoom = $(this);
$zoom.find('img').css(getImageStyle(zoomOriginImage, false));
$zoom.find('.overlay').css({
opacity: 0
}); if (zoomTimer) {
clearTimeout(zoomTimer);
}
zoomTimer = setTimeout(function() {
$zoom.html('');
zoomOriginImage = null;
}, 150);
}); $(window).on('scroll', function() {
$('#zoom-img').html('');
zoomOriginImage = null;
}); $(window).on('resize', function() {
if ($('#zoom-img img').length) {
$('#zoom-img img').css(getImageStyle(zoomOriginImage, true));
}
}); function getImageStyle(image, isZoom) {
var imageOffset = image.getBoundingClientRect();
var top = imageOffset.top;
var left = imageOffset.left;
var width = image.width;
var height = image.height; var style = {
top: top,
left: left,
width: width,
height: height
}; if (!isZoom) {
return Object.assign({}, zoomDefaults.styles.zoomImage, style);
} // Get the the coords for center of the viewport
var viewportX = window.innerWidth / 2;
var viewportY = window.innerHeight / 2; // Get the coords for center of the original image
var imageCenterX = imageOffset.left + image.width / 2;
var imageCenterY = imageOffset.top + image.height / 2; // Get offset amounts for image coords to be centered on screen
var translateX = viewportX - imageCenterX;
var translateY = viewportY - imageCenterY; // Figure out how much to scale the image so it doesn't overflow the screen
var scale = getScale(width, height); var zoomStyle = {
transform: 'translate3d(' + translateX + 'px, ' + translateY + 'px, 0) scale(' + scale + ')',
} return Object.assign({}, zoomDefaults.styles.zoomImage, style, zoomStyle);
} function getScale(width, height) {
var totalMargin = 40;
var scaleX = window.innerWidth / (width + totalMargin);
var scaleY = window.innerHeight / (height + totalMargin);
return Math.min(scaleX, scaleY);
}
} function scrollTop() {
// scroll top
$(window).on('load scroll', function() {
if ($(window).scrollTop() > 400) {
$('#scroll-top').addClass('visible');
} else {
$('#scroll-top').removeClass('visible');
}
})
$('#scroll-top').on('click', function(e) {
e.preventDefault();
$('html, body').animate({
scrollTop: 0
}, 150);
})
} function scrollToAnchor(offsetTop) {
// anchor click scroll to element
var breadcrumbHeight = $('.breadcrumb').outerHeight();
var offsetTop = 0;
if (SITE_SLUG === 'open') {
offsetTop = breadcrumbHeight;
} else {
offsetTop = $('.page-title').outerHeight() + breadcrumbHeight;
} // 锚点处理
$('.markdown').on('click', 'a', function(e) {
var href = $(this).attr('href');
if (/^#/.test(href)) {
e.preventDefault();
if ($(href).length) {
var top = $(href).offset().top - offsetTop;
$('html, body').scrollTop(top);
}
}
});
} function toggleSearchForm() {
// header search
$('.header').on('click', '.btn-search', function(e) {
e.preventDefault();
$('.header .user-menu').addClass('search-open');
$('.header .search-form input').focus();
})
$('html').on('click', function(e) {
$('.header .user-menu.search-open').removeClass('search-open');
})
$('html').on('click', '.header .search-form', function(e) {
e.stopPropagation();
})
}
}());