[ nginx ] 轉換切換目錄 change root path

轉換目錄時
會發生失敗 無法讀取
cat error.log 會出現
is forbidden , Permission denied 的字樣

請執行以下
To check if SELinux is running:
# getenforce

To disable SELinux until next reboot:
# setenforce Permissive

【代訂】三鷹の森ジブリ美術館門票




























【門票費用】
成人、大學生600元
高中、中學生450元
國小400元 / 幼兒(4歲以上)100元

【入場時間】
第一場10:00(到10:30為止)
第二場12:00(到12:30為止)
第三場14:00(到14:30為止)
第四場16:00(到16:30為止)

【營業時間】
10:00~18:00(星期二休館)
一天只有四個入場時間每場的入場時間只有半小時,超過時間就不能進去
但是入場後可以一直待到當天晚上6點美術館關門
詳細說明
1. 三鷹美術館於每週二休館,不對外開放參觀。美術館每日遊客有限,不保證一定會能預購成功請知悉
2. 旅客資料請務必於每月7號前提供完畢才視同有效單
3. 最終訂票結果會於當月15號前通知,並發送取票憑證
4. 此票券為記名制,務必提供同護照英文姓名,否則有被拒絕入場之可能
5. 【記名制】票券購買後,不接受任何原因的變更及取消

訂購時請提供以下訊息
1.【代表者】旅客【英文姓名】(同護照,務必跟護照上一樣,恕不接受更改名字)
2.訂購張數 , 例:成人2張 , 高中x1
3.電子信箱,會將門票寄到電子信箱

欲訂購者
於 facebook 訊息中留言詳細資料
[ facebook 三鷹の森ジブリ美術館門票代訂專頁 ] 點我進入
有對話紀錄 保障雙方權益
並確認匯款款項
預訂作業即開始進行

Laravel 5.0 必成功之安裝步驟





















Laravel 的安裝參考了網路上許多資源
發覺遺漏許多部份 , 失敗了數次 並經過一段工作時間將其匯整
使其能按照以下步驟 , 必定能安裝完成之列表
直接用 Pietty or MobaXterm 複製貼上簡單輕鬆的完成它


軟體版本
PHPphp5.4
WEBnginx
FRAMEWORKLaravel5.0
DBmariaDB
VMvmware8(2015.10.05 Vmware 11安裝無法選擇套件 進入以下步驟會有問題 )
OSCentOS7(選擇網站伺服器安裝,mariadb,php )


為了各位學習 Laravel 方便,提供 vmware 8.0 使用的 vmdk 供下載(download)
網友可以自己選擇要直接使用vm檔或是按照步骤完成



//----download Laravel5.0   -----------------------------------------------------------------

Laravel5.0_Vmdk
(click me download vmdk(vmare8 )for Laravel 5.0 )
(contain : nginx+php5.4+mariadb)

//----install step by step   -----------------------------------------------------------------

yum update yum install wget yum install epel-release //更新後才可執行 sudo yum install php-mcrypt* sudo yum install php-mcrypt* //laravel 會使用到的套件

//mariadb install yum install mariadb-server mariadb sudo systemctl start mariadb
第一次安裝 mysql -u root mysql -p (enter) password : ( 直接 enter 第一次不需密碼 )
設定密碼 SET PASSWORD FOR 'root'@'localhost' = PASSWORD ('你的密碼');
設定誰可以進入資料庫 grant all privileges on *.* to root@1.2.3.4 identified by '你的密碼'; ( 某人可以從1.2.3.4使用root進入) 視個人需求是否要修改port號 修改完記得要重啟 修改 mariadb port /etc/my.cnf


//php install No match for argument: php-mysql centos无法安装php-mysql模块 解决方案: 可能是epel源问题: 1.获取php7.0的yum源 rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm sudo yum install php-mbstring //laravel 會使用到的套件 yum install php php-mysql php-fpm (若出現異常跳過 沒有安裝跡象 ,則分開各別裝 ) (centos 內建 php5.4) ex : yum install php-fpm ex : yum install php ex : yum install php-mysql (centos 如果要安裝 更高php版本 7.2 請參考以下 ) yum install epel-release yum-utils -y yum install http://rpms.remirepo.net/enterprise/remi-release-7.rpm yum-config-manager --enable remi-php72 yum install php php-common php-opcache php-mcrypt php-cli php-gd php-curl php-mysql -y How to Install PHP 7.0, 7.1, 7.2

sudo vi /etc/php.ini /尋找 memory 修改記憶體配置 改為 512MB , 原本是128M sudo vi /etc/php-fpm.d/www.conf 修改listen = /var/run/php-fpm/php-fpm.sock ;user = apache user = nginx ;group = apache group = nginx listen.owner = nginx listen.group = nginx listen.mode = 0666 sudo systemctl start php-fpm systemctl enable php-fpm.service

以下為補充 ( laravel 5.1 need php5.5.9 + ) 若使用 Laravel 5.1 的朋友需使用底下安裝步驟(php5.6) //php5.6使用 wget http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm wget http://rpms.famillecollet.com/enterprise/remi-release-6.rpm rpm -Uvh remi-release-6*.rpm epel-release-6*.rpm vi /etc/yum.repos.d/remi.repo 找到標題是 [remi-php56] 將 enabled=0 改為 1 ( 以上找不到就自動省略 )

//nginx install rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
yum install nginx

centos8 
假設安裝遇問題 添加以下
cat << EOF > /etc/yum.repos.d/nginx.repo [nginx-stable] name=nginx stable repo baseurl=http://nginx.org/packages/centos/8/x86_64/ gpgcheck=1 enabled=1 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true EOF



