<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[qiuz]]></title><description><![CDATA[Life is need to record.]]></description><link>https://qiuz.site/</link><image><url>https://qiuz.site/favicon.png</url><title>qiuz</title><link>https://qiuz.site/</link></image><generator>Ghost 3.0</generator><lastBuildDate>Tue, 07 Apr 2026 21:01:13 GMT</lastBuildDate><atom:link href="https://qiuz.site/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[利用Docker搭建Ghost博客，一次搭建多处部署]]></title><description><![CDATA[<!--kg-card-begin: markdown--><blockquote>
<p>由于这几年服务器一直在换，导致每次到了服务器到期的时候就很痛苦，要重新搭建服务器环境部署自己的博客，作为前端er一直没想到docker，知道上次问了大佬才知道docker完全可以做到搭建了一次后，多处部署，这里记录下搭建过程吧。<br>
虽然网上有很多教程，但是自己搭建的时候还是遇到很多坑，还是有必要记录下。</p>
</blockquote>
<h4 id="docker">Docker文件目录</h4>
<p><img src="https://qiuz.site/content/images/2019/11/705BE40B-8323-4DF7-9A5F-477FE5074F81.png" alt="705BE40B-8323-4DF7-9A5F-477FE5074F81"></p>
<h4 id="docker">安装Docker</h4>
<p>网上教程很多的，这里贴下我安装时看的文章<br>
<a href="https://www.jianshu.com/p/94760f35c98c">Centos7 安装docker以及docker-compose</a><br>
<a href="https://www.jianshu.com/p/3b7d47a8b891">centos7安装docker</a></p>
<p>这里安装<code>docker-compose</code>直接用yum就可以了</p>
<pre><code class="language-bash">    yum -y install docker-compose
</code></pre>
<p>安装完后需要更换下国内镜像,我用的是<a href="https://www.daocloud.io/mirror">daocloud</a>这里不要用这里的Linux脚本<br>
<img src="http://qiuz.me/content/images/2019/09/D97465FE-E329-4146-B2D3-4B070269D663.png" alt="D97465FE-E329-4146-B2D3-4B070269D663">，它的脚本会多加一个逗号，直接获取到地址，自己去添加就好了</p>
<pre><code class="language-bash">vi  /etc/docker/daemon.json
</code></pre>
<pre><code class="language-bash">{
        &quot;registry-mirrors&quot;: [&quot;http://f1361db2.m.daocloud.io&quot;]
}
</code></pre>
<h4 id="dockercompose">Docker-compose启动文件</h4>
<p><code>docker-compose.yml</code></p>
<pre><code class="language-yml">version:</code></pre>]]></description><link>https://qiuz.site/li-yong-dockerda-jian-ghostbo-ke-yi-ci-da-jian-duo-chu-bu-shu/</link><guid isPermaLink="false">5d91fe3a84af13000169dd92</guid><category><![CDATA[Tinker]]></category><dc:creator><![CDATA[qiuz]]></dc:creator><pubDate>Tue, 01 Oct 2019 01:35:08 GMT</pubDate><media:content url="https://qiuz.site/content/images/2019/10/562693.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><blockquote>
<img src="https://qiuz.site/content/images/2019/10/562693.jpg" alt="利用Docker搭建Ghost博客，一次搭建多处部署"><p>由于这几年服务器一直在换，导致每次到了服务器到期的时候就很痛苦，要重新搭建服务器环境部署自己的博客，作为前端er一直没想到docker，知道上次问了大佬才知道docker完全可以做到搭建了一次后，多处部署，这里记录下搭建过程吧。<br>
虽然网上有很多教程，但是自己搭建的时候还是遇到很多坑，还是有必要记录下。</p>
</blockquote>
<h4 id="docker">Docker文件目录</h4>
<p><img src="https://qiuz.site/content/images/2019/11/705BE40B-8323-4DF7-9A5F-477FE5074F81.png" alt="利用Docker搭建Ghost博客，一次搭建多处部署"></p>
<h4 id="docker">安装Docker</h4>
<p>网上教程很多的，这里贴下我安装时看的文章<br>
<a href="https://www.jianshu.com/p/94760f35c98c">Centos7 安装docker以及docker-compose</a><br>
<a href="https://www.jianshu.com/p/3b7d47a8b891">centos7安装docker</a></p>
<p>这里安装<code>docker-compose</code>直接用yum就可以了</p>
<pre><code class="language-bash">    yum -y install docker-compose
</code></pre>
<p>安装完后需要更换下国内镜像,我用的是<a href="https://www.daocloud.io/mirror">daocloud</a>这里不要用这里的Linux脚本<br>
<img src="http://qiuz.me/content/images/2019/09/D97465FE-E329-4146-B2D3-4B070269D663.png" alt="利用Docker搭建Ghost博客，一次搭建多处部署">，它的脚本会多加一个逗号，直接获取到地址，自己去添加就好了</p>
<pre><code class="language-bash">vi  /etc/docker/daemon.json
</code></pre>
<pre><code class="language-bash">{
        &quot;registry-mirrors&quot;: [&quot;http://f1361db2.m.daocloud.io&quot;]
}
</code></pre>
<h4 id="dockercompose">Docker-compose启动文件</h4>
<p><code>docker-compose.yml</code></p>
<pre><code class="language-yml">version: '2'

services:
  nginx:
    tty: true
    image: nginx:stable-alpine
    restart: always
    volumes:
      - ./${NGINX_DIR}/conf/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./${NGINX_DIR}/conf/conf.d:/etc/nginx/conf.d
      - ./${NGINX_DIR}/www:/usr/share/nginx/html
      - ./${NGINX_DIR}/log:/var/log/nginx
      - ./${NGINX_DIR}/.acme.sh:/etc/nginx/.acme.sh
    ports:
      - &quot;80:80&quot;
      - &quot;443:443&quot;
    depends_on:
      - ghost
    links:
      - ghost
  mysql-db:
    container_name: mysql-docker        # 指定容器的名称
    image: mysql:5.6                   # 指定镜像和版本
    ports:
      - &quot;3306:3306&quot;
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_ROOT_HOST: ${MYSQL_ROOT_HOST}
      MYSQL_USER: 'ghost'
      MYSQL_PASS: 'ghost_password'
    volumes:
      - &quot;${MYSQL_DIR}/data:/var/lib/mysql&quot;           # 挂载数据目录
      - &quot;${MYSQL_DIR}/conf:/etc/mysql/conf.d&quot;      # 挂载配置文件目录
  ghost:
    image: ghost
    restart: always
    depends_on:
      - mysql-db
    links:
      - mysql-db
    ports:
      - 2368:2368
    volumes:
      - ./${GHOST_DIR}/content:/var/lib/ghost/content
      - ./${GHOST_DIR}/config.production.json:/var/lib/ghost/config.production.json
    environment:
      - NODE_ENV=production

</code></pre>
<p>这里变量通过<code>.env</code>定义的，在<code>docker-compose.yml</code>同级目录下执行</p>
<pre><code class="language-sh">vim .env
</code></pre>
<pre><code class="language-.env">MYSQL_ROOT_PASSWORD=root
MYSQL_ROOT_HOST=%
MYSQL_DIR=./mysql
NGINX_DIR=./nginx
GHOST_DIR=./ghost
</code></pre>
<p><strong>注意：</strong><br>
<strong>这里mysql端口为默认的，如果正式部署的话最好换成别的端口，不要用默认的，且root密码最好不要太简单以及关闭root远程连接权限，我这次还没部署完成，数据库就被黑了，幸好数据都有备份的</strong></p>
<p><img src="https://qiuz.site/content/images/2019/11/WechatIMG884.png" alt="利用Docker搭建Ghost博客，一次搭建多处部署"></p>
<h4 id="ghost">Ghost配置</h4>
<p>这里将<code>ghost</code>的<code>content</code>和<code>config.production.json</code>使用数据卷的方式，这样后面迁移的时候只要将文件拷贝过去，主题和配置都是在的<br>
配置文件如下：</p>
<pre><code class="language-js">{
    &quot;url&quot;: &quot;http://service_name&quot;,
    &quot;server&quot;: {
        &quot;port&quot;: 2368,
        &quot;host&quot;: &quot;0.0.0.0&quot;
    },
    &quot;database&quot;: {
        &quot;client&quot;: &quot;mysql&quot;,
        &quot;connection&quot;: {
            &quot;host&quot;: &quot;mysql-db&quot;,
            &quot;user&quot;: &quot;ghost&quot;,
            &quot;password&quot;: &quot;ghost_password&quot;,
            &quot;database&quot;: &quot;ghost&quot;,
            &quot;port&quot;: 3306,
            &quot;charset&quot;: &quot;utf8&quot;
        }
    },
    &quot;mail&quot;: {
        &quot;transport&quot;: &quot;Direct&quot;
    },
    &quot;logging&quot;: {
        &quot;transports&quot;: [
            &quot;file&quot;,
            &quot;stdout&quot;
        ]
    },
    &quot;process&quot;: &quot;systemd&quot;,
    &quot;paths&quot;: {
        &quot;contentPath&quot;: &quot;/var/lib/ghost/content&quot;
    }
}
</code></pre>
<h4 id="nginx">nginx配置</h4>
<p>监听80端口，转发到2368端口</p>
<pre><code class="language-conf">location / {
    proxy_pass http://ghost:2368;
}
</code></pre>
<p>这里因为nginx是一个容器，代理到ghost容器，这里是ghost，而不是localhost</p>
<h4 id>部署</h4>
<pre><code class="language-sh">docker-compose up -d
</code></pre>
<h4 id="end">END</h4>
<p>其实自己搭建的过程中遇到了很多问题，但是在记录时已经忘记了，望天~</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[前端多项目自动构建]]></title><description><![CDATA[<!--kg-card-begin: html--><blockquote>
  <p>Webhook 允许我们通过在Github.com订阅事件后构建后或者安装Github应用。当其中之一的事件被触发时，我们可以发送HTTP POST请求到webhook的配置URL。Webhook可以用作升级一个issue追踪，触发CI构建，升级一个后端镜像，或者甚至是部署你的生产服务器。只有想不到，没有做不到。</p>
  
  <p>这里有一个常见的例子：你到github上。有一个用于他们代码POST请求webhook的文本框。你输入一个URL。现在当你上传你的代码到github上时，github将会通过HTTP POST的方法请求你所选择的包含详细信息的URL。没有更简单的方法以便与任意Web服务进行开放式集成。</p>
</blockquote>

<p>作为国内的github——gitee.com，当然也是支持webhooks的。
<a href="https://gitee.com/help/categories/40">gitee webhooks文档</a></p>

<h4 id>基础支持</h4>

<ol>
<li>需要一台外网能访问的服务器  </li>
<li>需要项目仓库的管理员权限</li>
</ol>

<p>对于第一点来说，由于我这边是用公司的测试服务器，对外只开放了443端口，只能在443端口配置nginx，转发/webhoos请求到本地webhooks端口。</p>

<pre><code class="language-shell">   location ^~ /webhooks {
        proxy_pass http://localhost:8080;
   }
</code></pre>

<h4 id="webhooks">webhooks配置</h4>

<p>按照gitee文档配置好webhooks,服务器上需要起一个Node服务，监听8080端口
这里直接用了<a href="https://www.jianshu.com/p/caa541590d48">gitee码云使用webhook</a>这篇文章里的代码</p>

<pre><code class="language-js">var</code></pre>]]></description><link>https://qiuz.site/qian-duan-duo-xiang-mu-zi-dong-gou-jian/</link><guid isPermaLink="false">5d8e2619dd59f70001a55dcc</guid><category><![CDATA[FrontEnd]]></category><dc:creator><![CDATA[qiuz]]></dc:creator><pubDate>Thu, 14 Mar 2019 15:09:13 GMT</pubDate><media:content url="https://qiuz.site/content/images/2019/09/175866.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: html--><blockquote>
  <img src="https://qiuz.site/content/images/2019/09/175866.jpg" alt="前端多项目自动构建"><p>Webhook 允许我们通过在Github.com订阅事件后构建后或者安装Github应用。当其中之一的事件被触发时，我们可以发送HTTP POST请求到webhook的配置URL。Webhook可以用作升级一个issue追踪，触发CI构建，升级一个后端镜像，或者甚至是部署你的生产服务器。只有想不到，没有做不到。</p>
  
  <p>这里有一个常见的例子：你到github上。有一个用于他们代码POST请求webhook的文本框。你输入一个URL。现在当你上传你的代码到github上时，github将会通过HTTP POST的方法请求你所选择的包含详细信息的URL。没有更简单的方法以便与任意Web服务进行开放式集成。</p>
