четверг, 16 июня 2011 г.

PNG в IE fadeOut и fadeIn

Суть проблемы: при использовании функции fadeOut/fadeIn для png картинки в IE появляются вокруг картинки черные пятна.

Пример кода:

<html>
<head>
<script type="text/javascript" src="jquery-1.6.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#all").click( function() {
$("#all").fadeOut(1000);
});
});
</script>
</head>
<body>
<img src="images/all.png" id="all" />
</body>
</html>


Очень долго рылся в интернете, но всё же нашел решение. Все пишут про фильтры, но лично у меня сработало только это решение (IE6 / IE7 / IE8 - по IETester)


<html>
<head>
<script type="text/javascript" src="jquery-1.6.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
var i;
for (i in document.images) {
    if (document.images[i].src) {
        var imgSrc = document.images[i].src;
        if (imgSrc.substr(imgSrc.length-4) === '.png' || imgSrc.substr(imgSrc.length-4) === '.PNG') {
            document.images[i].style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled='true',sizingMethod='crop',src='" + imgSrc + "')";
        }
    }
}
$("#all").click( function() {


$("#all").fadeOut(1000);
});
});
</script>
</head>
<body>
<div id="all"><img src="images/all.png" id="all" /></div>
</body>
</html>

среда, 15 июня 2011 г.

PNG в IE Элегантное решение без заморочек


script.js:

function fixPNG(element){
if(/MSIE (5\.5|6).+Win/.test(navigator.userAgent)){
var src;
if(element.tagName=='IMG'){
if (/\.png$/.test(element.src)){
src = element.src;
element.src = "/images/spacer.gif";
}
}
else {
src = element.currentStyle.backgroundImage.match(/url\("(.+\.png)"\)/i)
if(src){
src = src[1];
element.runtimeStyle.backgroundImage="none";
}
}
if(src){
element.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + src + "',sizingMethod='scale')";
}
}
}

html:
<!--[if lt IE 7]>
<script type="text/javascript" src="/fixpng.js"></script>
<style type="text/css">
.iePNG, img { filter:expression(fixPNG(this)); }
.iePNG a { position: relative; }
</style>
<![endif]-->

вторник, 14 июня 2011 г.

Безопасность БД Joomla

Замена mysql_real_escape_string:

string getEscaped ( $text ) - экранирует символы для добавления в базу данных
string Quote ( $text ) - тоже что и getEscaped, только ещё строка обрамляется одинарными кавычками

Это методы объекта класса JDatabase

используются так (в модели): 
                $db = &$this->getDBO();
$query = 'INSERT INTO blabla VALUES('.$db->Quote($name).','.$db->Quote($description).');';

Данные вставляются именно так. Перед выводом на экран не забываем htmlspecialchars();

Прокладка маршрута Google Maps на javascript

Добрый день, уважаемый читатель. Заказали у меня скрипт для прокладки маршрута на карте, расчёта расстояний между городами. Первое, на что наткнулся: http://habrahabr.ru/blogs/webdev/110460/ Тут рассказывается о том, как подключить карту на страницу, расставить пины на ней. Был у меня опыт работы с такой фичей на айфоне, а тут мы будем писать полностью рабочее JavaScript решение (без серверной стороны!). Итак, создаём файл map.html и пишем туда обычные для любого html документа строки, сразу подключаем jquery (оно на по-любому где-нибудь понадоибится).

Статья написана не до конца (т.к. маршрут на Google Maps по России не прокладывается)


<html>
<head>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&language=ru"></script>
<script type="text/javascript" src="jquery-1.6.1.min.js"></script>
<style type="text/css">
#map_canvas
{
width:400px;
height:300px;
}
</style>
<script type="text/javascript">
$(document).ready(function() {
    var myLatlng = new google.maps.LatLng(-34.397, 150.644);
    var myOptions = {
        zoom: 8,
        center: myLatlng,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
width:"200px"
    }


    var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
});
</script>
</head>
<body>
<div id="map_canvas"></div>
</body>
</html>


Этот код выведет у вас на странице карту (на разные файлы стили и javascript не разношу для удобства написания статьи). Далее нам нужно понять как проложить маршрут между двумя точками. Хоть и достаточно сложно найти нужные статьи в интернете, но благо гуглу и его отличной документации: Directions Requests . Из документации мы берём функцию
function calcRoute()

  var start = document.getElementById("start").value;
  var end = document.getElementById("end").value;
  var request = {
    origin:start,
    destination:end,
    travelMode: google.maps.TravelMode.DRIVING
  };
  directionsService.route(request, function(result, status) {
    if (status == google.maps.DirectionsStatus.OK) {
      directionsDisplay.setDirections(result);
    }
  });
}

Т.е. гугл даёт нам вполне удобный фреймворк для работы с его картой. Нам достаточно придать переменный start и end нужный вид (название города или координаты точки) и указать каким образом мы будем передвигаться (travelMode : DRIVING, WALKING, BICYCLING (велосипеды на момент написания статьи поддерживаются только в US)), после чего наш маршрут проложен и останется получить лишь необходимые нам данные: через какие города проходит маршрут, расстояние между каждым населёнными пунктами и полное расстояние между городами, а для этого нам нужно будет использовать Distance Matrix API. Но сначала разберёмся как нам правильно проложить маршрут между двумя нашими городами (например, Москва и Париж).