開通80port服務 iptables -I INPUT -p tcp --dport 80 -j ACCEPT vi /etc/nginx/conf.d/default.conf 將內容整個砍掉 ,複製貼上底下內容即可 ( 注記得修改 root /usr/share/nginx/html/S1/public 位置) server { listen 80; server_name localhost; root /usr/share/nginx/html/S1/public; index index.php index.html index.htm; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { try_files $uri =404; fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; proxy_connect_timeout 159s; proxy_send_timeout 600; proxy_read_timeout 600; proxy_buffer_size 64k; proxy_buffers 16 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; proxy_pass_header Set-Cookie; proxy_redirect off; proxy_hide_header Vary; proxy_set_header Accept-Encoding ''; proxy_ignore_headers Cache-Control Expires; proxy_set_header Referer $http_referer; proxy_set_header Host $host; proxy_set_header Cookie $http_cookie; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Server $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }


視個人需求是否要修改port號 修改完記得要重啟 修改 nginx port /etc/nginx/conf.d/php.conf 修改 mariadb port /etc/my.cnf systemctl start nginx systemctl status nginx systemctl enable nginx.service

//Laravel install cd /usr/share/nginx/html/ wget http://down.golaravel.com/laravel/laravel-v5.0.22.zip unzip laravel-v5.0.22.zip mv laravel-v5.0.22 Laravel sudo chmod -R 775 Laravel sudo chown -R nginx.nginx Laravel systemctl restart nignx 這裡記住一定用sudo 去下cmd , 不要以為用root就不使用sudo 設定SELinux vi /etc/selinux/config 由原本 #SELINUX=enforcing 改為 SELINUX=disabled SELinux是 Security Enhanced Linux (安全加強的 Linux) 的縮寫, 他並不是一個防火牆的軟體,而是一個『針對檔案系統權限作更細部規劃的一個模組』。

假設到新電腦上安裝,複製原本的laravel資料夾過去 看log一直顯示 could not be opened failed to open stream permission denied
或是出現 0.0.0.0:8843 failed (13: Permission denied)

執行它即可
sudo setenforce 0
或是在 nginx.conf 最上方
user nginx 改為 root
參考
https://blog.51cto.com/waxyz/5336419


Lexical Analyzer C++ 語法解析器



#include<iostream>
#include<conio.h>
#include<string>
#include<fstream>
using namespace std;

/* The grammar follwed by this analyser is : you have to give a blank to differentite between two different entities, for eg 
       instead of writing "int c=a+b;", write it as "int c = a + b ;".
       
   To execute this program first create an "input.txt" file where the program is written or specify the path of the file which has 
      to be analysed, after compiling an "output.txt" file will be created where you have stored the program.
*/

bool keycheck(string str)
{
     string keyword[] ={"int","main()","float","if"};
     int flag=0;
     if(!(str[0]>=97 && str[0]<=122))
                     return false;
      for(int i=0;i<4;i++)
      {
             if(str == keyword[i])
              {     
                     flag = 1;
                     break;
              }
      }
     

     
     if(flag == 1)
             return true;
     else
             return false;
} 

string opcheck(string str)
{
     string reloperators[8] ={"=","==",">","<",">=","<="};
     string mathoperators[5] ={"+","*","/","-","%"};
     string operators[4]={"{","}",";",","};
     int flag1=0,flag2=0,flag=0;
     
    
    for(int i=0;i<4;i++)
    {
            if(str == operators[i])
            {
                   flag = 1;
                   break;
            }
    }
    if(flag == 1)
    {
            return "operator";
    }
    else
    {
    
        for(int i=0;i<8;i++)
         {       
             if(str == reloperators[i])
             {
                    flag1 = 1;
                    break;
             }
         }
         if(flag1 == 1)
         {
             return "relational operator";
         }
         else
         {
          for(int i=0;i<5;i++)
          {       
             if(str == mathoperators[i])
             {
                    flag2 =1;
                    break;
             }
          }
          
          if(flag2 == 1)
                  return "mathematical operator";
          else
                  return "error";
     }
    }
}
                   
         
             
int ischar(char c)
{
     if((c>=65 && c<=90) || (c>=97 && c<=122))
             return 1;
    else
             return 0; 
}          
                     

int isnum(char c)
{
    if(c>=48 && c<=57)
             return 1;
    else
             return 0;
}
    
int isnums(string str)
{
    int flag=0;
    for(int i = 0;i<str.length();i++)
    {
         if(!isnum(str[i]))
         {
                           if(str[i] != 46) 
                           {
                                     flag=1;
                                     break;
                           }
         }
    }
    
    if(flag == 1)
            return 0;
    else
            return 1;
}

int isidentifier(string str)
{
    int flag =0;
     for(int i=1;i<str.length();i++)
     {
      if(!ischar(str[i]))
      {
       if(!isnum(str[i]))
       {
        if(str[i] != 95)
        {
           if(str[i] == 91)
           {
                     i++;
                     for(;str[i]!= 93;)
                     {
                      if(!isnum(str[i]))
                      {
                                        flag =1;
                                        break;
                      }
                      i++;
                     }
           }
           else
           {         
                     flag = 1;
                     
           }
           
           if(flag ==1)
                   break;
        }
      }
     }
    }
    
    return flag;
}


int exc( string str1 )
{

    int flag=0;
    bool check;
 string str="",strch,strline;

    for(int j=0;j<str1.length();j++)
    {       
            if(str1[j] ==' ' || str1[j]=='\t')
            {
                                    
                      
              
                      
                     if(str != "")
                     {
                      if(ischar(str[0]))
                      {
                                    check = keycheck(str);
                                    
                                    if(check)
                                    {
                                            cout<<str<<"\t --> reserved word\n";  
                                    }        
                                    else
                                    {
                                      
                                        flag = isidentifier(str);
                                        
                                        if(flag == 1)
                                        {
                                                cout<<str<<"\t --> error\n";
                                                flag = 0;
                                        
                                        }
                                        else
                                        {
                                            cout<<str<<"\t --> identifier\n";
                                        }
                                    }
                                                                                             
                      
                                           
                      }
                      else
                      {
                          if(isnum(str[0]))
                          {
                                          if(isnums(str))
                                                         cout<<str<<"\t -->number\n";
                                          else
                                                         cout<<str<<"\t -->error\n";
                          }
                          else
                          {
                              strch = opcheck(str);
                              if(strch == "error")
                                     cout<<str<<"\t -->"<<strch<<"\n";
                              else
                                     cout<<str<<"\t -->"<<strch<<"\n";
                          }
                      } 
                      
                     }
                      
                     str="";  
            }
           else
            {
               str=str+str1[j];    
            }    
     }

 return 0 ;
}
             
                                                        
int main()
{
 
    string str="",strch,strline,str1;

    char a[520]; 
    cin.get(a,520); 
    exc(a);
                      
    system("pause");
                      
    

}

編譯後結果應如下圖














Access-Control-Allow-Origin error sending a jQuery

f you have this error trying to consume a service that you can't add the header Access-Control-Allow-Origin * in that application, but you can put in front of the server a reverse proxy, the error can avoided with a header rewrite.
Assuming the application is running on the port 8080 (public domain at www.mydomain.com), and you put the reverse proxy in the same host at port 80, this is the configuration for Nginx reverse proxy:
server {
    listen      80;
    server_name www.mydomain.com;
    access_log  /var/log/nginx/www.mydomain.com.access.log;
    error_log   /var/log/nginx/www.mydomain.com.error.log;

    location / {
        proxy_pass   http://127.0.0.1:8080;
        add_header   Access-Control-Allow-Origin *;
        add_header   Access-Control-Allow-Origin 'http://domain.com';

    }   
}

不分享會對不起自己的 - tawk線上即時客服系統

不分享會對不起自己的 - tawk線上即時客服系統

"線上即時客服系統"在現在的網站上是一常見的功能,英文字詞通常是用live help、live chat或live support。它提供了網站訪客,能夠在網站上當有需要問問題,或是需要馬上尋求協助時,用這個即時對談的功能,與在線上的客服人員用文字訊息對談,或甚至可以用語音交談。
現在也有很多網站使用其他外部應用程式工具,例如Line、QQ或facebook messager之類的即時交談工具來作這件事情,不過這些都需要要求網站訪客有安裝這些應用程式才能使用。今天要要介紹的tawk是不需要額外的工具的。
tawk的特性有以下幾個:
  • 一切"免費"。目前沒有額外的付費方案,沒有分什麼付費版或免費版,也沒有廣告。
  • 可用於所有網站。它也可以用在一般的網頁上,Joomla!系統其他系統,或是只用單純的HTML網頁也行。
  • 有中文介面。中文也很重要,很多這類的系統可能不一定有中文介面。
  • 全功能。這套tawk有幾乎應該有的線上客服功能。它也有提供iphone和android的手機應用程式(給客服人員用的)

圖文介紹

註:下面的說明中,我把使用的人分成兩端,一種我們叫"客服人員",也就這個網站的負責接待的人員,也就是負責回答問題的人。另一種叫"客戶",他們是來到這個網站的訪客,想要問問題或尋求協助的人。
它的網站是http://www.tawk.to。"tawk"應該是英文"talk"的唸法與改寫,標誌是一支鸚鵡的樣子。雖然網站沒有中文說明,不過註冊完進管理區後可以在右上角選擇"官話",就可以改成中文介面,這是它的官網畫面:


下面這是它的管理控制台畫面:

下面這是監控畫面,可以看到目前在你網站上的人,他們使用的ip、瀏覽器、正在看什麼頁面之類的資訊。客服人員也可以從這裡直接主動要和客戶對談,這種功能叫"主動交談"(push to talk):


下面這個所有談天訊息的記錄,它會忠實的記錄在這裡面:


下圖這是一開始需要設定,那個加入到你自己網站訊息提示工具的樣式,可以調整的設定很多,指示的圖片也可以用它裡面的圖庫或上傳自己的,下圖是客製化的工具:
下圖展示了,當客戶正在輸入訊息時,客服人員可以看得到"正在輸入"的字詞。這樣加快客服人員回應時間。


以下這兩個圖片是在網站上的使用展示,位置可以依你的設定來擺放,這裡是放在右下角,另一張圖片是正在交談的畫面。另一個要說明的是,如果客服人員離線時,就會變成留下訊息的表單。

如何安裝

大概的流程如下:
  1. 申請tawk的帳號,註冊時會需要填對你的email住址,註冊後它會寄送一封"Tawk.to account activation"的信,點按裡面的連結來啟用你的帳號。
  2. 到tawk.to網站上,用右上角的"login"頁面到登入畫面,輸入你的帳號密碼即可登入到管理區中。管理區的右上角有可以選擇語言的下拉選單,選擇"官話"可切換為中文的介面。
  3. 到上方選單的"網站&頁面" > "管理網站"中(英文是Sites & Pages > Manage Sites),可以新增你要放置tawk的網站位置等等的資訊,它最後可以產生一個api程式碼(javascript程式碼),把它加到你的網頁中就可以開始使用了。
  4. 如果你的網站有使用特定的系統,例如Joomla!、Wordpress、Drupal、OpenCart等等,你也可以下載相關的擴充或外掛,方便你進行設定,網址在:

在linux(centos) 安裝 Subversion 自建 SVN Server



Centos 7.2
前置過程需先安裝 httpd ( apache ) server

yum install httpd
systemctl start httpd
 iptables -I INPUT -p tcp --dport 80 -j ACCEPT
chkconfig httpd on

參考
https://wiki.centos.org/zh-tw/HowTos/Subversion

 安裝


[root@lucifer ~]# yum install mod_dav_svn subversion

4.1. Apache

在你進一步學習之先,你需要確定 Apache 已經被設置好。我假設你在做一個全新的安裝,因此如果你的 Apache 已經在運作中……請小心你所做的改動。我亦會解釋如何設置基本的密碼保護。然而,假若你想容許任何人存取版本庫,你可輕易地省略這部份。
你首先要做的事情就是開啟 /etc/httpd/conf/httpd.conf,而且最低限度更改 ServerName 這個指引。如果你需要協助或擁有更複雜的設定,請參詳 Apache 的文件。
[root@lucifer ~] vim /etc/httpd/conf/httpd.conf —— 作所需修改並存檔
[root@lucifer ~] service httpd start
[root@lucifer ~] chkconfig httpd on

在網絡上瀏覽你的機器,http://yourmachine ,看看你能否取得測試頁。做得到嗎?好了,讓我們進到更有趣的事情。

4.2. Subversion 給 Apache 的設定

下一步就是在 Apache 內設置某些設定,好讓 Subversion 與 Apache 能夠融洽相處。現在讓我們看看 Subversion 為你安裝的範例設定檔。

[root@lucifer ~] cd /etc/httpd/conf.d/
[root@lucifer ~] vim subversion.conf

# 有需要的話,請確定你移除這兩行的註釋
LoadModule dav_svn_module     modules/mod_dav_svn.so
LoadModule authz_svn_module   modules/mod_authz_svn.so

# 加入下列內容來支援基本驗證,並將 Apache 指向實際放置版本庫的地方。
<Location /repos>
        DAV svn
        SVNPath /var/www/svn/repos
        AuthType Basic
        AuthName "Subversion repos"
        AuthUserFile /etc/svn-auth-conf
        Require valid-user
</Location>

上面的位置是 Apache 在 URL 列上使用的。舉個例說:http://yourmachine/repos 指向你所指定的 SVNPath。上面只是一個範例,因此請按你的喜好放置東西。請確定你在完成編輯後儲存檔案。
然後我們須要建立你在上一部所指定的密碼檔。開始時你要利用 -cm 這個選項。它會建立檔案並用 MD5 將密碼加密。如果你需要加用戶,請確定你只使用 -m 選項,而不包含初次建立時的 -c。
[root@lucifer ~] htpasswd -cm /etc/svn-auth-conf yourusername
New password:
Re-type new password:
Adding password for user yourusername
[root@lucifer ~] htpasswd -m /etc/svn-auth-conf anotherusername
New password:
Re-type new password:
Adding password for user anotherusername

4.3. 設定你的版本庫


你接著要做的事情就是建立你用來提交及取出檔案的版本庫。利用 svn 所包含的工具,這是很容易的。
[root@lucifer ~] cd /var/www/ —— 或者你在上面所指定的路徑
[root@lucifer ~] mkdir svn
[root@lucifer ~] cd svn
[root@lucifer ~] svnadmin create repos
[root@lucifer ~] chown -R apache.apache repos
[root@lucifer ~] service httpd restart


現在去測試你能否透過網頁瀏覽器存取你的版本庫:http://yourmahcine/repos 。你應該取得一個對話方塊詢問用戶名稱及密碼。若然是這樣,請輸入你的憑證,然後你應該看見一版 Revision 0:/ 的頁面。這樣的話,版本庫的設定便大工告成了。如果你須要多個版本庫,請參考上面連結內的文檔。這裡只示範如何設置一個版本庫及開始應用它。話說回來,讓我們就這樣做。

6. 存取控制清單

一般來說,你不會想將所有版本庫的存取權給予所有用戶。你可以利用 ACL 來限制每位用戶存取版本庫的權限。ACL 可以透過 AuthzSVNAccessFile 這個檔案選項來啟用,它以一個檔名作為參數。例如:
AuthzSVNAccessFile /etc/svn-acl-conf
你可以在相關的 Location 部份加入它:
<Location /repos>
        DAV svn
        SVNPath /var/www/svn/repos
        AuthzSVNAccessFile /etc/svn-acl-conf
        AuthType Basic
        AuthName "Subversion repos"
        AuthUserFile /etc/svn-auth-conf
        Require valid-user
</Location>

注意是 使用 SVNPath  SVNParentPath
然後你可以建立 /etc/svn-acl-config。這個檔案內藏有這個格式的分段:
[版本庫名稱:版本庫路徑]
用戶 = 存取權
當中存取權可以是 r(唯讀)、rw(讀寫)、或空白(禁止存取)。預設的 ACL 是禁止用戶存取版本載。假設你有一個名叫 framework 的版本庫,而你想給 john 唯讀的權限,及 joe 讀寫的權限。你可以加入下面這個分段:
[framework:/]
john =  r
joe = rw
你亦可以在名叫 groups 的分段內建立群組,然後在存取控制清單內將 @ 符號放在群組前面。例如:
[groups]
staff = joe, george

[framework:/]
john =  r
@staff = rw
如果你想令所有用戶能閱讀每個版本庫,你可以為每個版本庫的根目錄加入以下一個分段:

[/]
* = r



如果想設定 誰才可以存取某些資料夾
subversion restrict user access folders


cd /etc/httpd/conf.d/
vim subversion.conf

多加入
AuthzSVNAccessFile /etc/svn-acl-conf

在 etc 下新增一檔案 叫 svn-acl-conf 

svn-acl-conf 內容設定如下 

[repos:/]
john = rw
(表示john 擁有整個資料夾瀏覽及編輯權限 )

[repos:/f1/f2]
Mary = r 
( 表示 Mary 只允許瀏覽 /f2 下資料夾內容 )

小心資料夾名稱後不要加到斜線了 例如 : f1/f2/


最後

設定SELinux

vi /etc/selinux/config

由原本 #SELINUX=enforcing 改為 SELINUX=disabled

記得重開機喔 !!

否則 commit 時 會一直出現  could not begin a transaction



注意 當你遇到 systemctl restart svnserve 無法啟動時
它告訴你 Root path '/var/svn' does not exist or is not a directory

vi /etc/sysconfig/svnserve  //修改路逕

# OPTIONS is used to pass command-line arguments to svnserve.
#
# Specify the repository location in -r parameter:
OPTIONS="-r /var/www/svn/repos"


重新做一次 開啟 svn 服務


netstat -nltp //查詢目前服務的阜號 例如 : 8891
kill 8891     //砍掉目前服務的 port
svnserve -d -r /var/www/svn/repos //重新繫結 svn 目錄
systemctl restart httpd //重啟 http 服務






node js 簡轉繁,繁轉簡 traditional to simplified

About This

用於 node.js 或瀏覽器之中:簡轉繁,或繁轉簡。

Install

shell (node.js)
npm install chinese-conv
shell (jspm for browser)
jspm install npm:chinese-conv

Usage

ES2015 (browser/node.js)
import {tify, sify} from 'chinese-conv';

// 轉成正體中文
let text = tify('所谓知己知彼百战不殆,作为星际2职业选手,他们在平时练习中不仅要练好自己的本族,还会经常选择其他两个族进行练习,这样可以更加了解本族之外两个种族的运营流程、弱点、真空期等。因此不只有Flash,全世界许多职业选手都会在练习时偶尔使用下别的种族,这也是他们众多练习手段的一种。');

console.log(text);
node.js
var chineseConv = require('chinese-conv');

var text = chineseConv.tify('所谓知己知彼百战不殆,作为星际2职业选手,他们在平时练习中不仅要练好自己的本族,还会经常选择其他两个族进行练习,这样可以更加了解本族之外两个种族的运营流程、弱点、真空期等。因此不只有Flash,全世界许多职业选手都会在练习时偶尔使用下别的种族,这也是他们众多练习手段的一种。');
//轉成簡體
var text = chineseConv.sify('轉成簡體測試');

console.log(text);

偵測是否為手機版 Detecting a mobile browser

up vote655down voteaccepted

Using Regex (from detectmobilebrowsers.com):

Here's a function that uses an insanely long and comprehensive regex which returns a true or false value depending on whether or not the user is browsing with a mobile.
window.mobilecheck = function() {
  var check = false;
  (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera);
  return check;
};
For those wishing to include tablets in this test (though arguably, you shouldn't), you can use the following function:
window.mobileAndTabletcheck = function() {
  var check = false;
  (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera);
  return check;
};

The Original Answer

You can do this by simply running through a list of devices and checking if the useragent matches anything like so:
function detectmob() { 
 if( navigator.userAgent.match(/Android/i)
 || navigator.userAgent.match(/webOS/i)
 || navigator.userAgent.match(/iPhone/i)
 || navigator.userAgent.match(/iPad/i)
 || navigator.userAgent.match(/iPod/i)
 || navigator.userAgent.match(/BlackBerry/i)
 || navigator.userAgent.match(/Windows Phone/i)
 ){
    return true;
  }
 else {
    return false;
  }
}
However since you believe that this method is unreliable, You could assume that any device that had a resolution of 800x600 or less was a mobile device too, narrowing your target even more (although these days many mobile devices have much greater resolutions than this)
i.e
function detectmob() {
   if(window.innerWidth <= 800 && window.innerHeight <= 600) {
     return true;
   } else {
     return false;
   }
}
Reference:
shareedit
15 
Hi I just visited the detectmobilebrowsers.com link on my iPad 3, iOS 6.1.2, and it says "No mobile browser detected". – Richard Lovejoy Mar 27 '13 at 18:28
30 
@RichardLovejoy when building sites, the ipad is generally not considered a mobile. – Michael ZaporozhetsMar 28 '13 at 11:14
36 
From the about page: Android tablets, iPads, Kindle Fires and PlayBooks are not detected by design. To add support for tablets, add |android|ipad|playbook|silk to the first regex. – Gras Double Jun 7 '13 at 0:28 
10 
Google TV is Android too. What define a mobile ? Screen Size ? Touch ? deviceOrientation ? When i design it's more a question of mousehover or not, big bouton or small links. So, for now, i run with "if (Modernizr.touch)" :) – molokoloco Jun 26 '13 at 22:26
12 
Gawd, this whole idea of user agents is awful and really, really needs to stop. We really need to stop allowing clients to fight against the tide and just stick with media queries. If they want to do redirects based on scale for particular pages, then just check the range of a particular media query via JS i.e. tylergaw.com/articles/reacting-to-media-queries-in-javascrip‌​t – marksyzm Aug 15 '13 at 10:07
How about:
if (typeof window.orientation !== 'undefined') { ... }
...since smartphones usually support this property and desktop browsers don't.
shareedit
7 
this is actually super unique and awesome, do you mind if I add it to my answer? – Michael ZaporozhetsJan 30 '13 at 0:34 
49 
This is probably not going to work for long. 1) Tablets can have decent screen sizes, you want them to display full desktop website but they will have this property 2) Windows 8 is here and with it a bunch of laptops with touch screen and screens that rotate. – Dave Hilditch Feb 20 '13 at 17:33
8 
as for your first point about Tablets with decent screen sizes- I think you could make the same arguments for all others solutions as well (a tablet with big screen that is been tracked as small screen). anyway the idea here is to search for property that is been shared by small devices instead of keep maintence long code and add regex with every new coming device/vesion/model. I think device detection is belong to the past and today we need to focus on feature detection. again I will be glad to here about more suitable property for that matter... – yoav barnea Mar 2 '13 at 20:01 
2 
Love it and works perfectly, thankyou. For my solution I was just after simple. – Bojangles Jun 18 '13 at 6:19
4 
window.orientation is a deprecated property (developer.mozilla.org/en-US/docs/Web/API/Window/orientation‌​, compat.spec.whatwg.org/#dom-window-orientation) that some mobile browsers choose to support for unknown reasons. Same browsers implement window.screen.orientation (which is defined in desktop browsers too). I can only assume that window.orientation is left there for legacy reasons and should therefore not be used in new applications. – Gajus Feb 8 '16 at 10:07
var isMobile = {
    Android: function() {
        return navigator.userAgent.match(/Android/i);
    },
    BlackBerry: function() {
        return navigator.userAgent.match(/BlackBerry/i);
    },
    iOS: function() {
        return navigator.userAgent.match(/iPhone|iPad|iPod/i);
    },
    Opera: function() {
        return navigator.userAgent.match(/Opera Mini/i);
    },
    Windows: function() {
        return navigator.userAgent.match(/IEMobile/i) || navigator.userAgent.match(/WPDesktop/i);
    },
    any: function() {
        return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
    }
};
How to use
if( isMobile.any() ) alert('Mobile');
To check to see if the user is on a specific mobile device:
if( isMobile.iOS() ) alert('iOS');
shareedit
1 
nice answer for all devices – Anup Oct 31 '13 at 7:16
   
Why not make any() a for...in loop of ORed isMobile members? – SomeShinyObject Mar 1 '14 at 15:43
   
@ChristopherW i had created its plugin and modified code as you advised – Mudaser Ali Apr 30 '14 at 19:57
1 
Maybe move iOS ahead of BlackBerry() just to put the more common cases first and let early bailout save some extra processing? – Rob_vH Mar 12 '15 at 14:33
2 
@Rob_vH i had put this code into github (github.com/smali-kazmi/detect-mobile-browser) with some advance features; you are open to send suggestions there as well – Mudaser Ali Mar 13 '15 at 19:45
Here is a simple solution from the source of facebook's slingshot
var isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
if (isMobile) {
  /* your code here */
}
shareedit
To add an extra layer of control I use the HTML5 storage to detect if it is using mobile storage or desktop storage. If the browser does not support storage I have an array of mobile browser names and I compare the user agent with the browsers in the array.
It is pretty simple. Here is the function:
// Used to detect whether the users browser is an mobile browser
function isMobile() {
    ///<summary>Detecting whether the browser is a mobile browser or desktop browser</summary>
    ///<returns>A boolean value indicating whether the browser is a mobile browser or not</returns>

    if (sessionStorage.desktop) // desktop storage 
        return false;
    else if (localStorage.mobile) // mobile storage
        return true;

    // alternative
    var mobile = ['iphone','ipad','android','blackberry','nokia','opera mini','windows mobile','windows phone','iemobile']; 
    for (var i in mobile) if (navigator.userAgent.toLowerCase().indexOf(mobile[i].toLowerCase()) > 0) return true;

    // nothing found.. assume desktop
    return false;
}
shareedit
1 
Can I please have a reason for the downvote? – dotTutorials Jun 27 '13 at 12:46
2 
I haven't tested on mobile yet, but sessionStorage.desktop doesn't exist in either Safari, Chrome, or Firefox (all newest versions at time of post). You get an up-vote though, since your solution goes in a better direction than others. But don't forget to use var mobile = instead of mobile =. – shuckster Dec 28 '13 at 15:33 
2 
Also a good idea not to use indexOf with older browsers still being around which don't support that method, or to use a polyfill. It's not necessary to use toLowerCase on a list of lowercase values, nor is it necessary to do so if you're running /ipad|iphone|etc/i.test(navigator.userAgent) instead of the slow loop you have up there.– Jeffrey Gilbert Jun 2 '14 at 22:19
Feature detection is much better than trying to figure out which device you are on and very hard to keep up with new devices coming out all the time, a library like Modernizr lets you know if a particular feature is available or not.
shareedit
7 
You've answered another question than what was asked. Rather than "how can I detect mobile?", you've answered "how can I detect certain features?". Not all device detection is for feature detection. What if we were looking to get statistics about devices? Then no, "feature detection" is not "much better than [figuring out device]". – Jonathan Allard Jun 1 '16 at 19:10
How about something like this?
if(
    (screen.width <= 640) || 
    (window.matchMedia && 
     window.matchMedia('only screen and (max-width: 640px)').matches
    )
  ){
   // Do the mobile thing
}
shareedit
   
Why not just use screen.width instead? It seems to me that's more reliable than window.matchMedia.– John Slegers Mar 12 '16 at 2:30
   
Good point John, I can't recall exactly what I was thinking at the time, it seems unlikely (looking at it now) that the second clause would return true if the first is false. There must have been some reason I added it though. – stujo Mar 23 '16 at 23:35
   
Most decent programmers feel ashamed when they see code they wrote themselves a year earlier. Those who don't just haven't grown as programmers ;-) – John Slegers Mar 24 '16 at 7:33 
1 
Thanks John :) Yeay Progress! – stujo Apr 12 '16 at 3:45
1 
Window resolution has nothing to do with whether a browser is on a mobile device or not. For example, lots of desktop browsers run in non-full-screen windows. If you present a UI designed for handheld screens to those browsers, their users are going to have a frustrating experience. – ʇsәɹoɈ Apr 21 '16 at 2:16 
Came here looking for a simple, clean way to detect "touch screens devices", which I class as mobile and tablets. Did not find a clean choice in the current answers but did work out the following which may also help someone.
var touchDevice = ('ontouchstart' in document.documentElement);
shareedit
1 
Why to use the ternary operator with true and false? var touchDevice = 'ontouchstart' in document.documentElement should behave exactly the same – abstraktor Apr 19 '16 at 8:41 
   