</blockquote>

<p>作为国内的github——gitee.com，当然也是支持webhooks的。
<a href="https://gitee.com/help/categories/40">gitee webhooks文档</a></p>

<h4 id>基础支持</h4>

<ol>
<li>需要一台外网能访问的服务器  </li>
<li>需要项目仓库的管理员权限</li>
</ol>

<p>对于第一点来说，由于我这边是用公司的测试服务器，对外只开放了443端口，只能在443端口配置nginx，转发/webhoos请求到本地webhooks端口。</p>

<pre><code class="language-shell">   location ^~ /webhooks {
        proxy_pass http://localhost:8080;
   }
</code></pre>

<h4 id="webhooks">webhooks配置</h4>

<p>按照gitee文档配置好webhooks,服务器上需要起一个Node服务，监听8080端口
这里直接用了<a href="https://www.jianshu.com/p/caa541590d48">gitee码云使用webhook</a>这篇文章里的代码</p>

<pre><code class="language-js">var http = require('http')  
var createHandler = require('gitee-webhook-handler')  
var handler = createHandler({ path: '/webhooks', secret: '123456' })// post 所需要用到的秘钥

function run_cmd(cmd, args, callback) {  
  var spawn = require('child_process').spawn;
  var child = spawn(cmd, args);
  var resp = "";
  child.stdout.on('data', function(buffer) { resp += buffer.toString(); });
  child.stdout.on('end', function() { callback (resp) });
}
handler.on('error', function (err) {  
  console.error('Error:', err.message)
})
handler.on('Push Hook', function (event) {  // 这个地方就是GitHub 和 Gitee 不一样的地方，需要注意  
        if (event.payload.ref === 'refs/heads/deploy') {
        run_cmd('bash', ['./deploy.sh', 'deploy', event.payload.repository.path], function(text){ console.log(text) });// 需要执行的脚本位置
        }
})

