判断当前浏览器是否为微信内置浏览器 MicroMessenger

通过微信内置浏览器的 User Agent

首先我们通过 PHP 内置的 $_SERVER["HTTP_USER_AGENT"] server 数组来获取 User Agent。

iPhone 通过微信内置浏览器访问网页时得到 User Agent 是:

Mozilla/5.0 (iPhone; CPU iPhone OS 6_1_3 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Mobile/10B329 MicroMessenger/5.0.1

Android 通过微信内置浏览器访问网页时得到 User Agent 是:

Mozilla/5.0 (Linux; U; Android 2.3.6; zh-cn; GT-S5660 Build/GINGERBREAD) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1 MicroMessenger/4.5.255

JS 判断

function is_weixin(){
    var ua = navigator.userAgent.toLowerCase();
    if(ua.match(/MicroMessenger/i)=="micromessenger") {
        return true;
     } else {
        return false;
    }
}

PHP 判断

function is_weixin(){ 
    if ( strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false ) {
            return true;
    }    
    return false;
}

Linux 下使用 vsftpd 搭建 ftp 服务

检查系统中是否已安装 vsftpd

rpm -qa | grep vsftpd

若未安装则使用安装命令

yum -y install vsftpd

安装完之后创建 ftp 用户和适用目录

useradd -s /sbin/nologin -d /home/ftproot ftproot

注:目录不要手动创建,该命令会自动创建

更令 ftp 用户密码

passwd ftproot

然后输入两次密码

打开 vsftpd 的配置文件

vim /etc/vsftpd/vsftpd.conf

找到 anonymous_enable 配置项,默认是YES,修改成NO,表示不允许匿名用户登录

:wq 保存文件,执行启动命令

CentOS 6 下启动

service vsftpd start

查看运行状态

service vsftpd status

CentOS 7 下启动

systemctl start vsftpd.service

查看运行状态

systemctl status vsftpd.service

完毕

微信小程序 底部弹出层 可触控移动动画效果

WXML

<view bindtap='showModal' class='click'><text>click</text></view>
<view class="commodity_screen {{showModalStatus?'active':''}}" animation="{{animationBG}}" bindtap="hideModal"></view>
<view animation="{{animationData}}" class="commodity_attr_box" wx:if="{{showModalStatus}}" bindtouchstart="mytouchstart" catchtouchmove="mytouchmove" bindtouchend="mytouchend" catchtap='hideModal'></view>

WXSS

.click{
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
}

/*使屏幕变暗  */

.commodity_screen {
  display: none;
  width: 100%;
  height: 100%;
  position: fixed;
  top: 0;
  left: 0;
  background: #000;
  opacity: 0;
  overflow: hidden;
  z-index: 1000;
  color: #fff;
  transition: all 2s ease;
}

.commodity_screen.active {
  display: block;
}

/*对话框 */

.commodity_attr_box {
  height: 1120rpx;
  width: 100%;
  position: fixed;
  bottom: 0;
  left: 0;
  z-index: 2000;
  background: #f8f8f8;
  /* padding-top: 20rpx; */
}

JS

Page({
  data: {
  },
  mytouchstart: function (e) {
    console.log(e.timeStamp + '- touch start')
    var startPoint = [e.touches[0].pageX, e.touches[0].pageY]
    this.setData({
      startPoint: startPoint
    })
  },
  mytouchend: function (e) {
    console.log(e.timeStamp + '- touch end')
    console.log(e)
    var endPoint = [e.changedTouches[0].pageX, e.changedTouches[0].pageY]
    this.setData({
      endPoint: endPoint
    })

    var startPoint = this.data.startPoint
    var y = endPoint[1] - startPoint[1]
    console.log('最终移动了Y=' + y)
    if (y > 0) {
      // this.hideModal()
      var animation = wx.createAnimation({
        duration: 500,
        timingFunction: "ease",
        delay: 0
      })
      this.animation = animation
      animation.translateY(900).step()

      var animationBG = wx.createAnimation({
        duration: 500,
        timingFunction: 'ease',
      })
      animationBG.opacity(0).step()

      this.setData({
        animationData: animation.export(),
        animationBG: animationBG.export(),
      })

      setTimeout(function () {
        this.setData({
          showModalStatus: false
        })
      }.bind(this), 500)

      this.setData({
        noscroll: ''
      })
    } else {
      // this.showModal()
      var animation = wx.createAnimation({
        duration: 500,
        timingFunction: "ease",
        delay: 0
      })
      this.animation = animation
      animation.translateY(0).step()
      this.setData({
        animationData: animation.export()
      })
    }
  },
  mytouchmove: function (e) {
    console.log(e.timeStamp + '- touch move')
    var curPoint = [e.touches[0].pageX, e.touches[0].pageY]
    var startPoint = this.data.startPoint
    var y = curPoint[1] - startPoint[1]
    console.log(y)

    var animation = wx.createAnimation({
      duration: 0,
      timingFunction: 'ease',
      delay: 0
    })
    this.animation = animation
    if (y > -50) {
      animation.translateY(y).step()
      this.setData({
        animationData: animation.export()
      })
    }
  },
  //显示对话框
  showModal: function () {
    // 显示遮罩层
    var animation = wx.createAnimation({
      duration: 500,
      timingFunction: "ease",
      delay: 0
    })
    animation.translateY(900).step()
    this.setData({
      animationData: animation.export(),
      showModalStatus: true
    })
    setTimeout(function () {
      animation.translateY(0).step()
      this.setData({
        animationData: animation.export()
      })
    }.bind(this), 0)

    var animationBG = wx.createAnimation({
      duration: 500,
      timingFunction: 'ease',
    })
    animationBG.opacity(0.5).step()
    this.setData({
      animationBG: animationBG.export()
    })

    this.setData({
      noscroll: 'noscroll'
    })
  },
  //隐藏对话框
  hideModal: function () {
    console.log('hideModal')
    // 隐藏遮罩层
    var animation = wx.createAnimation({
      duration: 500,
      timingFunction: "ease",
      delay: 0
    })
    animation.translateY(500).step()
    var animationBG = wx.createAnimation({
      duration: 500,
      timingFunction: 'ease',
    })
    animationBG.opacity(0).step()
    this.setData({
      animationData: animation.export(),
      animationBG: animationBG.export()
    })
    setTimeout(function () {
      animation.translateY(0).step()
      this.setData({
        animationData: animation.export(),
        showModalStatus: false
      })
    }.bind(this), 200)

    this.setData({
      noscroll: ''
    })
  },
})

问题:IOS 性能可以,安卓 性能堪忧

Welcome to the Gutenberg Editor

Of Mountains & Printing Presses

The goal of this new editor is to make adding rich content to WordPress simple and enjoyable. This whole post is composed of pieces of content—somewhat similar to LEGO bricks—that you can move around and interact with. Move your cursor around and you'll notice the different blocks light up with outlines and arrows. Press the arrows to reposition blocks quickly, without fearing about losing things in the process of copying and pasting.

What you are reading now is a text block, the most basic block of all. The text block has its own controls to be moved freely around the post...

... like this one, which is right aligned.

Headings are separate blocks as well, which helps with the outline and organization of your content.

A Picture is worth a Thousand Words

Handling images and media with the utmost care is a primary focus of the new editor. Hopefully, you'll find aspects of adding captions or going full-width with your pictures much easier and robust than before.

Beautiful landscape
If your theme supports it, you'll see the "wide" button on the image toolbar. Give it a try.

Try selecting and removing or editing the caption, now you don't have to be careful about selecting the image or other text by mistake and ruining the presentation.

The Inserter Tool

Imagine everything that WordPress can do is available to you quickly and in the same place on the interface. No need to figure out HTML tags, classes, or remember complicated shortcode syntax. That's the spirit behind the inserter—the (+) button you'll see around the editor—which allows you to browse all available content blocks and add them into your post. Plugins and themes are able to register their own, opening up all sort of possibilities for rich editing and publishing.

Go give it a try, you may discover things WordPress can already add into your posts that you didn't know about. Here's a short list of what you can currently find there:

  • Text & Headings
  • Images & Videos
  • Galleries
  • Embeds, like YouTube, Tweets, or other WordPress posts.
  • Layout blocks, like Buttons, Hero Images, Separators, etc.
  • And Lists like this one of course 🙂

Visual Editing

A huge benefit of blocks is that you can edit them in place and manipulate your content directly. Instead of having fields for editing things like the source of a quote, or the text of a button, you can directly change the content. Try editing the following quote:

The editor will endeavour to create a new page and post building experience that makes writing rich posts effortless, and has “blocks” to make it easy what today might take shortcodes, custom HTML, or “mystery meat” embed discovery.

Matt Mullenweg, 2017

The information corresponding to the source of the quote is a separate text field, similar to captions under images, so the structure of the quote is protected even if you select, modify, or remove the source. It's always easy to add it back.

Blocks can be anything you need. For instance, you may want to add a subdued quote as part of the composition of your text, or you may prefer to display a giant stylized one. All of these options are available in the inserter.

You can change the amount of columns in your galleries by dragging a slider in the block inspector in the sidebar.

Media Rich

If you combine the new wide and full-wide alignments with galleries, you can create a very media rich layout, very quickly:

Accessibility is important don't forget image alt attribute

Sure, the full-wide image can be pretty big. But sometimes the image is worth it.

The above is a gallery with just two images. It's an easier way to create visually appealing layouts, without having to deal with floats. You can also easily convert the gallery back to individual images again, by using the block switcher.

Any block can opt into these alignments. The embed block has them also, and is responsive out of the box:

https://vimeo.com/22439234

You can build any block you like, static or dynamic, decorative or plain. Here's a pullquote block:

Code is Poetry

The WordPress community

If you want to learn more about how to build additional blocks, or if you are interested in helping with the project, head over to the GitHub repository.


Thanks for testing Gutenberg!

👋