@abstraktor Ha.. so true, fixed. – Tigger Apr 19 '16 at 8:54
1 
What if desktop's monitor supports touch? – HappyCoder Aug 1 '16 at 1:25
   
@HappyCoder I believe it is up to the OS to tell the browser when the touch screen on a desktop is active. So, yes this check should still be valid. – Tigger Aug 1 '16 at 9:09
   
(+1), however, my desktop I'm using now has a touchScreen, and it isn't always consistent for touchstart|end|etc. – Cody Dec 16 '16 at 21:18
Here is a userAgent solution that is more efficent than match...
function _isMobile(){
    // if we want a more complete list use this: http://detectmobilebrowsers.com/
    // str.test() is more efficent than str.match()
    // remember str.test is case sensitive
    var isMobile = (/iphone|ipod|android|ie|blackberry|fennec/).test
         (navigator.userAgent.toLowerCase());
    return isMobile;
}
shareedit
6 
the test method is not case sensitive, but your regex is. you could just flag for case insensitive regex with an "i" at the end and do /iphone|etc/i.test(navigator.userAgent) – xec Feb 5 '13 at 17:01 
Here is my re-thought solution for the problem. Still not perfect. The only true solution would be if the device manufacturers start to take seriously the "Mobile" and "Tablet" user-agent strings. But probably this will only happen in our wildest dreams...
JS:
window.onload = userAgentDetect;
function userAgentDetect() {
  if(window.navigator.userAgent.match(/Mobile/i)
  || window.navigator.userAgent.match(/iPhone/i)
  || window.navigator.userAgent.match(/iPod/i)
  || window.navigator.userAgent.match(/IEMobile/i)
  || window.navigator.userAgent.match(/Windows Phone/i)
  || window.navigator.userAgent.match(/Android/i)
  || window.navigator.userAgent.match(/BlackBerry/i)
  || window.navigator.userAgent.match(/webOS/i)) {
    document.body.className+=' mobile';
    alert('True - Mobile - ' + navigator.userAgent);
  } else {
    alert('False - Mobile - ' + navigator.userAgent);
    //return false;
  }
  if(window.navigator.userAgent.match(/Tablet/i)
  || window.navigator.userAgent.match(/iPad/i)
  || window.navigator.userAgent.match(/Nexus 7/i)
  || window.navigator.userAgent.match(/Nexus 10/i)
  || window.navigator.userAgent.match(/KFAPWI/i)) {
    document.body.className-=' mobile';
    document.body.className+=' tablet';
    alert('True - Tablet - ' + navigator.userAgent);
  } else {
    alert('False - Tablet - ' + navigator.userAgent);
    //return false;
  }
}
What happens when the Nexus 7 tablet only have the Android UA string? First, the Mobile become true, than later on the Tablet also become true, but Tablet will delete the Mobile UA string from the body tag.
CSS:
/*************************Start of: Tablet*************************/
body.tablet { background-color: green; }
/**************************End of: Tablet**************************/