try {  
  http.createServer(function (req, res) {
    handler(req, res, function (err) {
      res.statusCode = 404
      res.end('no such location')
    })
  }).listen(8089) // 服务监听的端口，可以自行修改
}catch(err){
  console.error('Error:', err.message)
}
</code></pre>

<p>可以看到，这里我是使用特定分支<code>deploy</code>来作为是否自动构建的判断。</p>

<p>另外使用spawn命令时，args是以数组形式，例如直接执行shell脚本命令是</p>

<pre><code class="language-shell"> ./deploy.sh deploy my-app
</code></pre>

<p>使用spwan时要这样</p>

<pre><code class="language-js"> spwan('bash', ['./deploy.sh', 'deploy', 'my-app'])
</code></pre>

<p>由于是多项目配置webhooks，所以这里路径是通过仓库信息里的<code>event.payload.repository.path</code>来区分的</p>

<h4 id>构建脚本</h4>

<p>由于是在测试服务器上自动构建，webhooks服务只是监听仓库的变化，构建是要自己编写脚本来进行构建的</p>

<p>deploy.sh  </p>

<pre><code class="language-shell">#!/bin/bash

BASE_PATH="/www"

exec 1&gt;$BASE_PATH/webhooks/$2.log 2&gt;&amp;1

cd $BASE_PATH/$2

