JavaScript: отслеживание клика вне элемента

Задача: отследить клик вне элемента div.

Решение: для этого навесим событие на клик вышестоящего элемента, и при клике анализируем, то на чём кликнули «внутри» или «снаружи»:

Например:

html:

<div class="el1">
   <div class="el2"></div>
   <div class="el3"></div>
   <div class="el4"></div>
   <div class="el5"></div>



</div>

javascript:

$(".el1" ).bind( "click", function(e) {
                        if ( $(e.target).closest('.el4').length ) {
                            console.log("внутри");
                        return;
                        };
                        console.log("снаружи");  
                   });

Memcached: Server localhost (tcp 11211, udp 0) failed with: Network timeout

И снова поймал ту-же ошибку — воспроизводится при получении ранее не сохраненного в текущей сессии php значения get. Например:

$memcached = new Memcache();
$memcached->addServer('localhost', 11211);
echo $memcached->get('key')."\n";

Исправить не смог, на текущий момент припер «костылем»:

$memcached = new Memcache();
$memcached->addServer('localhost', 11211);
$rr=$memcached->getVersion();
echo $memcached->get('key')."\n";

Да! Я сам в шоке, проблема решается вставкой ПЕРЕД get, не нужного getVersion

UPDATE: проблема была в банальной не хватке места на ЖД

Плодятся зомби процессы defunct при вызове posix_kill

Проблема: есть некий трудоёмкий процесс в скрипте PHP, который вынесен из родительского потока.При завершении его, при помощи posix_kill, остается зомби процесс. Код вида:

                   $child_pid = pcntl_fork();
                   if (($child_pid==0) or ($child_pid==-1)){ // -1 если дочерний процесс стартовать не удалось

//здесь много грузящей процессор работы

                    PutLog(messageslogfile, BOn."--завершил дочерний процесс", true);    
                    if ($child_pid!=-1){ posix_kill(posix_getpid(), SIGKILL);}; // если продолжаем в основном потоке, то и кончаем его                    
                   } else {                       
                        PutLog(messageslogfile, BOn."--стартовал дочерний процесс", true);    
                   };                    

Проблема возникает из за того, что нам нужно как-то отчитаться в главный процесс, что дочерний процесс завершен, и только тогда ОС поймёт, что зомби можно убирать. Классически для этого используют pcntl_wait, но рабочих примеров найти не смог.

Решение: объявим, что нам собственно всё равно что происходит с «детьми»:

pcntl_signal(SIGCHLD, SIG_IGN);

После этого зомби-процессы плодиться перестают

Memcached: MemcachePool::get(): Server localhost (tcp 11211, udp 0) failed with: Network timeout

После очередной перезагрузки сервера, при работе с memcached из PHP стали валиться ошибки вида:


MemcachePool::get(): Server localhost (tcp 11211, udp 0) failed with: Network timeout

Решение: перевел memcached в режим debug и увидиел, что не может создать папку /var/run/memcached.socket (premission denied). Для того чтобы мог сам создавать, в /etc/memcached.conf добавил возможность запуска сервиса из под root:

-u root

Datatables.net: субгриды для таблицы

Задача: при щелчке по одной из ячеек, разворачивать «subgrid» для таблицы. Примерно так:

Решение:

<table id="ownersgrid" class="display" style="width:100%">
        <thead>
            <tr>                
                <th>#</th>
                <th></th>
                <th>Наименование</th>
                <th>Полное наименование</th>
                <th>Телефон</th>    
                <th>Email</th> 
                <th>Договора</th>
            </tr>
        </thead>
</table>

<script>
 ownerstable=$('#ownersgrid').DataTable( {
        dom: 'frtipB',
        destroy: true,
        select: true,
        lengthMenu: [
            [ 10, 25, 50, -1 ],
            [ '10 строк', '25 строк', '50 строк', 'Все строки' ]
        ],
        buttons: [            
            {
            text: 'Редактировать',
                action: function ( e, dt, node, config ) {
                  ConnectorEdit("edit");  
                }
            },
            {
            text: 'Добавить',
                action: function ( e, dt, node, config ) {
                  ConnectorEdit("add");  
                }
            },
            
            'excel','print','pageLength',
        ],        
         paging: true,
         keys: true,
         //scrollY:        400,
        //scrollCollapse: true,
        //scroller:       true,         
        "processing": true,
        "serverSide": true,
        "ajax": {
            "url": "/server/owners/OwnersGrid",
            "type": "POST",
            "data": {               
            }
        },
    "language": {
             url: '/js/i18n/datatable.json'
        },        
    "columns": [                    
            { "data": "id"},
            { "data": "deleted" },
            { "data": "name"},
            { "data": "full_name" },
            { "data": "phone" },
            { "data": "email" },
            { className: 'dt-control',orderable: false,data: null,defaultContent: '',width: '10%'},
        ]        
    } );
    $('#ownersgrid').unbind();
    $('#ownersgrid').on('dblclick', 'tbody td', function () {        
         OwnerEdit("edit");
    }); 
    $('#ownersgrid tbody').on('click', 'td.dt-control', function () {
        var tr = $(this).closest('tr');
        var row = ownerstable.row( tr );

        if ( row.child.isShown() ) {
            // This row is already open - close it
            destroyChild(row);
            tr.removeClass('shown');
        }
        else {
            // Open this row
            createChild(row);
            tr.addClass('shown');
        }
    } );    
function createChild ( row ) {
    // This is the table we'll convert into a DataTable
    var table = $('<table class="display" style="width:100%">'+
        '<thead>'+
        '    <tr>                '+
        '        <th>#</th>'+
        '        <th></th>'+
        '        <th>Наименование</th>'+
        '        <th>Полное наименование</th>'+
        '        <th>Телефон</th>    '+
        '        <th>Email</th> '+
        '        <th>Договора</th>'+
        '    </tr>'+
       ' </thead>'+
    '</table>');


    // Display it the child row
    row.child( table ).show();
 
    // Initialise as a DataTable
    var usersTable = table.DataTable( {
       dom: 't',
        destroy: true,
        select: true,
        lengthMenu: [
            [ 10, 25, 50, -1 ],
            [ '10 строк', '25 строк', '50 строк', 'Все строки' ]
        ],
        buttons: [            
            {
            text: 'Редактировать',
                action: function ( e, dt, node, config ) {
                  ConnectorEdit("edit");  
                }
            },
            {
            text: 'Добавить',
                action: function ( e, dt, node, config ) {
                  ConnectorEdit("add");  
                }
            },
            
            'excel','print','pageLength',
        ],        
         paging: true,
         keys: true,
         //scrollY:        400,
        //scrollCollapse: true,
        //scroller:       true,         
        "processing": true,
        "serverSide": true,
        "ajax": {
            "url": "/server/owners/OwnersGrid",
            "type": "POST",
            "data": {               
            }
        },
    "language": {
             url: '/js/i18n/datatable.json'
        },        
    "columns": [                    
            { "data": "id"},
            { "data": "deleted" },
            { "data": "name"},
            { "data": "full_name" },
            { "data": "phone" },
            { "data": "email" },
            { className: 'dt-control',orderable: false,data: null,defaultContent: '',width: '10%'},
        ]        
    } );
};
function destroyChild(row) {
    var table = $("table", row.child());
    table.detach();
    table.DataTable().destroy();
 
    // And then hide the row
    row.child.hide();
}
</script>
1 78 79 80 81 82 308