/*************************Start of: Mobile*************************/
body.mobile { background-color: red; }
/**************************End of: Mobile**************************/
alert lines added for development. Chrome console can emulate many handheld devices. Test there.
I welcoming device name suggestions.
EDIT:
Just don't use this, use feature detection instead.
shareedit
I advise you check out http://wurfl.io/
In a nutshell, if you import a tiny JS file:
<script type='text/javascript' src="//wurfl.io/wurfl.js"></script>
you will be left with a JSON object that looks like:
{
 "complete_device_name":"Google Nexus 7",
 "is_mobile":true,
 "form_factor":"Tablet"
}
(that's assuming you are using a Nexus 7, of course) and you will be able to do things like:
if(WURFL.form_factor == "Tablet"){
    //dostuff();
}
This is what you are looking for.
Disclaimer: I work for the company that offers this free service. Thanks.
shareedit
1 
And howcome this does not recognize safari on iphone ? – Amyth Sep 6 '16 at 2:05
   
Can you expand on what browser you are using (exact UA string would be perfect), what data you are getting and what you are expecting? – Luca Passani Sep 7 '16 at 13:11
what about using "window.screen.width" ?
if (window.screen.width < 800) {
// do something
}
or
if($(window).width() < 800) {
//do something
}
I guess this is the best way because there is a new mobile device every day !
(although I think it's not that supported in old browsers, but give it a try :) )
shareedit
Here is he full function
function isMobile(){
    return (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino|android|ipad|playbook|silk/i.test(navigator.userAgent||navigator.vendor||window.opera)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test((navigator.userAgent||navigator.vendor||window.opera).substr(0,4)))
}

jQuery.noConflict();
jQuery(document).ready(function(){
    if(isMobile()) alert("Mobile"); else alert("Not Mobile");
});
shareedit
   
.substr(0,4) returns first 4 letters. How does it detect "android.+mobile"? – raacer Aug 24 '15 at 21:31
1 
@raacer there are actually two regexes in the answer (both on the same line) - the first one checks against the entire UA string, and looks for android, mobile etc, while the second one only checks against the first 4 characters of the UA. – JackW Aug 27 '15 at 13:45
//true / false
function isMobile()
{
   return (/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent) ); 
}
also you can follow this tutorial to detect a specific mobile. Click here.
shareedit
   
Please add Mobile to your RX – oriadam Jul 11 '16 at 11:05
The best must be :
var isMobile = (/Mobile/i.test(navigator.userAgent));
But like like Yoav Barnea says...
// Seem legit
var isMobile = ('DeviceOrientationEvent' in window || 'orientation' in window);
// But with my Chrome on windows, DeviceOrientationEvent == fct()
if (/Windows NT|Macintosh|Mac OS X|Linux/i.test(navigator.userAgent)) isMobile = false;
// My android have "linux" too
if (/Mobile/i.test(navigator.userAgent)) isMobile = true;
After this 3 tests, i hope var isMobile is... ok
shareedit
   
> Firefox mobile on android doesn't seem to have "'orientation' in window" – molokoloco May 30 '13 at 12:38
1 
Sorry.. ok for me it work well like that now. "if (Modernizr.touch) /* ... */ " and go on... – molokoloco Jun 1 '13 at 13:31 
   
Just wondering how Modernizr.touch would work when on a touchscreen desktop device. – B2K Jul 10 '15 at 14:27
There's no perfect solution for detecting whether JS code is executed on a mobile browser, but the following three options should work in most cases.

Option 1 : browser sniffing

!function(a){var b=/iPhone/i,c=/iPod/i,d=/iPad/i,e=/(?=.*\bAndroid\b)(?=.*\bMobile\b)/i,f=/Android/i,g=/(?=.*\bAndroid\b)(?=.*\bSD4930UR\b)/i,h=/(?=.*\bAndroid\b)(?=.*\b(?:KFOT|KFTT|KFJWI|KFJWA|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|KFARWI|KFASWI|KFSAWI|KFSAWA)\b)/i,i=/IEMobile/i,j=/(?=.*\bWindows\b)(?=.*\bARM\b)/i,k=/BlackBerry/i,l=/BB10/i,m=/Opera Mini/i,n=/(CriOS|Chrome)(?=.*\bMobile\b)/i,o=/(?=.*\bFirefox\b)(?=.*\bMobile\b)/i,p=new RegExp("(?:Nexus 7|BNTV250|Kindle Fire|Silk|GT-P1000)","i"),q=function(a,b){return a.test(b)},r=function(a){var r=a||navigator.userAgent,s=r.split("[FBAN");return"undefined"!=typeof s[1]&&(r=s[0]),s=r.split("Twitter"),"undefined"!=typeof s[1]&&(r=s[0]),this.apple={phone:q(b,r),ipod:q(c,r),tablet:!q(b,r)&&q(d,r),device:q(b,r)||q(c,r)||q(d,r)},this.amazon={phone:q(g,r),tablet:!q(g,r)&&q(h,r),device:q(g,r)||q(h,r)},this.android={phone:q(g,r)||q(e,r),tablet:!q(g,r)&&!q(e,r)&&(q(h,r)||q(f,r)),device:q(g,r)||q(h,r)||q(e,r)||q(f,r)},this.windows={phone:q(i,r),tablet:q(j,r),device:q(i,r)||q(j,r)},this.other={blackberry:q(k,r),blackberry10:q(l,r),opera:q(m,r),firefox:q(o,r),chrome:q(n,r),device:q(k,r)||q(l,r)||q(m,r)||q(o,r)||q(n,r)},this.seven_inch=q(p,r),this.any=this.apple.device||this.android.device||this.windows.device||this.other.device||this.seven_inch,this.phone=this.apple.phone||this.android.phone||this.windows.phone,this.tablet=this.apple.tablet||this.android.tablet||this.windows.tablet,"undefined"==typeof window?this:void 0},s=function(){var a=new r;return a.Class=r,a};"undefined"!=typeof module&&module.exports&&"undefined"==typeof window?module.exports=r:"undefined"!=typeof module&&module.exports&&"undefined"!=typeof window?module.exports=s():"function"==typeof define&&define.amd?define("isMobile",[],a.isMobile=s()):a.isMobile=s()}(this);

alert(isMobile.any ? 'Mobile' : 'Not mobile');
This particular browser sniffing code is that of a library called isMobile.

Option 2 : window.orientation

Test is window.orientation is defined :
alert(typeof window.orientation !== 'undefined' ? 'Mobile' : 'Not mobile');
shareedit
This could also be a solution.
var isMobile = false; //initiate as false

  // device detection
  if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent) 
  || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent.substr(0,4))) isMobile = true;

  console.log('Mobile device:'+isMobile);

  var doc_h = $(document).height(); // returns height of HTML document
  var doc_w = $(document).width(); // returns width of HTML document
  console.log('Height: '+doc_h);
  console.log('width: '+doc_w);

  var iPadVertical = window.matchMedia("(width: 768px) and (height: 1024px) and (orientation: portrait)");
  var iPadHoricontal = window.matchMedia("(width: 1024px) and (height: 767px) and (orientation: landscape)");

  console.log('Height: '+doc_h);
  console.log('width: '+doc_w);

  if (iPadVertical.matches) {
      console.log('Ipad vertical detected');
  }else if (iPadHoricontal.matches){
      console.log('Ipad horicontal detected');
  }else {
      console.log('No Ipad');
  }
If you use both methods, you will get a perfect way to detect different devices.
shareedit
In any case, checking for type of device must be called just ONE TIME: your phone can't surprisingly stay a desktop in a moment :)
So, code for checking by userAgent, suggested here sometime ago, have to be look like that:
(function(a){window.isMobile = (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))})(navigator.userAgent||navigator.vendor||window.opera);

console.info('This is %s device', window.isMoblie ? 'mobile' : 'desktop');
shareedit

Here's an ECMAScript 6 solution (TypeScript ready)
public isMobile(): boolean {
  let check = false;
  ((a => {
      if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) check = true;
      }))(navigator.userAgent || navigator.vendor);
  return check;
 }