branch=$(git branch | grep $1)

git pull

if [[ -n "$branch" ]]; then  
        # 切换到构建分支
  git checkout deploy
else  
  git checkout -b deploy origin/deploy
fi

# 拉取最新代码
git pull  
# 构建
npm run build  
</code></pre>

<p>判断当前是否在deploy分支上，不在就切换过去</p>

<p>以上，服务器端全部Ok，剩下的就是项目中的配置了</p>

<h4 id>项目发布命令</h4>

<p>在项目中新增一个publish.sh</p>

<pre><code class="language-shell">#!/bin/bash

set -e

function build_deploy() {  
    if [[ -n "$(git status --porcelain)" ]]; then
        echo "Working tree *NOT* clean. Please stash/commit your changes before any operations."
        exit 1
    fi

    current_branch="$(git symbolic-ref --short -q HEAD)"

    if [[ -n "$(git rev-parse --verify --quiet deploy)" ]]; then
        git branch -D deploy
    fi

    git checkout -b deploy

    git push -f origin deploy:deploy

    git checkout $current_branch

    git branch -D deploy

}

build_deploy <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="351175">[email&#160;protected]</a>
</code></pre>

<p>在package.json中的scripts中新增一个命令</p>

<pre><code class="language-js">    "deploy": "cross-env scripts/bash/publish.sh",
</code></pre>

<p><code>cross-env</code>这个是针对于团队中使用windows开发的</p>

<p>大概思路就是，发布时，会判断当前分支是否有变动，没有的话就从当前分支切一个本地<code>deploy</code>分支，然后强推到远程<code>deploy</code>分支，再切换回去，删除本地<code>deploy</code>分支</p>

<p>然后webhooks会监听到分支的Push,判断分支为<code>deploy</code>,执行<code>deploy.sh</code></p>

<p>完工。</p>

<p>参考：</p>

<ol>
<li><a href="https://www.jianshu.com/p/caa541590d48">gitee码云使用webhook</a>  </li>
<li><a href="https://www.jianshu.com/p/711b201e6a12">Webhooks在API世界中的角色</a>  </li>
<li><a href="https://segmentfault.com/a/1190000015437514">Webhook到底是个啥？</a></li>
</ol>
        <!--kg-card-end: html-->]]></content:encoded></item><item><title><![CDATA[记一次解决问题的弯曲历程]]></title><description><![CDATA[<!--kg-card-begin: html--><p>之前在做项目中，有一个需求是要由一个二级table，也就是table中嵌套一个table。虽然table是不能之前嵌套的，但是可以利用td里放一个div来嵌套table。需求是这个嵌套的table是可以点击展开收起，当时是直接利用了CSS3的transition属性来做的这个一个动画。</p>

<p><strong>页面主要代码：</strong></p>

<pre><code>&lt;table&gt;
    &lt;thead&gt;&lt;/thead&gt;
    &lt;tbody ng-repeat="item in items"&gt;
        &lt;tr&gt;
            &lt;td&gt;item.name&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;
                &lt;div&gt;
                    &lt;table&gt;</code></pre>]]></description><link>https://qiuz.site/ji-yi-ci-jie-jue-wen-ti-de-wan-qu-li-cheng/</link><guid isPermaLink="false">5d8dfefedd59f70001a55dbb</guid><category><![CDATA[FrontEnd]]></category><dc:creator><![CDATA[qiuz]]></dc:creator><pubDate>Mon, 26 Sep 2016 06:46:03 GMT</pubDate><media:content url="https://qiuz.site/content/images/2019/09/spacex-TV2gg2kZD1o-unsplash.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: html--><img src="https://qiuz.site/content/images/2019/09/spacex-TV2gg2kZD1o-unsplash.jpg" alt="记一次解决问题的弯曲历程"><p>之前在做项目中，有一个需求是要由一个二级table，也就是table中嵌套一个table。虽然table是不能之前嵌套的，但是可以利用td里放一个div来嵌套table。需求是这个嵌套的table是可以点击展开收起，当时是直接利用了CSS3的transition属性来做的这个一个动画。</p>

