20 октября 2012 г.

Одна интересная особенность innerHTML в Internet Explorer

Была замечена интересная особенность работы innerHTML в IE. Ниже приведен код страницы с двумя блоками, каждый из которых содержит по таблице. Скрипт получает ссылки на таблицы. Теперь, если удалить таблицы из DOM, они останутся в памяти, поскольку в коде есть на них актуальные ссылки. Так и делаем. Только первую таблицу удаляем очисткой innerHTML родительского узла, а вторую - с помощью метода removeChild.

Проверяем. Со ссылками, естественно, все в порядке, только в IE первая таблица лишилась своего содержимого. Остался только элемент TABLE.

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

Это касается любых элементов, а не только таблиц. Эту особенность я наблюдал в 6, 7 и 9 версиях. Восьмой версии просто нет под рукой.

<div id="block_1">
    <table id="table_1">
        <tr>
            <td>Эту таблицу мы удалим, просто очистив innerHTML родительского объекта.</td>
        <tr>
    </table>
</div>
<div id="block_2">
    <table id="table_2">
        <tr>
            <td>Эту таблицу мы удалим с помощью метода removeChild.</td>
        <tr>
    </table>
</div>

<script type="text/javascript">
    var table_1 = document.getElementById('table_1');
    var table_2 = document.getElementById('table_2');
    var block_1 = document.getElementById('block_1');
    var block_2 = document.getElementById('block_2');
    
    
    block_1.innerHTML = '';
    block_2.removeChild(table_2);
    
    alert(table_1);
    alert(table_2);
    alert(table_1.innerHTML);
    alert(table_2.innerHTML);
</script>

11 октября 2012 г.

Почему не работает call_user_func_array

В документации по call_user_func_array есть два интересующих нас момента:
  •  "[call_user_func_array] Возвращает результат функции или FALSE в случае ошибки." 
  • "Передача параметра функции по значению при ожидаемой передаче по ссылке вызовет предупреждение и заставит call_user_func() вернуть FALSE..." 
На практике PHP (5.3.4) таки выдает предупреждение ("PHP Warning: Parameter 4 to JHTMLMenu::treerecurse() expected to be a reference, value given in /htdocs/libraries/joomla/html/html.php on line 87"), callback-функция действительно не выполняется, но call_user_func_array возвращает NULL, вместо обещанного FALSE. Ради справедливости отмечу, что тут мы получаем предупреждение, а не ошибку.

Пример из Joomla 1.5.7. Тут решается двумя разными способами: 1) делаем все элементы массива ссылками
<?php
if (strnatcmp(phpversion(),'5.3') >= 0)
{
    foreach($args as $key => $value)
    {
        $refs[$key] = &$args[$key];
    }
}
?>

или сам массив $args передаем по ссылке
<?php
call_user_func_array( array( $className, $func ), &$args );
?>