Выпадающее меню Javascript не работает в Internet Explorer

У меня есть раскрывающееся меню, в котором у меня возникают проблемы с работой в Internet Explorer. Он отлично работает с Chrome и Firefox, но ничего не делает в Internet Explorer. И я предпочитаю хранить все мои JavaScript в отдельном документе javascript.js, а также не хочу работать с библиотекой. Код HTML, который я использую, таков:

<div id="sidemeny-container">
<div class="sidemenu-maincat">
    cat1
        <div class="sidemenu-subcat hidden">
         - Subcat 1 
        </div>
        <div class="sidemenu-subcat hidden">
         - Subcat 2 
        </div>
        <div class="sidemenu-subcat hidden">
         - Subcat 3 
        </div>  
    </div>

    <div class="sidemenu-maincat">
    cat2
        <div class="sidemenu-subcat hidden">
         - Subcat 2-1 
        </div>
        <div class="sidemenu-subcat hidden">
         - Subcat 2-2 
        </div>
        <div class="sidemenu-subcat hidden">
         - Subcat 2-3 
        </div>  
    </div>
        </div>

И код CSS:

#sidemeny-container {
    border-bottom:1px #000 solid; 
    height: auto;
    width: 153px;
    float:left;
    padding: 10px 0px 0px 0px;

}

.sidemenu-maincat {
    border-top: 1px #000 solid;
    border-right: 1px #000000 solid;
    width:148px;
    height:auto;
    float:left;
    padding: 0px 0px 0px 5px;
}

.sidemenu-subcat.hidden {
    display:none;
    width:148px;
    height:auto;
    float:left;
    padding: 0px 0px 0px 15px;
}

И javascript, который у меня есть в отдельном документе .js:

    function initiate()
    {

  if (document.getElementsByClassName)
    {
        var sideMenuOptions = document.getElementsByClassName('sidemenu-maincat');
        for (var i = 0; i < sideMenuOptions.length; i++) {
            sideMenuOptions[i].addEventListener('click', function() {
                var subMenuItems = this.getElementsByClassName('sidemenu-subcat');
                for (var s = 0; s < subMenuItems.length; s++) {
                    var subItem = subMenuItems[s];
                    if (subItem.offsetWidth === 0 && subItem.offsetHeight === 0) {
                        subItem.className = 'sidemenu-subcat';
                    } else {
                        subItem.className = subItem.className + ' hidden';
                    }
                }
            });
        }
    }
    else
    {
        var sideMenuOptions = document.getElementsByTagName('div');
        for (var i = 0; i < sideMenuOptions.length; i++) {
            if (sideMenuOptions[i].className == 'sidemenu-maincat')
            {
                sideMenuOptions[i].addEventListener('click', function() {
                    var subMenuItems = this.getElementsByClassName('sidemenu-subcat');
                    for (var s = 0; s < subMenuItems.length; s++) {
                        var subItem = subMenuItems[s];
                        if (subItem.offsetWidth === 0 && subItem.offsetHeight === 0) {
                            subItem.className = 'sidemenu-subcat';
                        } else {
                            subItem.className = subItem.className + ' hidden';
                        }
                    }
                });
            }
        }
    }
    }

    window.onload = initiate;
0
nl ja de
@Plynx Он говорит: «Объект не поддерживает это свойство или метод» и помещает его в строку, начинающуюся с sideMenuOptions [i] и остальную часть скрипта.
добавлено автор Benji, источник
Это IE 8. Как я могу обойти это?
добавлено автор Benji, источник
Какая версия IE это? IE 8 и менее не поддерживали addEventListener .
добавлено автор Plynx, источник
Нажмите F12, чтобы открыть инструменты разработчика и нажмите «Начать отладку» на вкладке сценария, а затем запустите свой код. Есть ли ошибки? IE любит тихо терпеть неудачу, если вы не скажете, что хотите узнать.
добавлено автор Plynx, источник

2 ответы