<p><strong>页面主要代码：</strong></p>

<pre><code>&lt;table&gt;
    &lt;thead&gt;&lt;/thead&gt;
    &lt;tbody ng-repeat="item in items"&gt;
        &lt;tr&gt;
            &lt;td&gt;item.name&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;
                &lt;div&gt;
                    &lt;table&gt;
                        &lt;thead&gt;&lt;/thead&gt;
                        &lt;tbody ng-repeat="color in item.colors"&gt;
                            &lt;tr&gt;
                                &lt;td&gt;color&lt;/td&gt;
                            &lt;/tr&gt;
                    &lt;/table&gt;
                &lt;/div&gt;  
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
</code></pre>

<p>将二级table增加一个<code>class</code>为<code>showOrHide</code>,将高度用<code>transition</code>设为平滑过渡的效果：</p>

<pre><code>heigth : 0;
transition:heigth .6s;
</code></pre>

<p>默认将其高度设为0，在点击后触发<code>showOrhide</code>函数：</p>

<pre><code>let display = false;
var other = document.querySelectorAll('.showOrHide');
for (var i = 0, len = other.length; i &lt; len; i++) {
    if (other[i] != ele) {
        if (parseInt(other[i].style.height) &gt; 0) {
            display = false;
            slideToggleTrans(display,other[i]);         }
    }
}
if (parseInt(ele.style.height) &gt; 0) {
    display = true;
}
display = !display;
slideToggleTrans(display,ele);
</code></pre>

