В настоящее время я пытаюсь поместить строку меню моей веб-страницы HTML в отдельный файл без использования php.
Как правильно это настроить?
Использование php-файла невозможно из-за используемой мной CMS (http://www.coast-cms.de, только на немецком языке). Поэтому мне нужно было сделать это без Include. Я почти заставил это работать так, как я хочу, используя jquery.load
.
Панель навигации загружается правильно, но выпадающее меню в ней не открывается, пока я не перезагружу, или на некоторых страницах вообще не работает.
Я подозреваю, что это как-то связано с порядком загрузки скриптов, но, учитывая мой ограниченный опыт работы с jQuery, я не смог ни узнать, как сортировать процесс загрузки, ни какой порядок был бы правильным.
<script src = "assets/js/jquery-3.4.1.min.js"></script>
<div id = "navbar"></div>
<script>
$("#navbar").load( "/modules/navbar.html");
</script>
Я ожидал, что смогу просто вставить другой html-файл в мой существующий, прежде чем что-то еще произойдет, но мой код, похоже, загружает файл в какой-то другой момент.
Обновлено: Я использую jquery.dropotron для подменю https://github.com/ajlkn/jquery.дропотрон.
navbar.html
<header id = "header">
<h1 id = "logo"><a href = "index.html">Company Name</a></h1>
<nav id = "nav">
<ul>
<li><a href = "index.html">Home</a></li>
<li>
<a href = "" class = "submenu">X</a>
<ul>
<li><a href = "a.html">A</a></li>
<li><a href = "b.html">B</a></li>
<li><a href = "c.html">C</a></li>
<li><a href = "d.html">D</a></li>
<li><a href = "e.html">E</a></li>
<li><a href = "f.html">F</a></li>
</ul>
</li>
<li><a href = "ueber_uns.html">Über uns</a></li>
<li><a href = "g.html">G</a></li>
<li><a href = "h.html">H</a></li>
<li><a href = "#FOOTER">Kontakt</a></li>
</ul>
</nav>
</header>
Обновлено еще раз: Код, который, я думаю, используется для гамбургер-меню в main.js
a('<a href = "#navPanel" class = "navPanelToggle"></a>').appendTo(b);
a('<div id = "navPanel"><nav>' + a("#nav").navList() + '</nav><a href = "#navPanel" class = "close"></a></div>').appendTo(d).panel({
delay: 500,
hideOnClick: true,
hideOnSwipe: true,
resetScroll: true,
resetForms: true,
side: "right"
});
Извините, я действительно должен был предоставить эту информацию сразу. Добавил сейчас. Я использую jquery.dropotron для подменю. (github.com/ajlkn/jquery.дропотрон) Я также добавил код navbar.html в исходный пост.
Код, в котором вы включаете dropotron.js
и вызываете $('#nav ul').dropotron()
, находится в вашем файле navbar.html
или где-то после вызова .load
на вашей первой странице? Если вы сделаете что-то вроде $('#navbar').load('/modules/navbar.html', function() { $('#nav ul').dropotron(); });
, похоже, это облегчит проблему?
То, что вы предложили, решило проблему, но сейчас я очень редко получаю два выпадающих меню. Что касается места, где он должен называться, я не на 100%, я новичок в JS и работаю с купленным шаблоном. Однако я нашел следующее в main.js, который загружается в конце главной страницы: a("#nav > ul").dropotron({ alignment: "right", hideDelay: 400 });
Это то, о чем вы говорили?
Я предполагаю, что изначально этот код иногда запускался после вызова load()
для импорта HTML, что заставляло раскрывающийся список работать правильно, но иногда запускался до завершения вызова load()
- и поэтому не находил элемент #nav ul
, поскольку он еще не был загружен. Теперь он по-прежнему работает до и после, но метод обратного вызова, который я предложил в своем предыдущем комментарии, всегда работает, поэтому иногда он создает два раскрывающихся списка для одного и того же элемента. я не знаком с вашей CMS; Вы можете отредактировать main.js
и закомментировать эту dropotron()
строку, или этот файл нельзя редактировать?
На самом деле мне удалось несколько исправить это, добавив { alignment: "right", hideDelay: 400 }
к предоставленному вами коду. Тогда я думаю, что мой вопрос решен, хотя я не уверен на 100%, сделал ли я второй раскрывающийся список невидимым, положив первый прямо поверх него. Спасибо за вашу помощь!
Прочитав ваш комментарий сейчас (напечатал мой, пока вы тоже печатали): именно в этом была проблема. Совместил проделанное с удалением строчки из .js файла, теперь все работает как задумано. Большое спасибо!
Чтобы «подвести итог» нашего обсуждения комментариев для тех, кто может столкнуться с этой проблемой: проблема заключалась в том, что сценарий выпадающего меню (с использованием jquery.dropotron
) изначально иногда запускался до того, как элемент был загружен с помощью AJAX, и иногда запускался после (другими словами, иногда элемент был загружается AJAX быстро до того, как парсер попадет в JS, который вызывает dropotron
в файле main.js
, а иногда он загружается после).
Когда вызов dropotron
был вызван до того, как элемент был загружен AJAX, ему не удалось найти ничего, к чему можно было бы прикрепиться, поэтому он ничего не сделал. Когда он был вызван после того, как элемент был загружен AJAX, он нашел элемент и смог создать раскрывающийся список (следовательно, панель навигации иногда работала, а иногда не работала).
Чтобы решить эту первую проблему, вы подтвердили, что использование обратного вызова для создания раскрывающегося списка после его загрузки фактически всегда создавало раскрывающийся список:
$('#navbar').load('/modules/navbar.html', function() {
$('#nav ul').dropotron();
});
Однако затем проблема заключалась в том, что в определенных ситуациях он вызывался дважды - это было связано с тем, что строка dropotron
вызывалась в main.js
таким же образом, как и изначально, где иногда она запускалась до завершения AJAX, а иногда после; когда он побежал после, он создал второе меню.
Окончательное решение состояло в том, чтобы закомментировать строку в main.js
, чтобы удалить второй вызов, и просто использовать обратный вызов AJAX, чтобы убедиться, что dropotron
вызывается после загрузки элемента.
Извините, что беспокою вас снова, но я думаю, что это не было полным исправлением. Ошибка появляется не часто (может быть, 1 раз из 20), но время от времени все же возникает. html index.html:61 Uncaught TypeError: $(...).dropotron is not a function at HTMLDivElement.<anonymous> (index.html:61) at HTMLDivElement.<anonymous> (jquery-3.4.1.min.js:2)
Для меня это звучит так, будто скрипт запускается до того, как что-то загрузится. Также я заметил, что гамбургер-меню для небольших устройств тоже время от времени отсутствует. Как вы думаете, можно ли заставить main.js загружаться в нужный момент?
Исправлена новая проблема с выпадающим списком, переместив загрузку dropoton в <head>, но так и не понял, как исправить меню гамбургера.
Я собирался предположить, что JS не был загружен в правильном порядке. Лучший способ, который я использовал для включения скриптов, — загружать их все по порядку в конце вашего HTML, непосредственно перед тегом </body>
. Так и должно быть <body><!-- other HTML --><script src='jquery.js'></script><script src='dropotron.js'></script><script> /* CUSTOM CODE */ </script></body>
. Таким образом, вы знаете, что весь ваш HTML-код загружается первым (кроме того, что вы загружаете с помощью AJAX), и вы знаете, что ваши скрипты в порядке (dropotron должен идти после jQuery, так как он полагается на него, а пользовательский код должен быть последним, если он использует либо).
Что касается меню гамбургеров, я сам не использовал dropotron
, но я посмотрю и посмотрю, смогу ли я определить, что происходит. У вас есть какие-либо ошибки, когда меню гамбургера не появляется?
Я не совсем уверен, что в гамбургер-меню используется дропотрон, но я добавил код, который, как мне кажется, используется для гамбургер-меню из main.js в исходный пост. Нет ошибок, когда меню гамбургера не появляется
Звучит как отдельная проблема, которая обычно требует второго вопроса о SO. В коде, который вы обновили, он использует $('#nav').navList()
, но я не уверен, что это за функция navList
или что она делает (я мог бы предположить, но я бы не стал просто гадать). Я также не знаю, что установлено для переменных b
и d
. Я бы посоветовал выяснить, что делает navList
, откуда он берется (является ли он частью другой библиотеки jQuery?), и найти, на что установлены b
и d
, а затем опубликовать новый вопрос с этой информацией и как можно больше информации о случаях когда он появляется и не появляется.
Наконец-то разобрался. Проблема заключалась только в порядке загрузки скриптов. Исправлено то, что main.js (в котором были активированы и выпадающее меню, и гамбургер-меню) не загружался до завершения загрузки всей страницы.
Я достиг этого с помощью следующего кода:
<script>$(document).ready(function() {$.getScript("assets/js/main.js");});</script>
Можете ли вы поделиться кодом
navbar.html
или хотя бы минимальной версией без личной информации / информации о компании? У вас есть JS, который работает на#navbar
после кода, который вы показали выше? Является ли раскрывающийся список простым<select>
без дополнительного JS или это настраиваемый раскрывающийся список, такой как selectmenu или раскрывающийся список Bootstrap?