作者归档:Daniel Sun

解决Handsontable在minSpareRows, stretchH和rowHeaders开启的情况时,自动添加的新行宽度和列头宽度不一致导致表格错位的问题

Handsontable的初始化代码如下

// Define element
    var hot_populate = document.getElementById('hot_populate')

    // Initialize with options
    var hot_populate_init = new Handsontable(hot_populate, {
        data: hot_populate_data,
        startRows: 8,
        startCols: 5,
        minSpareRows: 1,
        colHeaders: true,
        rowHeaders: true,
        stretchH: 'all',
        contextMenu: true,
    });

这时,如果我们编辑表格自动生成的最后一行,就会发现只要输入的文本长度比较短,整个表格会因为当前列的宽度问题而发生错位。

经过各种搜索,我也没有发现什么好的解决方案,只能采用了一种每次在创建新行后刷新表格绘制的方法。而且实现的过程也比较绕远,不过问题最终还是解决了。如果有更好的办法,欢迎大家分享给我。

首先,打开handsontable.min.js,在文件开头加入

var mydansunFixNewColWidth = new Event('mydansunFixNewColWidth');

然后,往下查找instance.draw()

你会找到下面这行代码

n.addEventListener(window,"resize",function(){"none"!==t.instance.getSetting("stretchH")&&t.instance.draw()}),

然后把下面这行代码添加到上面那行代码的后面(注意上面那行代码最后有个逗号)

n.addEventListener(window,"mydansunFixNewColWidth",function(){"none"!==t.instance.getSetting("stretchH")&&t.instance.draw()}),

最后,我们修改之前Handsontable的初始化代码如下

// Define element
    var hot_populate = document.getElementById('hot_populate')

    // Initialize with options
    var hot_populate_init = new Handsontable(hot_populate, {
        data: hot_populate_data,
        startRows: 8,
        startCols: 5,
        minSpareRows: 1,
        colHeaders: true,
        rowHeaders: true,
        stretchH: 'all',
        contextMenu: true,
        afterCreateRow:function(index,amount){
            var instance = hot_populate_init;
            if(instance !== undefined){
                window.dispatchEvent(mydansunFixNewColWidth);
            }
            
        },
    });

再返回我们的页面,刷新。现在添加的新行已经可以拥有正确的宽度了,错位的问题也得到了解决。

用js解决bootstrap的列col在重新在新的一行排列时,会受到上一行列col高度影响的问题

我们经常遇到这种情况,当我们在一行(row)中放置多个列(col)的时候,新起一行的列因为上面一行有一列超高,位置发生了移动。

bootstrap官方的解决方法是在每一行的末尾,插入下面的div用来清除浮动

http://v3.bootcss.com/css/#grid-responsive-resets

<div class="clearfix visible-xs-block"></div>

其中,visible-xs-block 是可以改变的,改变成你每个列用的栅格种类,比如你所有的栅格用的是col-lg-4 (如上图),你就需要改成visible-xs-block

但是这样,我们需要对每一行都做处理,这不适合下面两种情况

  1. 如果每一列是由程序(比如PHP)自动生成的,没办法手动添加
  2. 每一列用了多种栅格,比如col-md-6 col-lg-4 ,手动很麻烦

下面我编写了一个js来快速解决这个问题,首先我们把所有需要处理的栅格都加上col-split 的class,然后把下面的js代码放在合适的位置让他能够执行即可。

$(".col-split").each(function(index, el) {
        var $this = $(this);
        var $parent = $this.parent('.row');
        if($parent.data("colSplit") === true){
            return;
        }
        $parent.data("colSplit",true);
        var classes = $this.attr("class");
        var exp = new RegExp(/col-([a-zA-Z]{2})-(\d+)/,"g");
        var result;
        while ((result = exp.exec(classes)) != null){
            var visible = "visible-" + result[1] + "-block";
            var width = parseInt(12 / parseInt(result[2]));
            $parent.children('.col-split').each(function(index, el) {
                var $item = $(this);
                var number = index + 1;
                if(number % width == 0){
                    $item.after('<div class="clearfix ' + visible + '">');
                }
            });
        }
    });

添加代码完成后,刷新页面,我们想要的样子就出现了。