<p>利用<code>display</code>变量来控制二级table的展开还是收起，同时将其他展开的收起。<code>slideToggleTrans(display,ele)</code>函数主要是一个计算二级table的高度:</p>

<pre><code>function slideToggleTrans(display,eleMore) {
 //  display表示默认更多展开元素是显示状态还是隐藏
    eleMore &amp;&amp; (eleMore.style.height = display ? (function () {
        var height = 0;
        Array.prototype.slice.call(eleMore.childNodes).forEach(function (child)                     {
                if (child.nodeType === 1) {
                    var oStyle = window.getComputedStyle(child);
                    height += child.clientHeight +  (parseInt(oStyle.borderTopWidth) || 0) + (parseInt(oStyle.borderBottomWidth) || 0);
                }
            });
        return height;
    })() + "px" : "0px");
}
</code></pre>

<p>这样一来完全是没有问题，<strong>BUT</strong>交互是有问题的。</p>

<p>因为这个二级table可不是仅仅展示，还有按钮可以编辑删除的，编辑删除后，需要读取接口获取新的数据吧，问题就是这里。因为重新获取这个<code>items</code>，获取完后页面是会重新渲染的，这就导致我修改完后，页面回到了初始状态，也就是我好辛苦在多条记录中找到的那一条记录下的二级table中多条记录中的某条数据，修改完后我需要再看一下的话，就只能花个几分钟再重新找一次了。（我是有多闲啊！）。</p>

<p>所以这就是需要解决的问题。</p>

<h3 id>下面就是花式钻牛角尖</h3>

<p><strong>首先</strong>，我不想放弃这个我好不容易写出来的工具类，所以我开始还是将目光锁定了这个工具类上。</p>

<p>既然用<code>transition</code>来控制高度的，所以我还是利用这个属性来控制二级table修改完变化的高度。这样删除某条记录，我将其从<code>item.colors</code>中<code>splice(index,1)</code>，这样<code>ng-repeat</code>会重新渲染一遍，但是其他没有改变的不会去渲染了。OK，删除解决了，那编辑和添加同样这样解决。为此，还找后端添加color接口给我返回这个新增的id了。这样一来，问题完美解决了。真是prefect！</p>

<p>重新发布后不到一个小时，问题又出现了！</p>

<ul>
<li>后端：前端你这个展开样式有问题<br></li>
<li>我：我这边没问题啊（怎么可能，老纸测的好好的，你一测就有问题，坑啊）<br></li>
<li>后端：你看这截图<br></li>
<li>我：。。。噢 我改一下（妈蛋，什么鬼数据啊）<br></li>
</ul>

<p>问题出在数据上，有一些数据内容比较大，这样就吧td的高度撑起来了，比其他的高很多，这样如果将一个高度为32px的修改后高度为58px,这样内容超出我袁先生设置的高度，部分内容不可见了。</p>

<p>一看是这个问题，so easy嘛，啪啪啪代码改好了，在修改数据后，我再调一次<code>slideToggleTrans(display,ele)</code>来计算高度不就OK了。修改后本地开始测，但是为毛我修改后计算的高度跟实际的不一样啊喂。折腾好久发现了问题，但是没法改啊，原因是Angular的页面渲染机制（别问我渲染机制是什么，这只是我大概猜测）。</p>

<p>于是我讲目光再次锁定到数据记录上了。你不是自己边高度嘛，我就把你数据锁死，内容过多不给你撑起高度，看你还给我变高度(傲娇脸)</p>

<pre><code>max-width: 100px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
</code></pre>

<p>问题解决，快表扬我</p>

<p>重新打包发布，继续学习，毕竟还是一个菜鸟啊</p>

<p>一天后，后端找我，坑比又来了！！！</p>

<h4 id="tabletable">这次，是一级table编辑提交后，二级table收起了</h4>