Your code works fine on IE9 & IE10. However, previous versions do not support addEventListener, and the attachEvent method does not supply a currentTarget property. For this reason, the only way to determine the calling object is to replace the this reference via prototyping (or use a framework).

Другая проблема с вашим кодом заключается в том, что IE8 не поддерживает getElementsByClassName() . Пока ваш код проверяет это, резервный пытается снова использовать его для создания экземпляра subMenuItems . Лучшим подходом было бы использовать Document.querySelectorAll , который работает в IE8 и выше и позволит вам избежать дублирования кода.

Полный пример:

Element.prototype.addAnEvent = function(name, funct) {
    if (this.addEventListener) {
        this.addEventListener(name, funct, false);
    } else if (this.attachEvent) {
        var _this = this;
        this.attachEvent("on" + name, function() {
            funct.apply(_this);
           //where the value of "this" in funct should point to "element"
        });
    }
};

function initiate() {
    var sideMenuOptions = document.querySelectorAll('.sidemenu-maincat');
    for (var i = 0; i < sideMenuOptions.length; i++) {
        sideMenuOptions[i].addAnEvent('click', function() {
            openSubmenu(this);
        });
    }
}

function openSubmenu(element) {
    var subMenuItems = element.querySelectorAll('.sidemenu-subcat');
    for (var s = 0; s < subMenuItems.length; s++) {
        var subItem = subMenuItems[s];
        if (subItem.offsetWidth === 0 && subItem.offsetHeight === 0) {
            subItem.className = 'sidemenu-subcat';
        } else {
             subItem.className = subItem.className + ' hidden';
        }
    }
}

