Показаны сообщения с ярлыком browsers. Показать все сообщения
Показаны сообщения с ярлыком browsers. Показать все сообщения

среда, 29 июля 2015 г.

RegExp в Presto

Opera в своё время прославилась тем, что не поддерживала compile() у регулярных выражений. Дело было в движке Presto (которые почему-то не желает их копилировать).

И вот случилось - Opera переехала на Blink. Теперь compile() поддерживается.... но не в Opera Mini, которая как была на Presto, там так и остаётся.

понедельник, 1 июня 2015 г.

Показать в JavaScript alert без остановки таймера

Вообще, использовать стандартный JavaScript alert даже для отладки - плохая идея. Для сообщений есть отличные окошки из Bootstrap JS или jQueryUI, для отладочной информации - console.log.

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

В браузерах, основанных на WebKit (Chrome, Safari, JavaFX WebEngine) открытый alert считается чрезвычайным событием и останавливает все таймеры своей нити. Поэтому показывать его надо в отдельной нити, вот так:

function showMessage(text){
  setTimeout(function() { alert(text); }, 1);
}

понедельник, 30 марта 2015 г.

JavaScript charset в браузере

Согласно стандарту HTML5, стандартная кодировка страницы - UTF-8. А вот с JavaScript всё сложнее.

Пусть у нас есть какой-то JSON. Напишем функцию, которая его возвращает:

function getOutlineJson() {
  return {
      "title" : "Элемент1"
  };
}

Сохраняем в отдельный файл, привязываем через <script>. Пытаемся вывести в консоль:


document.addEventListener('DOMContentLoaded', function() {
  console.log(getOutlineJson());
});

В консоли будет JSON с полями на неведомом языке. Хотя, как подтверждает view.encoding() в консоли Sublime, все файлы - в UTF-8.

А если добавить вывод чего-то кириллического прямо на экран?

document.addEventListener('DOMContentLoaded', function() {
  console.log("проверка консоли");
  console.log(getOutlineJson());
});

Внезапно, кодировка починилась. Видимо, кодировка выставляется по первому вызову.

Лечится мета-тегом:

<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />

Проверено в Firefox и Chrome.

понедельник, 17 сентября 2012 г.

CSS: @import

Оказывается, в CSS можно делать include. Синтаксис вот такой:
@import url("filename") [type]
Типы бывают:
  • all - Все типы. Это значение используется по умолчанию.
  • aural - Речевые синтезаторы, а также программы для воспроизведения текста вслух. Сюда, например, можно отнести речевые браузеры.
  • braille - Устройства, основанные на системе Брайля, которые предназначены для слепых людей.
  • handheld - Наладонные компьютеры и аналогичные им аппараты.
  • print - Печатающие устройства вроде принтера.
  • projection - Проектор.
  • screen - Экран монитора.
  • tv - Телевизор.

Часто ли вы видите CSS-вёрстку на экране телевизора? Жалко, что там их не применяют. Можно бы было вырезать рекламные паузы через ADBlock.

С мест сообщают, что мобильные браузеры не понимают @import, если путь файлу не обрамлён url. Хотя по стандарту:

Работающий вариант:

@import url("filename") [type]
И не работающий:

@import "filename" [type]
эквивалентны.

И ещё – IE 7 не поддерживает типы. Более того, если указать тип, то он перестаёт подгружать и сам файл.

воскресенье, 16 сентября 2012 г.

showModalDialog’s returnValue is undefined in Chrome

С мест сообщают – в Chrome у showModalDialog returnValue – undefined. Баг известен с 2010 года и пока (16 сентября 2012) не исправлен.

Фиксить так:

В окне, которое вызывает модальное:

window.returnValue = undefined;
var result = window.showModalDialog("modalwindow.aspx", window, "dialogHeight:650px; dialogWidth:900px;");
if (result == undefined)
   result = window.returnValue;
if (result != null && result != "undefined")
  // Do something with the return value
  // defined in "result"

В модальном окне:

if (window.opener) {
    window.opener.returnValue = "your return value";
}
window.returnValue = "your return value";
self.close();

IE isn’t focusing anchor link

В IE обнаружен загадочный баг.