<p>我就想问，你一级table编辑跟二级table有毛裤关系啊，但是被后端说服了，也确实是不友好，所以又是一顿折磨，就这个问题已经持续一周了啊！！！</p>

<p>我实在不知道怎么解决了，于是动歪点子了。在高度展开后，将高度设为<code>auto</code>,这样我就不去造假数据了。但是问题还是没有解决，于是想着利用<code>setTimeout</code>来在获取数据后将高度展开。但是为什么非要等js执行完后再去渲染页面啊妈蛋！！</p>

<p>所以，决定换一个方式来实现这个工具类。找了半天，发现jquery有一个<code>slideToggle</code>方法，啊啊啊，我为什么不早点发现这个。这样的话，直接在样式里增加一个<code>showOrHide{{$index}}</code>样式，这样可以找到确定的div了。这样的话，在二级table里修改删除都不用担心高度问题了，因为这个方法是利用的<code>display</code>属性，<code>heigth</code>默认为<code>auto</code>。但是一级table编辑后二级table收起的问题还是没有解决啊，思索了一天多还是没找到解决方案。昨天一大神路过，于是我把他打劫了。大神听了问题，说了一句话，你可以在这个对象里加一个属性<code>displayOpen</code>，为true的话，页面渲染时将其<code>display</code>属性设为<code>block</code>，可以利用<code>ng-if</code>或<code>ng-show</code>。</p>

<p>果然大神就是大神，几分钟解决了困扰我许久的问题。</p>

<p>于是，我走上了正道。</p>

<p>按大神的方式去实现了，但是为毛点击后不出现了啊，二级table你死哪儿去了。噢，原来我用了<code>ng-show</code>，但是这个不是控制样式的啊，于是我想着应该有<code>ng-style</code>的指令的，先改成这个，再去查了一下，啊哈果然有我真是天才啊。<a href="https://docs.angularjs.org/api/ng/directive/ngStyle">The ngStyle directive allows you to set CSS style on an HTML element conditionally.</a></p>

