Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 06.08.2014, 12:37
Интересующийся
Отправить личное сообщение для Mitrich Посмотреть профиль Найти все сообщения от Mitrich
 
Регистрация: 24.08.2013
Сообщений: 20

Как обмануть jQ при помощи jQ? (CamelCase в атрибутах)
Приветствую!

Столкнулся с любопытной проблемой.
Нужно в рамках одного проекта под jQuery работать с SVG. Оказалось, что jQuery берёт на себя наглость принудительно все имена атрибутов переводить в нижний регистр, а SVG енто XML и к регистру более чем чувствителен...

Разрабы jQuery более 3-х лет гордо отказываются фиксить баг переводя его в разряд фичи... http://bugs.jquery.com/ticket/11166#propertyform

Предвижу советы написать на нативном javascript, что-то вроде:
document.getElementsByTagName('svg')[0].setAttribute('someAttributes', 'x')
Но запутка в том, что практически весь DOM выводится и обновляется jQuery и в итоге получаю всё равно someattributes

Вот и получается нужен костыль для победы над jQuery средствами самой jQuery.
Первое, что пришло в голову каким ниб регулярным выражением пройтись и исправить написание. Но не пойму можно ли взять и переписать кусок сырого хэтэмэля без использования attr() setAttribute() и т.п....

А может ещё какие варианты есть?
Ответить с цитированием
  #2 (permalink)  
Старый 06.08.2014, 12:43
Аватар для ixth
Профессор
Отправить личное сообщение для ixth Посмотреть профиль Найти все сообщения от ixth
 
Регистрация: 19.01.2010
Сообщений: 354

Это, конечно, совет не в тему, но попробуй всю работу с svg оформить с помощью Snap.svg.

UPD. Или покажи код, чтобы было ясно как именно при помощи jQuery выводится SVG.

Последний раз редактировалось ixth, 06.08.2014 в 12:45.
Ответить с цитированием
  #3 (permalink)  
Старый 06.08.2014, 13:02
Интересующийся
Отправить личное сообщение для Mitrich Посмотреть профиль Найти все сообщения от Mitrich
 
Регистрация: 24.08.2013
Сообщений: 20

Не знаю... Библиотека, как таковая особо и не нужна.
Проблема в том, что требуется внедрять сырой SVG прямо в html вроде:

<svg baseProfile="full" width="300" height="200" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns="http://www.w3.org/2000/svg" version="1.1" id="svg">
......
</svg>

А jQuery гадит если тащить код svg ещё какой-то библиотекой, то наверное ничего не изменится... только ещё библиотеку осваивать...

--
И да, от jQuery отказаться нельзя... там много чего с ним понакручено...

Последний раз редактировалось Mitrich, 06.08.2014 в 13:11.
Ответить с цитированием
  #4 (permalink)  
Старый 06.08.2014, 13:16
Отправить личное сообщение для Octane Посмотреть профиль Найти все сообщения от Octane  
Регистрация: 10.07.2008
Сообщений: 3,873

jQuery специально не выполняет toLowerCase для имен атрибутов, это делает браузер, пока документ отображается в режиме text/html, т.е. если выполнить:
document.body.setAttribute('A', 1)
Chrome и Firefox добавят атрибут «а»:
[JS]document.body.attributes[0].name //→ 'a'

Последний раз редактировалось Octane, 06.08.2014 в 16:14.
Ответить с цитированием
  #5 (permalink)  
Старый 06.08.2014, 13:54
Интересующийся
Отправить личное сообщение для Mitrich Посмотреть профиль Найти все сообщения от Mitrich
 
Регистрация: 24.08.2013
Сообщений: 20

Хм.. та ки jQ плюёт на любой DOCTYPE и конвертит всё в нижний регистр. setAttribute нативного js работает корректно, но не в моём случае... Кроме костыля ничего не поможет... Разве что удалить toLowerCase() из кода jQ, но это как-то совсем грязно...
Ответить с цитированием
  #6 (permalink)  
Старый 06.08.2014, 14:17
Аватар для Makarov
Профессор
Отправить личное сообщение для Makarov Посмотреть профиль Найти все сообщения от Makarov
 
Регистрация: 08.07.2013
Сообщений: 212

Посмотрел у себя: в хроме и лисе в lowercase конвертит браузер, ишак регистр сохраняет.
Ответить с цитированием
  #7 (permalink)  
Старый 06.08.2014, 14:21
Отправить личное сообщение для Octane Посмотреть профиль Найти все сообщения от Octane  
Регистрация: 10.07.2008
Сообщений: 3,873

Я же говорю, jQuery не при чем, преобразование выполняет браузер. При изменении доктайпа документ не перестанет быть text/html контентом, сервер должет отдавать заголовок content-type: application/xml+xhtml, но это никто в здравом уме не использует.

