Есть ли способ загрузить полнофункциональную строку меню без PHP?

В настоящее время я пытаюсь поместить строку меню моей веб-страницы 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"
        });

Можете ли вы поделиться кодом navbar.html или хотя бы минимальной версией без личной информации / информации о компании? У вас есть JS, который работает на #navbar после кода, который вы показали выше? Является ли раскрывающийся список простым <select> без дополнительного JS или это настраиваемый раскрывающийся список, такой как selectmenu или раскрывающийся список Bootstrap?

user1189882 29.05.2019 20:30

Извините, я действительно должен был предоставить эту информацию сразу. Добавил сейчас. Я использую jquery.dropotron для подменю. (github.com/ajlkn/jquery.дропотрон) Я также добавил код navbar.html в исходный пост.

vosspl 29.05.2019 20:44

Код, в котором вы включаете dropotron.js и вызываете $('#nav ul').dropotron(), находится в вашем файле navbar.html или где-то после вызова .load на вашей первой странице? Если вы сделаете что-то вроде $('#navbar').load('/modules/navbar.html', function() { $('#nav ul').dropotron(); });, похоже, это облегчит проблему?

user1189882 29.05.2019 21:12

То, что вы предложили, решило проблему, но сейчас я очень редко получаю два выпадающих меню. Что касается места, где он должен называться, я не на 100%, я новичок в JS и работаю с купленным шаблоном. Однако я нашел следующее в main.js, который загружается в конце главной страницы: a("#nav > ul").dropotron({ alignment: "right", hideDelay: 400 }); Это то, о чем вы говорили?

vosspl 29.05.2019 22:39

Я предполагаю, что изначально этот код иногда запускался после вызова load() для импорта HTML, что заставляло раскрывающийся список работать правильно, но иногда запускался до завершения вызова load() - и поэтому не находил элемент #nav ul, поскольку он еще не был загружен. Теперь он по-прежнему работает до и после, но метод обратного вызова, который я предложил в своем предыдущем комментарии, всегда работает, поэтому иногда он создает два раскрывающихся списка для одного и того же элемента. я не знаком с вашей CMS; Вы можете отредактировать main.js и закомментировать эту dropotron() строку, или этот файл нельзя редактировать?

user1189882 29.05.2019 22:50

На самом деле мне удалось несколько исправить это, добавив { alignment: "right", hideDelay: 400 } к предоставленному вами коду. Тогда я думаю, что мой вопрос решен, хотя я не уверен на 100%, сделал ли я второй раскрывающийся список невидимым, положив первый прямо поверх него. Спасибо за вашу помощь!

vosspl 29.05.2019 22:50

Прочитав ваш комментарий сейчас (напечатал мой, пока вы тоже печатали): именно в этом была проблема. Совместил проделанное с удалением строчки из .js файла, теперь все работает как задумано. Большое спасибо!

vosspl 29.05.2019 22:53
Как конвертировать HTML в PDF с помощью jsPDF
Как конвертировать HTML в PDF с помощью jsPDF
В этой статье мы рассмотрим, как конвертировать HTML в PDF с помощью jsPDF. Здесь мы узнаем, как конвертировать HTML в PDF с помощью javascript.
0
7
136
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Чтобы «подвести итог» нашего обсуждения комментариев для тех, кто может столкнуться с этой проблемой: проблема заключалась в том, что сценарий выпадающего меню (с использованием 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 загружаться в нужный момент?

vosspl 29.05.2019 23:41

Исправлена ​​новая проблема с выпадающим списком, переместив загрузку dropoton в <head>, но так и не понял, как исправить меню гамбургера.

vosspl 29.05.2019 23:48

Я собирался предположить, что 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, так как он полагается на него, а пользовательский код должен быть последним, если он использует либо).

user1189882 29.05.2019 23:52

Что касается меню гамбургеров, я сам не использовал dropotron, но я посмотрю и посмотрю, смогу ли я определить, что происходит. У вас есть какие-либо ошибки, когда меню гамбургера не появляется?

user1189882 29.05.2019 23:55

Я не совсем уверен, что в гамбургер-меню используется дропотрон, но я добавил код, который, как мне кажется, используется для гамбургер-меню из main.js в исходный пост. Нет ошибок, когда меню гамбургера не появляется

vosspl 29.05.2019 23:57

Звучит как отдельная проблема, которая обычно требует второго вопроса о SO. В коде, который вы обновили, он использует $('#nav').navList(), но я не уверен, что это за функция navList или что она делает (я мог бы предположить, но я бы не стал просто гадать). Я также не знаю, что установлено для переменных b и d. Я бы посоветовал выяснить, что делает navList, откуда он берется (является ли он частью другой библиотеки jQuery?), и найти, на что установлены b и d, а затем опубликовать новый вопрос с этой информацией и как можно больше информации о случаях когда он появляется и не появляется.

user1189882 30.05.2019 00:12
Ответ принят как подходящий

Наконец-то разобрался. Проблема заключалась только в порядке загрузки скриптов. Исправлено то, что main.js (в котором были активированы и выпадающее меню, и гамбургер-меню) не загружался до завершения загрузки всей страницы.

Я достиг этого с помощью следующего кода:

<script>$(document).ready(function() {$.getScript("assets/js/main.js");});</script>

Другие вопросы по теме