<h3 id="end">END</h3><!--kg-card-end: html-->]]></content:encoded></item><item><title><![CDATA[jQuery实现轮播图的无缝滚动]]></title><description><![CDATA[<!--kg-card-begin: html--><p>之前在学习jQuery时，想做一个轮播图的demo，于是在网上了找了相关的视频教程。然后根据教程不断的改变ul元素的左外边距自己做了一个demo，但是在演示的时候，最后一张到第一张图片切换到时候没有动画效果。之后尝试在最后多添加一个第一张图片，然后在展示这张图片时，默默的把其换成了真正的第一张图片，这样在切换的时候看不到痕迹。但是这样在第一张点击向前时，会出现两张一样的第一张图片。那么如何实现无缝滚动呢？</p>

<p>一、原理 
实现原理是通过div的overflow:hide属性来显示单个图片，再不断的改变ul元素的左外边距动画显示每个图片，最关键的是这里，在将ul的第一个元素左移后，将其添加到ul的尾部然后删除，这样，当前显示的图片一直是第一张图片。</p>

<p>二、动手看看 
html代码：  </p>

<pre><code>&lt;div id="container"&gt;  
    &lt;div id="content"&gt;
        &lt;ul class="photo"&gt;
            &lt;li class="Li"&gt;&lt;img src="images/</code></pre>]]></description><link>https://qiuz.site/ai-di-sheng-la-lao-si-ji-da-qia-liao/</link><guid isPermaLink="false">5d8e2624dd59f70001a55dd2</guid><category><![CDATA[FrontEnd]]></category><dc:creator><![CDATA[qiuz]]></dc:creator><pubDate>Fri, 19 Aug 2016 06:46:03 GMT</pubDate><media:content url="https://qiuz.site/content/images/2019/09/12677958-2560-1600.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: html--><img src="https://qiuz.site/content/images/2019/09/12677958-2560-1600.jpg" alt="jQuery实现轮播图的无缝滚动"><p>之前在学习jQuery时，想做一个轮播图的demo，于是在网上了找了相关的视频教程。然后根据教程不断的改变ul元素的左外边距自己做了一个demo，但是在演示的时候，最后一张到第一张图片切换到时候没有动画效果。之后尝试在最后多添加一个第一张图片，然后在展示这张图片时，默默的把其换成了真正的第一张图片，这样在切换的时候看不到痕迹。但是这样在第一张点击向前时，会出现两张一样的第一张图片。那么如何实现无缝滚动呢？</p>

<p>一、原理 
实现原理是通过div的overflow:hide属性来显示单个图片，再不断的改变ul元素的左外边距动画显示每个图片，最关键的是这里，在将ul的第一个元素左移后，将其添加到ul的尾部然后删除，这样，当前显示的图片一直是第一张图片。</p>

<p>二、动手看看 
html代码：  </p>

<pre><code>&lt;div id="container"&gt;  
    &lt;div id="content"&gt;
        &lt;ul class="photo"&gt;
            &lt;li class="Li"&gt;&lt;img src="images/1.jpg"&gt;&lt;/li&gt;
            &lt;li class="Li"&gt;&lt;img src="images/2.jpg"&gt;&lt;/li&gt;
            &lt;li class="Li"&gt;&lt;img src="images/3.jpg"&gt;&lt;/li&gt;
            &lt;li class="Li"&gt;&lt;img src="images/4.jpg"&gt;&lt;/li&gt;
            &lt;li class="Li"&gt;&lt;img src="images/5.jpg"&gt;&lt;/li&gt;
            &lt;li class="Li"&gt;&lt;img src="images/6.jpg"&gt;&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/div&gt;
    &lt;div id="nav"&gt;
        &lt;a href="#" class="next"&gt;&lt;/a&gt;
        &lt;a href="#" class="prev"&gt;&lt;/a&gt;
    &lt;/div&gt;
&lt;/div&gt;  
</code></pre>

<p>接下来是CSS部分，利用ul外层的div的overflow属性来显示单个图片</p>

<pre><code>#content {
    overflow: hidden;
    width: 400px;
    height: 300px;
    margin: 0 auto;
    border: 3px solid black;
}
</code></pre>

<p>还需要将ul里的图片弄成一行，这个直接利用浮动设置</p>

<pre><code>.photo li {
    float: left;
}
</code></pre>

<p>这样基本的布局已经完成了，下面要实现的就是jQuery的部分了，将ul的左外边距依次减小图片的宽度400px。但是这样的话，当移动到最后一张图片的时候，再点击下一页，就要把ul的左外边距重新设置成0px,这样就完成了图片的轮播。</p>

<p>但是这样其实有一个BUG，你从最后一张图片跳到第一张图片其实是没有动画效果的，看起来很不舒服，那怎么弄，才能解决这个小BUG呢。</p>

<p>其实jQuery有两个方法，prepend() 和append()。前者是在一个元素中的头部插入一个元素，后者是在尾部，这样每次在将ul的第一个元素左移400px后，将其添加到ul的尾部然后删除利用remove()方法，也就是说这第一个元素现在成了最后一个元素。这中间需要用一个变量保存这个元素，可以利用clone()方法。</p>

<p>代码如下</p>

<pre><code>$(document).ready(function(){
        $("#nav .next").click(function(){
            movenext();
        });
        function movenext(){
        $(".photo li:first-child").animate({marginLeft:"-400px"},1000,function(){
                    var temp=$(this).clone();
                        $(this).remove();
                        temp.css({marginLeft:"0"});
                    $(".photo").append(temp);
                });
        }
    });
</code></pre>

<p>这样，向后轮播实现。向前是一样的</p>

<pre><code>$(document).ready(function(){
            $("#nav .prev").click(function(){
                moveprev();
            });
            function moveprev(){
                    var temp=$(".photo li:last-child").clone();
                    $(".photo li:last-child").remove();
                    temp.css({marginLeft:"-400px"});
                    $(".photo").prepend(temp);
                    $(".photo li:first-child").animate({marginLeft:"0"},1000);
            }
        });
</code></pre>

<p>这里需要注意的一点，向前是需要先将尾部的元素添加到头部，再执行图片的切换，和向后的顺序是相反的。</p>

<p>在线轮播图展示：<a href="https://qiuziz.github.io/FirstIndex/lunbotu/lunbotu.html">简单的轮播图</a></p><!--kg-card-end: html-->]]></content:encoded></item></channel></rss>