Когда мы вставляем inline-svg в text/html контент с помощью innerHTML браузер выполняет преобразования и ничего с этим мы поделать не можем. В примере ниже атрибуты WIDTH и HEIGHT при вставке в документ без использования jQuery преобразуются в нижний регистр:
<!DOCTYPE html>
<html lang="en">
<head>
    <title>…</title>
    <meta charset="UTF-8">
</head>
<body>
    <script>
        var inlineSVG = '<svg WIDTH="300" HEIGHT="200"><polygon points="100,10 40,198 190,78 10,78 160,198" style="fill:lime;stroke:purple;stroke-width:5;fill-rule:evenodd;" /></svg>',
            tmpContainer = document.createElement('div'),
            svgElement;

        tmpContainer.innerHTML = inlineSVG;
        svgElement = document.body.appendChild(tmpContainer.firstChild);
        tmpContainer = null;

        alert([
            svgElement.attributes[0].name,
            svgElement.attributes[1].name
        ]);
    </script>
</body>
</html>

Последний раз редактировалось Octane, 06.08.2014 в 16:09.
Ответить с цитированием
  #8 (permalink)  
Старый 06.08.2014, 14:33
Интересующийся
Отправить личное сообщение для Mitrich Посмотреть профиль Найти все сообщения от Mitrich
 
Регистрация: 24.08.2013
Сообщений: 20

Э нет... Так да не так
Напр.: в Вашем примере добавим атрибут svg baseProfile

<!DOCTYPE html>
<html lang="en">
<head>
    <title>…</title>
    <meta charset="UTF-8">
</head>
<body>
    <script>
        var inlineSVG = '<svg baseProfile="full" WIDTH="300"  HEIGHT="200"><polygon points="100,10 40,198 190,78 10,78 160,198" style="fill:lime;stroke:purple;stroke-width:5;fill-rule:evenodd;" /></svg>',
            tmpContainer = document.createElement('div'),
            svgElement;

        tmpContainer.innerHTML = inlineSVG;
        document.body.appendChild(tmpContainer.firstChild);
        tmpContainer = null;
        svgElement = document.querySelector('svg');

        alert([
            svgElement.attributes[0].name,
            svgElement.attributes[1].name,
            svgElement.attributes[2].name,
        ]);
    </script>

</body>
</html>


PS. И енто логично.., иначе как бы браузеры вообще отображали бы svg (в полном объёме)

PPS. А как добавит батон "посмотреть" к примеру?
PPPS. И да результат будет корректный alert выдаст baseProfile.....

-----
В коде jQ туева хуча конвертаций в нижний регистр, на подобии:
// All attributes are lowercase
		// Grab necessary hook if one is defined
		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
			name = name.toLowerCase();
			hooks = jQuery.attrHooks[ name ] ||
				( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
		}

К сожалению я не настолько владею предметом, что бы найти непосредствено корень зла и пропатчить его. По этому написание костыля мне кажется более простой задачей, но и с ней я пока не справляюсь...

Последний раз редактировалось Octane, 06.08.2014 в 15:27. Причина: [html run]
Ответить с цитированием
  #9 (permalink)  
Старый 06.08.2014, 15:40
Отправить личное сообщение для Octane Посмотреть профиль Найти все сообщения от Octane  
Регистрация: 10.07.2008
Сообщений: 3,873

хм ну да isXMLDoc для inline-svg будет возвращать false…
можно попробовать декоратор для jQuery.isXMLDoc написать, который будет дополнительно проверять, что элемент не вложен в <svg>.
Ответить с цитированием
  #10 (permalink)  
Старый 06.08.2014, 15:54
Отправить личное сообщение для Octane Посмотреть профиль Найти все сообщения от Octane  
Регистрация: 10.07.2008
Сообщений: 3,873

Ченибудь типа такого
jQuery.isSVG = new function () {
    function isSVG(node) {
        return node.nodeName.toLowerCase() == 'svg';
    }
    return function (elem) {
        while (elem) {
            if (isSVG(elem)) {
                return true;
            }
            elem = elem.parentNode;
        }
        return false;
    };
};

jQuery.isXMLDoc = new function () {
    var isXMLDoc = jQuery.isXMLDoc;
    return function (elem) {
        return jQuery.isSVG(elem) || isXMLDoc(elem);
    };
};

не проверял на работоспособность


--------------------------
а блин там же в условии nType !== 1, весь jQuery.attr придется переопределять

Последний раз редактировалось Octane, 06.08.2014 в 16:06.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как при щелчке прибавить значение cookies на единицу. Peter23 Общие вопросы Javascript 6 23.02.2013 13:14
Скролл контента при помощи Drag&Drop, как прокрутка в Google Maps Deprime Элементы интерфейса 1 24.12.2012 15:47
Как отследить пропал ли текст placeholder-а при фокусе на поле ввода z1987 Общие вопросы Javascript 2 19.12.2012 11:10
Как при чтении или записи свойства объекта вызывать функцию danik.js Общие вопросы Javascript 3 16.09.2010 17:57
Подскажите как при помощи JS hta в трею свернуть kimboo Общие вопросы Javascript 4 11.07.2008 16:00