Модераторы: Sardar, Aliance
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Добавление правил в таблицу стилей в FF 
V
    Опции темы
Ciber SLasH
Дата 17.4.2014, 17:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1813
Регистрация: 9.11.2004
Где: С.-Петербург

Репутация: 24
Всего: 67



Приветствую всех!
Давно написал ф. для добавления правила в таблицу стилей и ф. работала. Но с какой-то версии FireFox перестала работать ф. и меню не отрабатывает.
Подскажите пожалуйста, где ошибка в коде:
Код

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content='text/html; charset=windows-1251'>
<link rel="stylesheet" type='text/css' href='./main.css'>
<script type='text/javascript'>
/*** Для добавления правил в таблицу стилей ***/
function changeStyle(css, ssNum) {
var styleObj = document.getElementsByTagName('STYLE')[0];
    if (!styleObj) {    // если нет тэга STYLE в документе
        styleObj = document.createElement('STYLE');
        styleObj.type = 'text/css';
        document.getElementsByTagName('HEAD')[0].appendChild(styleObj);
    }
    if (document.styleSheets) {
        if (document.styleSheets[ssNum].addRule) {    // for IE
            var sList = css.split('\n');
            for (var i = 0; i < sList.length; i++) {
                var selector = sList[i].substr(0, sList[i].search(/\s\{/));
                var rule = (
                    sList[i].substring( sList[i].indexOf('{')+1, sList[i].lastIndexOf('}') )
                ).replace(/[\t\r\n]/g, '');
                document.styleSheets[ssNum].addRule(selector, rule);
            }
        }
        else if (document.styleSheets[ssNum].insertRule) {    // for FF
            document.styleSheets[ssNum].insertRule(css, document.styleSheets[ssNum].cssRules.length);
        }
    }
    else if (!window.opera) {    // for NOT Opera
        var rule = document.createTextNode(css);
        styleObj.appendChild(rule);
    }
}
onload = function () {
//==[ Fix stylesheets ]=========================================================
// Fix UL margin-left в FF в добавление border-collapse во всех браузерах, кроме Оперы
var cssFF = 'ul {margin-left: -20px}\n';
var css =
    'table {table-layout: fixed; border-collapse: collapse}';
    //'td {border: 3px double #269CF7}';
    if (document.body.textContent) {    // if FF
        //document.styleSheets[1].insertRule(cssFF+css, document.styleSheets[1].cssRules.length);
        changeStyle(cssFF+css, 1);
    } else {
        changeStyle(css, 1);
    }
//==[ Add event to menu ]=======================================================
menuElem = document.getElementById("menu");
    for (var i = 0; i < menuElem.childNodes.length; i++) {
        var curNode = menuElem.childNodes[i];
        if (curNode.nodeName == "LI") {
            curNode.onmouseover = function () {this.className = "enter"}
            curNode.onmouseout = function () {this.className = ""}
            if (curNode.lastChild.nodeName == "UL"    // IE
                ||
                curNode.lastChild.previousSibling.nodeName == "UL"    // Gecko
            )
                curNode.firstChild.className = "subMenu";
        }
    }
}
</script>
<style type='text/css'>
@import url("./menu.css");
body {overflow-x: hidden}
ul {margin-left: 20px}
td {border: 1px solid #269CF7}    /* for Opera */
</style>
</head>

<body>
<div class='menu' onMouseOver='menuElem.style.display = "block"' onMouseOut='menuElem.style.display = "none"'>
<span id='menuText'>МЕНЮ</span>
<ul id='menu' onClick='menuElem.style.display = "none"'>
    <li><a href='#JS_sprav'>Справочник по JavaScript</a>
        <ul>
            <li><a href='#stand_comp'>Стандарты и совместимость</a></li>
            <li><a href='#object_model'>Объектная модель JavaScript</a></li>
            <li><a href='#model_event'>Модели событий JavaScript</a></li>
        </ul>
    </li>
</ul>
</div>
</body>
</html>

FF ругается в консоль так:
Цитата
Ошибка: SyntaxError: An invalid or illegal string was specified
Источник: test.htm
Строка: 27


Это сообщение отредактировал(а) Ciber SLasH - 17.4.2014, 17:03

Присоединённый файл ( Кол-во скачиваний: 1 )
Присоединённый файл  css.rar 1,29 Kb
PM   Вверх
Aliance
Дата 25.4.2014, 14:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 55
Всего: 137



Использовать глобальную переменную menuElem в атрибутах обработчиков событий - не гуд. У меня на jsfiddle выдает как минимум эту ошибку.
PM MAIL WWW ICQ Skype   Вверх
Ciber SLasH
Дата 27.4.2014, 00:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1813
Регистрация: 9.11.2004
Где: С.-Петербург

Репутация: 24
Всего: 67



Заменил в обработчиках событий глобальную переменную на document.getElementById("menu") и заработало, но в консоли всё равно ругается на 27 строку:
Цитата
Ошибка: SyntaxError: An invalid or illegal string was specified
Строка: 27

Хотя раньше и так работало. Видимо в новых версиях FF обработчики событий больше не видят глобальных переменных.
PM   Вверх
Aliance
Дата 28.4.2014, 10:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 55
Всего: 137



Не то, чтобы это не правильно, но лично мне кажется нелогичным. Я бы посоветовал делать так:
в обработчики событий вешать функции (при чем лучше делать это именно inline, чтобы было сразу понятно что должно вызываться и когда), а в функции обращаться к единой переменной, которая просчитана один раз в закеширована (это может быть и глобальная, конечно, но лучше в качестве неймспейса завести некий объект и переменную хранить как его свойство).

Выложи обновленный код на jsfiddle и посмотрим, что там за ошибка.
PM MAIL WWW ICQ Skype   Вверх
Ciber SLasH
Дата 28.4.2014, 22:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1813
Регистрация: 9.11.2004
Где: С.-Петербург

Репутация: 24
Всего: 67



Попробовал создать объект, на обработчики навесить функции - вообще перестало работать в FF 28.0
http://jsfiddle.net/YRNF9/2/
PM   Вверх
Aliance
Дата 29.4.2014, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 55
Всего: 137



Ну а теперь открываем консоль по ссылке и видим ошибки:
Цитата

Uncaught ReferenceError: menuHide is not defined
Uncaught ReferenceError: menuShow is not defined 


Это потому, что в левом верхнем селекте нужно выбрать было не onload, а no wrap (лучше в body, но для примера все равно).

После этого вроде как пример работает нормально, без ошибок. Только я бы посоветовал не извращаться и писать все атрибуты html в нижнем регистре, onClick выглядит ужасно. Но это лишь мое мнение smile
PM MAIL WWW ICQ Skype   Вверх
Ciber SLasH
Дата 29.4.2014, 11:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1813
Регистрация: 9.11.2004
Где: С.-Петербург

Репутация: 24
Всего: 67



Выбрал no wrap, изменил атрибуты в нижний регистр. В текущем состоянии:
Цитата
Метка времени: 29.04.2014 12:15:37
Ошибка: TypeError: menuObj.menu is undefined
Источник: http://fiddle.jshell.net/YRNF9/7/show/
Строка: 194

PM   Вверх
Aliance
Дата 29.4.2014, 16:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 55
Всего: 137



Какой браузер-то? В Хроме все окей. Видимо проблема в Лисе? Вообще, 194 строчка - это первая строчка в функции changeStyle. Может быть идет наведение мышкой ДО события onload? Тогда еще объект не успевает заинититься, и такая ошибка может возникнуть. Но это нормально. Не нормально то, что такая ситуация не обрабатывается внутри методов, навешанных на события.

А зачем вообще нужна функция changeStyle? Она, честно говоря, похода на огромный костыль. Что мешает просто написать нужные стили сразу и просто менять класс у элемента при взаимодействии с ним? Ну или второй вариант менять стили (elem.style.STYLE = 'VALUE')?

И еще, я бы вот таких проверок не делал бы (curNode.nodeName == "LI"), ибо регистрозависимость есть зло. Лучше привести в нижний регистр и сравнивать с li.

Кстати, чтобы работало \n - нужно его заключать в двойные кавычки.
PM MAIL WWW ICQ Skype   Вверх
Ciber SLasH
Дата 29.4.2014, 17:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1813
Регистрация: 9.11.2004
Где: С.-Петербург

Репутация: 24
Всего: 67



Браузер уже писал - FF 28.0
Остальное позже поковыряю...
PM   Вверх
Ciber SLasH
Дата 1.5.2014, 19:06 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1813
Регистрация: 9.11.2004
Где: С.-Петербург

Репутация: 24
Всего: 67



Внутри методов повесил проверку: typeof(menuObj.menu) == "undefined"
Функция действительно костыль. Она и была написана, как костыль для разных браузеров.
А по поводу \n ошибаешся - оно работает и в одинарных и в двойных кавычках в JS. Это у PHP в одинарных кавычках строка не вычисляется.
А ошибка:
Цитата
Ошибка: SyntaxError: An invalid or illegal string was specified
Источник: test.htm
Строка: 27

как выяснилось, означает, что insertRule не поддерживает мультистроки. Поэтому пршлось мультистроку css-правил разбивать на части:
Код
var ruleList = css.split("\n");
for (var i = 0; i < ruleList.length; i++) {
    SS.insertRule(ruleList[i], SS.cssRules.length);
}

Код по ссылке исправил.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Форум для вопросов, которые имеются в справочниках, но их поиск вызвал затруднения, или для разработчика требуется совет или просьба отыскать ошибку. Напоминаем: 1) чётко формулируйте вопрос, 2) приведите пример того, что уже сделано, 3) укажите явно, нужен работающий пример или подсказка о том, где найти информацию.
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | JavaScript: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0891 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.