Если ASP.Net страница:

  • делает (например, по нажатию на страницу) redirect на другую через anchor (т.е. otherPage.aspx#anchor)
  • в IIS настроен ISAPI_Rewrite (локально повторить не удалось)
  • браузер – IE (повторяется в т.ч. в 9-ом)

То может случится так, что anchor “отбросится” и страниця загрузится как otherPage.aspx.

Выловить и перенастроить практически невозможно.

Единственный выход – вместо redirect вставлять в literal на странице “<script language=’javascript’>location.href = ‘otherPage.aspx#anchor’;</script>”. Можно дополнительно поставить проверку – делать такой redirect только если браузер ie. Название браузера искать в Request.Browser.Type.

О document.ready заботаться не стоит – redirect он и есть redirect.

суббота, 25 августа 2012 г.

Click() doesn’t work in Chrome and Safari

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

Как правило, это работает. Но в браузерах на движке WebKit (например, Chrome и Safari) может и не сработать. В частности, Safari игнорирует click() по скрытым объектам.

Поэтому надо скрывать “народным” способом, чтобы не поломать вёрстку:

Вместо:

display: none;

Поставить в CSS:

width: 0px;
height: 0px;
position: absolute;

пятница, 21 октября 2011 г.

JavaScript: быстрые циклы

length в JavaScript - штука медленная. Это очень хорошо видно по скорости выполнения циклов. Вовремя заменив for на while, можно получить выигрыш в производительности в 7 раз.

В умелых руках циклы JavaScript прекрасно заменяют друг друга. А значит, есть повод дополнить старый постинг о среднем арифметическом.

var digitRegEx=/^-?\d+([,\.]\d+)?$/g;
 
function arithmeticMean() {
  var len = arguments.length, i = len, finalSum = 0;
  if (!i)
    return 0;
  while (i--)
    if (digitRegEx.test(arguments[i]))
      finalSum += parseFloat(arguments[i]);
  return (len) ? finalSum / len : 0;
}

Кстати, как народная, так и более-менее проектная реализация всяких дополнительных функций для IE грешат for по lenght и ужасающе медленным trim(). Если руки дойдут - надо бу исправить.

четверг, 13 октября 2011 г.

JavaScript: concat для getElementsByTagName

Иногда гибкость JavaScript немного обманывает. Например, все знают, что getElementsByTagName возвращает вроде бы массив. И если нам нужно получить все input и textarea, то мы посмотрим в справке, что есть фунция concat и - склеим!

Увы, нас ждёт разочарование. То, что приходит - это набор, но не совсем массив. Его надо преобразовывать в Array и уже потом склеивать.

Как склеивать? Обычно рекомендуют Array.prototype.slice.call(document.getElementsByTagName('input'), 0) или немыслимое [].slice.call(document.getElementsByTagName('input'), 0). Это работает во всех браузерах, кроме... IE. IE считает, что COM-объект HTMLCollection вовсе не обзательно будет массивом. И бросает ошибку "JScript object expected.".

Поэтому мы расширим функцию из предыдущего примера ещё одной полезной тулзой.

function toArray(obj) {
    var array = [];
    for (var i = 0; obj.length && i < obj.length; i++)
      array[i] = obj[i];
    return array;
  }

  function setReadOnly(){
    var item = document.getElementsByTagName('input');
    var el, els = toArray(document.getElementsByTagName('input')).concat(
                      toArray(document.getElementsByTagName('textarea')));
   for(el in els)
     if(els[el].readOnly && typeof(els[el].className) != "undefined")
       els[el].className += ' readonly';
   }

среда, 12 октября 2011 г.

JavaScript: Переменное количество аргументов у функции

Внутри каждой функции JavaScript доступен массив arguments, в котором лежат все переданные аргументы. Это позволяет, например, посчитать среднее арифметическое для любого числа аргументов.

Пишем:

var digitRegEx=/^-?\d+([,\.]\d+)?$/g;

function arithmeticMean() {
  if (!arguments.length)
    return 0;
  var finalSum = 0;
  for (var i = 0; i < arguments.length; i++)
    if (digitRegEx.test(arguments[i]))
      finalSum += parseFloat(arguments[i]);
  return (arguments.length) ? finalSum / arguments.length : 0;
}

Считаем:

alert(arithmeticMean(1, 2, 3, 4, '5', 'this param is counted as 0');

А вот делать digitRegEx.compile() - не надо. В Opera 11 откомпилированные RegExp перестают работать.