Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 

389 строки
11 KiB

  1. import $ from 'jquery';
  2. require('jquery.easing');
  3. import {StudioPreviewUtil} from '../../_global/scripts/utils/StudioPreviewUtil';
  4. class IHKHeader {
  5. constructor(header) {
  6. this.header = header.addClass('initiated');
  7. this.window = $(window);
  8. this.body = $('body');
  9. this.overlayOpen = false;
  10. this.showOpenedNav = this.header.find('.primary').data("show-opened-menu");
  11. const t = this;
  12. this.initLogo();
  13. this.initTopLink();
  14. this.initScroll();
  15. this.initSearch();
  16. this.initPrimaryNav();
  17. this.initSecondaryNav();
  18. this.initToggling();
  19. this.initLanguage();
  20. if(this.showOpenedNav){
  21. t.header.find('.toggle-nav').click();
  22. }
  23. this.body.on('open-navigation', function (event, data) {
  24. if (data.openMenu) {
  25. t.header.find('.toggle-nav').click();
  26. }
  27. t.initPrimaryNav(data.rootUrl);
  28. });
  29. }
  30. initLogo() {
  31. const t = this;
  32. const logo = t.header.find('.logo');
  33. const img = logo.find('img');
  34. const overlay = $('<span class="logo-overlay" />').appendTo(logo);
  35. const logoObserver = new ResizeObserver(() => {
  36. if (img.height() < 44) {
  37. overlay.css('left', img.height() * 2.1);
  38. } else {
  39. overlay.removeAttr('style');
  40. }
  41. })
  42. logoObserver.observe(img.get(0));
  43. };
  44. initTopLink() {
  45. const t = this;
  46. const toplink = $('<a href="#" class="toplink" tabindex="-1" />').text('Top').prependTo(t.header);
  47. toplink.on('click', function (e) {
  48. e.preventDefault();
  49. $('html, body').animate({'scrollTop': 0}, Math.round($(window).scrollTop() / 12 + 300), 'easeOutQuad');
  50. })
  51. }
  52. initSearch() {
  53. const t = this;
  54. const formNav = $('<div class="form-nav" />').appendTo(t.header.find('.search form'));
  55. t.header.find('nav .secondary').clone().appendTo(formNav);
  56. t.header.find('nav .meta').clone().appendTo(formNav);
  57. t.header.find('.open-search, .close-search').on('click', function (e) {
  58. t.header.toggleClass('search-open').removeClass('nav-open');
  59. if (t.header.hasClass('search-open')) {
  60. setTimeout(function () {
  61. t.header.find('.search-field').focus();
  62. }, 200)
  63. }
  64. t.toggleContentScroll();
  65. })
  66. };
  67. initScroll() {
  68. const t = this;
  69. window.addEventListener("scroll", function () {
  70. window.requestAnimationFrame(function () {
  71. t.checkScroll();
  72. })
  73. }, {passive: true});
  74. };
  75. checkScroll() {
  76. const t = this;
  77. const st = this.window.scrollTop();
  78. if (t.overlayOpen || $('.gallery-popup.open').length) {
  79. return false;
  80. }
  81. if (st > 59) {
  82. this.header.addClass('scrolled');
  83. this.body.addClass('header-scrolled');
  84. } else {
  85. this.header.removeClass('scrolled');
  86. this.body.removeClass('header-scrolled');
  87. }
  88. if (st > this.window.height() * 1.2) {
  89. this.header.addClass('show-toplink');
  90. }
  91. else {
  92. this.header.removeClass('show-toplink');
  93. }
  94. }
  95. initToggling() {
  96. this.header.find('.overlay-holder').on('click touch', this.toggleNavigation.bind(this));
  97. this.header.find('.toggle-nav').on('click touch', this.toggleNavigation.bind(this));
  98. };
  99. toggleNavigation() {
  100. const t = this;
  101. if (StudioPreviewUtil && StudioPreviewUtil.isStudioPreview()) {
  102. $("html").stop().animate({'scrollTop': 0}, 300, 'swing', function () {
  103. t.header.toggleClass('nav-open');
  104. t.toggleContentScroll();
  105. });
  106. } else {
  107. t.header.toggleClass('nav-open');
  108. t.toggleContentScroll();
  109. }
  110. };
  111. initPrimaryNav(optionalRootUrl) {
  112. const t = this;
  113. const primary = t.header.find('.primary');
  114. $(primary).empty();
  115. t.baseUrl = primary.attr('data-base-url');
  116. t.rootUrl = primary.attr('data-root-url');
  117. if (optionalRootUrl) {
  118. t.rootUrl = optionalRootUrl;
  119. primary.off('click', 'a');
  120. }
  121. primary.append($('<ul class="current" />').attr('data-json', t.baseUrl + t.rootUrl));
  122. primary.on('click', 'a', function (e) {
  123. const a = $(this);
  124. const li = a.parent();
  125. const ul = li.parent('ul');
  126. if (li.hasClass('deep')) {
  127. e.preventDefault();
  128. if (a.siblings('ul').length) {
  129. ul.removeClass('current');
  130. t.toTop(ul);
  131. a.siblings('ul').addClass('current');
  132. li.addClass('open');
  133. t.manageTabIndex();
  134. } else {
  135. const deepUl = $('<ul />').attr('data-json', a.attr('href')).appendTo(li);
  136. t.loadNav(deepUl);
  137. }
  138. } else if (li.hasClass('back')) {
  139. e.preventDefault();
  140. t.toTop(ul);
  141. if (ul.closest('li').length) {
  142. ul.removeClass('current')
  143. .closest('li').removeClass('open')
  144. .parent('ul').addClass('current');
  145. t.manageTabIndex();
  146. } else {
  147. const backUl = $('<ul />').attr('data-json', a.attr('href')).insertBefore(ul);
  148. t.loadNav(backUl);
  149. }
  150. }
  151. });
  152. t.loadNav(t.header.find('.primary ul'));
  153. }
  154. initSecondaryNav() {
  155. // secondary-nav-item
  156. const t = this;
  157. const $secondary = t.header.find("nav").find(".secondary");
  158. const $secondaryItems = $secondary.find(".secondary-nav-item");
  159. $.each($secondaryItems, function (index,element) {
  160. $(element).on("click", function (e) {
  161. if($(element).data("is-channel")){
  162. e.preventDefault();
  163. const elementRootUrl= $(this).data("root-url");
  164. t.initPrimaryNav(elementRootUrl);
  165. } else {
  166. return true;
  167. }
  168. });
  169. });
  170. }
  171. loadNav(ul) {
  172. const t = this;
  173. const currentPageId = t.header.find('.primary').data("page-content-id");
  174. if (ul.parent('li').length) {
  175. ul.addClass('current');
  176. setTimeout(function () {
  177. const parentUl = ul.addClass('loading').parent('li').addClass('open')
  178. .closest('.current').removeClass('current');
  179. t.toTop(parentUl);
  180. }, 20)
  181. }
  182. $.ajax({
  183. url: ul.attr('data-json'),
  184. type: "GET",
  185. dataType: "json",
  186. xhrFields: {withCredentials: true}
  187. }).done(function (data) {
  188. ul.attr('data-cm-metadata', '[{"_":{"$Ref":"content/' + data.tocListId + '"}}]');
  189. if (data.parentId) {
  190. $('<li class="back" />').appendTo(ul)
  191. .append($('<a />').attr('href', t.baseUrl + data.parentId).text(data.title));
  192. }
  193. if(!data.hideOverview) {
  194. if (data.showOverview) {
  195. const overviewElement = $('<li class="overview" />');
  196. overviewElement.appendTo(ul)
  197. .append($('<a />').attr('href', data.url).text(window.ihk.translations.overview));
  198. if (data.contentId === currentPageId.toString()) {
  199. overviewElement.find("a").addClass("active");
  200. }
  201. }
  202. }
  203. const parentElement = data;
  204. $.each(data.items, function () {
  205. const itemsBaseUrl = ihk.settings.navigationItemsUrl;
  206. let itemUrl = this.url;
  207. if(itemsBaseUrl){
  208. itemUrl = itemsBaseUrl + itemUrl;
  209. }
  210. let li = $('<li />').attr('data-id', this.contentId).attr('data-cm-metadata', '[{"_":{"$Ref":"content/' + this.contentId + '"}}]').appendTo(ul),
  211. a = $('<a />').html(this.title).appendTo(li);
  212. switch (this.type) {
  213. case "CMChannel" :
  214. li.addClass('deep');
  215. a.attr('href', t.baseUrl + this.contentId);
  216. break;
  217. case "CMArticle" :
  218. li.addClass('link');
  219. a.attr('href', itemUrl);
  220. break;
  221. default :
  222. li.addClass('miscellaneous');
  223. li.attr('data-type', this.type);
  224. a.attr('href', itemUrl);
  225. }
  226. if (this.linktype == 'external') {
  227. li.addClass('external');
  228. $(li).find("a").attr("target","_blank")
  229. }
  230. if (this.viewType === 'onlinemagazinstart') {
  231. // todo als link
  232. li.removeClass('deep');
  233. li.addClass('magazine-nav');
  234. $(li).find("a").attr("href",itemUrl);
  235. if (this.titleImage) {
  236. a.text('').append($('<img src="' + this.titleImage + '" alt="' + this.title + '" />'))
  237. }
  238. }
  239. if (this.viewType === 'themenseite' && !parentElement.root) {
  240. li.addClass('overview');
  241. li.removeClass('deep');
  242. a.attr('href', itemUrl);
  243. }
  244. if (this.trackCode && this.trackCode.length > 0) {
  245. $(li).find("a").attr("onmousedown", this.trackCode);
  246. }
  247. if (this.restrictedTo && this.restrictedTo.indexOf('extranet') > -1) {
  248. li.addClass('extranet');
  249. } else if (this.restrictedTo && this.restrictedTo.indexOf('intranet') > -1) {
  250. li.addClass('intranet');
  251. }
  252. if (this.doctype &&
  253. (this.doctype.indexOf('Datei') > -1 || this.doctype.indexOf('PDF') > -1 || this.doctype.indexOf('PIC') > -1)) {
  254. li.addClass('download');
  255. }
  256. if(this.contentId === currentPageId.toString()){
  257. $(li).find("a").addClass("active");
  258. }
  259. });
  260. ul.addClass('current').attr('data-id', data.contentId);
  261. if (ul.parent('li').length) {
  262. setTimeout(function () {
  263. const parentUl = ul.removeClass('loading').parent('li').addClass('open')
  264. .closest('.current').removeClass('current');
  265. t.toTop(parentUl);
  266. t.manageTabIndex();
  267. }, 20)
  268. } else if (ul.next('ul').length) {
  269. const innerUl = ul.next('ul');
  270. let wrapperLi = ul.find('li[data-id="' + innerUl.attr('data-id') + '"]').addClass('open');
  271. if (!wrapperLi.length) {
  272. wrapperLi = $('<li />').addClass('open').appendTo(ul);
  273. }
  274. wrapperLi.append(innerUl);
  275. setTimeout(function () {
  276. innerUl.removeClass('current');
  277. wrapperLi.removeClass('open');
  278. t.manageTabIndex();
  279. }, 20)
  280. }
  281. })
  282. }
  283. toggleContentScroll() {
  284. const t = this;
  285. if (t.header.hasClass('nav-open') || t.header.hasClass('search-open')) {
  286. t.overlayOpen = true;
  287. this.body.trigger('overlay-open');
  288. t.body.css('top', (t.window.scrollTop() * -1) + 'px').addClass('nav-open');
  289. if (t.header.hasClass('search-open')) {
  290. t.body.addClass('search-open');
  291. }
  292. } else {
  293. t.overlayOpen = false;
  294. this.body.trigger('overlay-close');
  295. const top = Math.abs(parseInt(t.body.css('top')));
  296. t.body.removeClass('nav-open').removeClass('search-open').removeAttr('style');
  297. t.window.scrollTop(top);
  298. }
  299. }
  300. initLanguage() {
  301. const lang = this.header.find('.language');
  302. lang.find('button').on('click', function (e) {
  303. lang.toggleClass('open');
  304. })
  305. lang.on('click', function (e) {
  306. e.stopPropagation();
  307. })
  308. this.body.on('click', function () {
  309. lang.removeClass('open');
  310. })
  311. lang.siblings().find('a').on('focus', function () {
  312. lang.removeClass('open');
  313. })
  314. }
  315. manageTabIndex() {
  316. this.header.find('.primary a').attr('tabindex', '-1');
  317. this.header.find('.primary .current > li > a').removeAttr('tabindex');
  318. }
  319. toTop(ul) {
  320. if (ul.scrollTop() > 0) {
  321. ul.animate({'scrollTop': 0}, 300, 'swing');
  322. }
  323. }
  324. }
  325. export default IHKHeader;
  326. $('body').on('ihk-init', function () {
  327. $('.page-header:not(.initiated)').each((i, el) => {
  328. new IHKHeader($(el));
  329. });
  330. });