Используем Geocoding API. Для того, чтобы получить  координаты города нам нужно послать обычный GET-запрос: http://maps.google.com/maps/geo?q=Москва&output=json&oe=utf8&sensor=false. Но, как мы знаем, москва есть и в Америке: http://maps.google.com/maps/geo?q=Moscow+US&output=json&oe=utf8&sensor=false . Это всё хорошо, но тут я наткнулся в документации, что это дедовские методы, а сейчас пора Google Maps V3. Вуаля, есть повод для размышлений. Открываю консоль в google chrome и начинаю писать запрос через классы.

Копаем Google Maps V3.4
http://maps.google.com/maps/api/js?sensor=false&v=3.4&language=ru


Все методы, которые были описаны выше работают, но теперь я задаюсь вопросом: как продвинутые пользователи работают с картами. Для начала мы начнём с геокодирования. Есть класс google.maps.Geocoder() который имеет один метод geocode(request:GeocoderRequest, callback:function(Array.<GeocoderResult>,GeocoderStatus)).


GeocoderRequest в свою очередь это обычная спецификация объекта (т.е. как объект должен выглядеть):

var Request = { address : "Адресс для геокодирования",
bounds : "Квадрат поиска, является объектом LatLngBounds",
language : "Желаемый язык результата",
location : "Координаты, вокруг которых искать, является объектом LatLng",
region : "Домен страны, по которой идёт поиск" } - вот и весь объект

Далее привожу описание классов из документации гугла:

google.maps.GeocoderStatus class

The status returned by the Geocoder on the completion of a call to geocode().

Constant

ConstantDescription
ERRORThere was a problem contacting the Google servers.
INVALID_REQUESTThis GeocoderRequest was invalid.
OKThe response contains a valid GeocoderResponse.
OVER_QUERY_LIMITThe webpage has gone over the requests limit in too short a period of time.
REQUEST_DENIEDThe webpage is not allowed to use the geocoder.
UNKNOWN_ERRORA geocoding request could not be processed due to a server error. The request may succeed if you try again.
ZERO_RESULTSNo result was found for this GeocoderRequest.


google.maps.GeocoderResult object specification

A single geocoder result retrieved from the geocode server. A geocode request may return multiple result objects. Note that though this result is "JSON-like," it is not strictly JSON, as it indirectly includes a LatLng object.

Properties

PropertiesTypeDescription
address_componentsArray.<GeocoderAddressComponent>An array of GeocoderAddressComponents
geometryGeocoderGeometryA GeocoderGeometry object
typesArray.<string>An array of strings denoting the type of the returned geocoded element. A type consists of a unique string identifying the geocode result. (For example, "administrative_area_level_1", "country", etc.)

google.maps.GeocoderAddressComponent object specification

A single address component within a GeocoderResult. A full address may consist of multiple address components.

Properties

PropertiesTypeDescription
long_namestringThe full text of the address component
short_namestringThe abbreviated, short text of the given address component
typesArray.<string>An array of strings denoting the type of this address component


Теперь с помощью этих классов мы можем поставить карту на нужный адрес. Пример:

var geocoder = new google.maps.Geocoder(); geocoder.geocode( { 'address': "Moscow"}, function(results, status) { if (status == google.maps.GeocoderStatus.OK) { map.setCenter(results[0].geometry.location); var marker = new google.maps.Marker({ map: map, position: results[0].geometry.location }); } else { alert("Geocode was not successful for the following reason: " + status); } });

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

var geocoder = new google.maps.Geocoder(); geocoder.geocode( { 'address': "Odessa USA"}, function(results, status) { if (status == google.maps.GeocoderStatus.OK) { for(var i = 0; i < results.length; i++) console.log(results[i].formatted_address, results[i].geometry.location.lat(), results[i].geometry.location.lng()); } else { alert("Geocode was not successful for the following reason: " + status); } });

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

Первый запрос отлично возвращает информацию о маршруте, а второй совсем не хочет.. пишет ZERO_RESULTS. В документации написано, что не может быть найден маршрут. Но на другом сайте, использующем google maps маршрут прокладывается. В чем дело, гугл? На этом пока ступор.. даже на maps.google.com не выводит маршрута.

JQuery UI и Вывод на экран
jquery тоже имеет очень хорошую документацию и прямо там я нашёл такой пример: http://jqueryui.com/demos/autocomplete/#remote-jsonp 
Это как раз то, что нужно, полностью берём  код примера и копируем себе на страницу
следующие файлы:
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/themes/base/jquery-ui.css" type="text/css" media="all" /> 
<link rel="stylesheet" href="http://static.jquery.com/ui/css/demo-docs-theme/ui.theme.css" type="text/css" media="all" /> 

и картинку можно взять отсюда