window.onload = initiate;
1
добавлено
Это сделал трюк! Большое спасибо человеку. Это так чертовски сложно без библиотеки, а IE - настолько дерьмовый.
добавлено автор Benji, источник
Да, это, похоже, решает все проблемы. Хотя я хотел бы иметь все мои javascripts в отдельном документе, который я использую для них. Есть ли способ решить это?
добавлено автор Benji, источник
Это связано с тем, что document.querySelectorAll ('. Sidemenu-maincat') выбирает только div, а изображения накладываются поверх div, что делает их «обложками» div, что делает некоторые детали не доступны для кликов?
добавлено автор Benji, источник
И ошибок в консоль dev тоже нет.
добавлено автор Benji, источник
Humm ... Я работаю для меня, когда я нажимаю фактический div, но не тогда, когда я нажимаю картинку, находящуюся внутри div. Я попробую его с полным кодом и посмотрю, как он там работает. EDIT: Это то же самое, оно работает, когда изображение не кликает, а div.
добавлено автор Benji, источник
И теперь это не работает вообще :(
добавлено автор Benji, источник
Это действительно работает, но он всегда открывает второе подменю, то есть варианты, которые появляются всегда Subcat 2-1 Subcat 2-2 Subcat 2-3
добавлено автор Benji, источник
Я действительно не понимаю, как заставить его работать: /
добавлено автор Benji, источник
Поэтому я просто поставил это перед моей строкой кода с помощью addEventListener ? Я совершенно новый с javascript, и я не полностью понимаю весь этот код.
добавлено автор Benji, источник
Извини за это. Ссылка на элемент заменялась на каждой итерации цикла. Я обновил свой ответ, чтобы исправить это, установив элемент в источник события.
добавлено автор Theodore Brown, источник
Он работает для меня в IE8 +. Вы получаете какие-либо ошибки в консоли dev?
добавлено автор Theodore Brown, источник
Бенджи - я добавил полный пример кода. Надеюсь это поможет.
добавлено автор Theodore Brown, источник
Я заметил, что если вы добавите onclick = "openSubmenu (this)" в div sidemenu-maincat, щелчок по изображению будет корректно работать в IE8.
добавлено автор Theodore Brown, источник
Я понял проблему. event.srcElement возвращает источник события, а не элемент, на который было обработано событие (в вашем случае он вернет изображение, если это то, что вы нажали). Поскольку attachEvent не имеет свойства currentTarget , единственный способ определить вызывающий объект - заменить ссылку this с помощью прототипирования. Я обновил свой ответ, чтобы отразить это.
добавлено автор Theodore Brown, источник

Большинство разработчиков ответят на эту проблему, используя надежный полиполк, такой как JQuery, который обрабатывает такие проблемы совместимости с другими браузерами, как это для вас. Он очень старался не отставать от всех вопросов, связанных с перекрестным браузером!

Если вам интересно, вы можете включить jQuery в свой источник и заменить

sideMenuOptions[i].addEventListener('click', function() { 

с

$(sideMenuOptions[i]).on("click", function() { 

Это должно заставить вас начать.

0
добавлено
Да ... Проблема только в том, что я действительно борюсь за то, как решить это, сделав это на данный момент.
добавлено автор Benji, источник
Я не использую какую-либо библиотеку
добавлено автор Benji, источник
@Benji Нет проблем! По крайней мере, теперь вы знаете, в чем проблема. Каждый раз, когда вы используете функцию, не поддерживаемую IE, вам нужно разветвиться в обоих способах ее выполнения.
добавлено автор Plynx, источник
@Benji Это потому, что это сложно! Это фиктивный и склонный к ошибкам, и даже опытные разработчики могут столкнуться с проблемами. Вот почему мы в основном используем библиотеки, которые отсортировали все это. Кто хочет запомнить несколько способов сделать каждую простую вещь? Если вы хотите попробовать себя в этом, каждый раз, когда вы достигаете ошибки в IE, оберните этот оператор с помощью if (/ * независимо от имени функции * /) , чтобы узнать, существует ли он. Если он существует, используйте его. Если это не так, в предложении else сделайте это способом IE. Сайты quirksmode.org и
добавлено автор Plynx, источник
JavaScript Jobs — чат
JavaScript Jobs — чат
8 336 участник(ов)

JavaScript Jobs — чат для поиска работы и людей Правила оформления: https://teletype.in/@telegram-ru/r1WQe5F1m См. также: @mobile_jobs, @devops_jobs, @nodejs_jobs, @react_js, @angular_ru, @js_ru

JavaScript.ru
JavaScript.ru
7 932 участник(ов)

Сообщество сайта JavaScript.ru в Slack.

pro.js
pro.js
4 675 участник(ов)

Про JavaScript и NodeJS Invite: https://t.me/joinchat/Be4rsT5Rsgq30DHutjxXgA Правила: http://telegra.ph/ru-chat-rules-06-19 Вакансии только с ЗП, не чаще раза в неделю.

JavaScript — русскоговорящее сообщество
JavaScript — русскоговорящее сообщество
3 269 участник(ов)

Рекомендуем сразу отключить уведомления Правила: https://rudevs.network/ByaMH6un7 См. также: @js_noobs_ru, @nodejs_ru, @typescript_ru, @react_js, @electron_ru Вакансии и поиск работы: @javascript_jobs

JavaScript Noobs — сообщество новичков
JavaScript Noobs — сообщество новичков
2 484 участник(ов)

Чат для новичков

javascript_ru
javascript_ru
915 участник(ов)

Сообщество любителей самого популярного языка программирования в мире. Чат основан в 2009 году. Логи: https://goo.gl/9EOeM7 Поддержка бота: @chat_linker (ссылка на репу внутри) Вам будут интересны @frontend_ru и @css_ru

jsChat
jsChat
603 участник(ов)

Чат посвященный программированию на языке javaScript Перед отправкой ссылки на Ваш контент посоветуйтесь с админом Все ссылки удаляются ботом автоматически

JavaScript for Zombies Chat
JavaScript for Zombies Chat
492 участник(ов)

Чат про JavaScript для настоящих zombie! Вход строго по приглашениям! Ссылка для строгих приглашений: https://t.me/joinchat/AAMBHz3Uyr0tuZ7VaB029g

All That JS
All That JS
417 участник(ов)

JS на русском