上面的js代码支持使用多种栅格的列,比如col-md-6 col-lg-4 ,他会在合适的位置自动插入,效果如图

在mac上使用vmbox映射本地目录开发laravel时,解决storage目录Permission denied的问题

我目前使用vmbox中的ubuntu虚拟机共享代码目录来开发laravel,在这期间遇到一个古怪的问题,就是发现storage目录下面的一些文件虚拟机里的php-fpm貌似没有权限(Permission denied),包括但不限于storage/app,storage/logs等。

而当我在mac中把这些目录的权限改为777后发现并不能解决问题。其中在storage/framework/cache中,php-fpm的确拥有了在这个目录创建二级目录的权限,但是貌似在他自己创建的目录中,php-fpm又并没有w权限了。

后来登录到ubuntu中测试发现,php-fpm在cache文件夹创建了缓存索引文件夹,所有者居然是root的,而且的确没有其他人的w权限。后来又经过其他测试我发现,在vmbox的共享目录中,无论你在虚拟机里使用哪个用户创建什么文件,它的所有者都是root:root,权限也都如下图所示。

后来这个问题用了很多方法,包括mac这边设置用户组,ubuntu设置用户组,但都没有很好的解决。后来想了一个终极办法,就是让php-fpm以root的权限运行。解决方案参考:https://onlyke.com/html/883.html

让php-fpm以root的权限运行

注意,本方法仅用于开发环境来解决一些奇怪问题或者方便使用,请勿在生产环境让php-fpm以root身份运行,否则一切后果自负。

  1. 编辑/etc/php/7.0/fpm/pool.d/www.conf,把user和group修改为root
    ; Unix user/group of processes 
    ; Note: The user is mandatory. If the group is not set, the default user's group ; will be used. 
    user = root 
    group = root
    
  2. 编辑/lib/systemd/system/php7.0-fpm.service,在ExecStart的–nodaemonize前面加上–allow-to-run-as-root,就像下面这样
    ExecStart=/usr/sbin/php-fpm7.0 --allow-to-run-as-root --nodaemonize...
  3. 执行命令
    systemctl daemon-reload
  4. 重启php-fpm即可
    service php7.0-fpm restart
  5. 最后,可以通过ps命令来查看效果
    ps auwx | grep php

    可以看到,php-fpm已经以root身份运行了。

Chrome 49低版本或者其他浏览器访问HTTP2网站出现ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY

问题跟我想的一样,是因为加密的方式被拒绝导致的

解决方式,在nginx.conf中设置

ssl_protocols               TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers                 EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers   on;

这个是CloudFlare 使用的配置

参考下面的文章

https://imququ.com/post/why-tls-handshake-failed-with-http2-enabled.html

Nginx+PHP-fpm中开启日志,error_log的有关问题

要保障PHP在error_log中输出日志,要确保以下设置为正确的值

php.ini中

; Common Values:
;   E_ALL (Show all errors, warnings and notices including coding standards.)
;   E_ALL & ~E_NOTICE  (Show all errors, except for notices)
;   E_ALL & ~E_NOTICE & ~E_STRICT  (Show all errors, except for notices and coding standards warnings.)
;   E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR  (Show only errors)
; Default Value: E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
; Development Value: E_ALL
; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT
; http://php.net/error-reporting
error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT

...

; Besides displaying errors, PHP can also log errors to locations such as a
; server-specific log, STDERR, or a location specified by the error_log
; directive found below. While errors should not be displayed on productions
; servers they should still be monitored and logging is a great way to do that.
; Default Value: Off
; Development Value: On
; Production Value: On
; http://php.net/log-errors
log_errors = On

php-fpm.conf中error_log覆盖了php.ini中的设置

; Error log file
; If it's set to "syslog", log is sent to syslogd instead of being written
; in a local file.
; Note: the default prefix is /var
; Default Value: log/php-fpm.log
error_log = /var/log/php7.0-fpm.log

pool.d/www.conf中,确保开启输出(非常重要)

; Redirect worker stdout and stderr into main error log. If not set, stdout and
; stderr will be redirected to /dev/null according to FastCGI specs.
; Note: on highloaded environement, this can cause some delay in the page
; process time (several ms).
; Default Value: no
catch_workers_output = yes