整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

推荐20个开源的前端低代码项目

推荐20个开源的前端低代码项目

约2500字,建议阅读9分钟

本文分享几个值得学习和使用的前端低代码开源项目,更深入地了解什么是低代码。

近几年,在技术领域低代码是比较热门的话题,比如阿里云推出了钉钉低代码,通过简单的拖拽、配置,即可完成业务应用的搭建,腾讯云则是推出了微搭,通过行业化模板、拖放式组件和可视化配置快速构建多端应用。

低代码是基于可视化和模型驱动理念,结合云原生与多端体验技术,它能够在多数业务场景下实现大幅度的提效降本,为专业开发者提供了一种全新的高生产力开发范式。下面就来分享几个值得学习和使用的前端低代码开源项目,更深入地了解什么是低代码。

1 Appsmith

Appsmith 是一款开源低代码框架,主要用于构建管理面板、内部工具和仪表板等,允许拖放 UI 组件来构建页面,通过连接到任何 API、数据库或 GraphQL 源,并使用 JavaScript 语言编写逻辑,可以在短时间内创建内部应用程序。

项目链接:https://github.com/appsmithorg/appsmith

最新star:24288


2 LowCodeEngine

LowCodeEngine 由阿里巴巴钉钉宜搭团队开发的低代码框架,基于阿里云的云基础设施和钉钉的企业数字化操作系统。使用者只需要基于低代码引擎便可以快速定制符合自己业务需求的低代码平台。同时LowCodeEngine还提供了很多的基础组件,可以帮助开发者快速地构建业务页面。

项目链接:https://github.com/alibaba/lowcode-demo

最新star:887


3 Amis

Amis 是百度开源的一款前端低代码框架,通过 JSON 配置就能生成各种后台页面,包括数据获取、表单提交及验证等功能,同时,Amis内置 100+ 种 UI 组件,能够满足各种页面组件展现的需求,极大减少开发成本,甚至可以不需要了解前端。amis 在百度内部得到了广泛使用,在 4 年多的时间里创建了 3w 多页面,从内容审核到机器管理,从数据分析到模型训练,amis 满足了各种各样的页面需求。我们可以下载源码,然后使用如下的命令来体验。

项目链接:https://github.com/baidu/amis

最新star:12860


4 tmagic-editor

tmagic-editor是一款由腾讯技术中心出品的一款开源低代码框架,能够实现零代码/低代码生成页面 , 可以快速搭建可视化页面生产平台,让非技术人员可以通过拖拽和配置,自助生成H5页面、PC页面、TV页面,大大降低页面生产成本 。

项目链接:https://github.com/Tencent/tmagic-editor

最新star:3112


5 dooring-electron-lowcode

dooring-electron-lowcode是一款功能强大,专业可靠的可视化页面配置解决方案,致力于提供一套简单方便、专业可靠、无限可能的H5落地页最佳实践。技术栈以react和typescript为主, 后台采用nodejs开发, electron作为桌面端基础方案。

项目链接:https://github.com/H5-Dooring/dooring-electron-lowcode

最新star:150


6 vite-vue3-lowcode

vite-vue3-lowcode 是一款基于Vite2.x + Vue3.x + TypeScript技术框架的的H5 低代码平台。目前只是一个简单的模板,支持数据配置的导入和导出,配置的修改和删除操作,用到的技术有sandbox 中执行自定义逻辑、monaco-editor 自定义代码补全、vue3 createRenderer 自定义渲染器等。

项目链接:https://github.com/buqiyuan/vite-vue3-lowcode

最新star:2158


7 shida

shida是一个视频可视化搭建项目,开发者可以通过拖拽就可以快速地生产一个短视频,使用方式就像易企秀或百度 H5 等 h5 低代码平台一样。shida的后端视频合成部分是基于FFCreator进行开发的,FFCreator 是一个基于 node.js 的轻量、灵活的短视频加工库,只需要添加几张图片或视频片段再加一段背景音乐,就可以快速生成一个很酷的视频短片。

项目链接:https://github.com/tnfe/shida

最新star:363


8 quark-h5

quark-h5是一个使用Vue + Koa的前端低代码框架,和大多数的前端低代码框架一样,采用的是编辑器生成页面JSON数据,服务端负责存取JSON数据,渲染时从服务端取数据JSON交给前端模板处理。

项目链接:https://github.com/huangwei9527/quark-h5

最新star:3064


9 gods-pen

码良是一个在线生成 H5 页面并提供页面管理和页面编辑的平台,用于快速制作 H5 页面。用户无需掌握复杂的编程技术,通过简单拖拽、少量配置即可制作精美的页面,可用于营销场景下的页面制作。同时,也为开发者提供了完备的编程接入能力,通过脚本和组件的形式获得强大的组件行为和交互控制能力。

项目链接:https://github.com/ymm-tech/gods-pen

最新star:4247


10 luban-h5

鲁班H5是基于Vue2.0开发的支持拖拽方式来快速生成页面的低代码平台,功能基本类似于易企秀、Maka、百度等H5平台。

项目链接:https://github.com/ly525/luban-h5

最新star:5654


11 mometa

mometa 并不是传统主流的低代码平台(如 amis),mometa 是面向研发、代码可视设计编辑平台,更像是 dreamweaver、gui的可视编辑 工具。借助它,我们可以获得所见即所得的可视编辑开发体验。

项目链接:https://github.com/imcuttle/mometa

最新star:3469


12 h5-factory

h5-factory是专题页面可视化编辑工具,可以通过拖拽来设计页面,并且支持一键生成html文件。

项目链接:https://github.com/xuhaiqing/h5-factory

最新star:6


13 steedos-platform

steedos-platform是 Salesforce 低代码平台的开源替代方案,使用可视化工具进行模型设计, 页面设计, 流程设计, 报表设计,只需点击鼠标,就能快速创建应用程序,实现敏捷开发的新高度。在技术实现细节上,steedos-platform使用元数据定义对象,字段,配置,代码,逻辑和页面布局,并基于这些元数据自动生成系统的数据结构以及Steedos应用程序的用户界面和自动化逻辑。

项目链接:https://github.com/steedos/steedos-platform/

最新star:951


14 lz-h5-edit

lz-h5-edit是一个H5低代码编辑平台,支持拖拽、缩放、旋转、动画、撤销、重做、组合元素等方式来创建H5页面。

项目链接:https://github.com/lzuntalented/lz-h5-edit

最新star:462


15 tefact

星搭开源无代码编辑器,使用图形化界面生成 网站、H5和表单,无需任何代码即可生成应用程序。

项目链接:https://github.com/staringos/tefact/

最新star:244


16 fast-poster

fast-poster是一款使用Python+Vue开发的通用海报生成器,可以用来快速地生成海报。使用时只需要经过三步即可生成所需要的海报:启动服务 > 编辑海报 > 生成代码。

项目链接:https://github.com/psoho/fast-poster

最新star:408


17 openDataV

OpenDataV 是一款基于Vue3 + vite + TypeScript开发前端可视化低代码平台。支持拖拽式、可视化、低代码数据可视化开发,你可以用它自由的拼接成各种炫酷的大屏,同时支持接入开发者自己开发的组件接入平台。

项目链接:https://github.com/AnsGoo/openDataV

最新star:196


18 mall-cook

Mall-Cook 是一个基于 vue 开发的可视化商城搭建平台,包括多页面可视化构建、Json Schema 生成器(可视化搭建物料控制面板),实现组件流水线式标准接入平台。最新版本使用 uni-app 重构物料、模板项目,支持生成 H5、小程序多端商城。

项目链接:https://github.com/wangyuan389/mall-cook

最新star:3632


19 form-generator

form-generator是一个基于Element UI表单设计及代码生成器,可将生成的代码直接运行在基于Element的vue项目中,也可导出JSON表单,使用配套的解析器将JSON解析成真实的表单。

项目链接:https://github.com/JakHuang/form-generator

最新star:7482


20 vjdesign

vjdesign是一款支持任何 vue 项目中的组件,不需要二次开发就可以定义支持的组件以及组件的属性,并且对组件的属性和数据的关系以及表单的交互行为也可以通过设计器配置实现。

项目链接:https://github.com/fyl080801/vjdesign

最新star:384

nillawebprojects里面是一些使用HTML5、CSS和JavaScript构建的小型项目。


推荐原因:vanillawebprojects这个项目很适合前端新手学习,每一个小项目都同时使用到了HTML+CSS+JS,这是前端最基础的内容,扎实的掌握了前端三件套之后,对以后学习前端框架会有很大的帮助。里面一共包含了20个小项目,学会这几个项目,相信你对HTML、CSS和JS会有一个更深刻的认知。


GitHub地址:https://github.com/bradtraversy/vanillawebprojects



JavaScript是最好的语言之一,尤其是在前端开发中。在本文中,您将找到7个为初学者提供免费源代码的最佳javascript项目。

手把手教你7个有趣的JavaScript 项目-上「附源码」(本篇)

手把手教你7个有趣的JavaScript 项目-下「附源码」


1.使用JavaScript创建待办事项列表应用



如果您是javascript语言的初学者,则待办事项列表应用程序是最好的和最容易的应用程序之一,如果您使用HTML CSS和一点点的javascript,则可以创建此简单的待办事项列表应用程序,您将找到源代码这个js项目的底部。

<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>创建待办事项列表应用</title>
<style type="text/css">
$primary: #313e50;
$grey: #cdcdcd;
$secondary: #1dd2af;

%reset {
    margin: 0;
    padding: 0;
    border: none;
    outline: none;
    background: transparent;
}

%transition {
    transition: all 0.2s ease;
    -webkit-transition: all 0.2s ease;
}

body {
    background: #f1f1f1;
    margin-top: 2rem;
}

/*PEN STYLES*/
.tasker {
    max-width: 400px;
    margin: 0 auto;
    .error {
        display: none;
        background: rgba(237, 28, 36, 0.7);
        color: #fff;
        padding: 14px;
        margin-bottom: 10px;
        border-radius: 5px;
        text-align: center;
    }

    ul {
        @extend %reset;
        background: #fff;
    }

    li,
    .error,
    button,
    input {
        @extend %reset;
        font: 18px/1.25em Helvetica, Arial, Sans-serif;
    }
}

.tasker-header {
    display: inline-flex;
    background: $primary;
    justify-content: space-between;
    width: 100%;
    input,
    button {
        color: #fff;
        box-sizing: border-box;
        font-size: 1.25em;
        padding: 14px;
    }

    input {
        flex-grow: 2;
    }

    button {
        @extend %transition;
        background: $secondary;
        border-left: 1px solid ($secondary * 1.05);
        &:hover {
            background: $secondary * 1.1;
        }
    }
}

.tasker-body {
    .task {
        display: block;
        position: relative;
        padding: 14px 40px 14px 14px;
        border-bottom: 1px solid rgba(0, 0, 0, 0.1);
        &:last-child {
            border-bottom: none;
        }

        &:hover > button {
            opacity: 1;
        }

        &.completed {
            color: $grey;
            text-decoration: line-through;
        }

        input {
            margin-right: 10px;
        }

        button {
            @extend %transition;
            color: $grey;
            margin: 14px;
            position: absolute;
            top: 0;
            right: 0;
            opacity: 0;
            &:hover {
                color: #ed1c24;
            }
        }
    }
}
</style>
</head>
<body>
<!--PEN CODE-->
<div id="tasker" class="tasker">
    <div id="error" class="error">Please enter a task</div>
    <div id="tasker-header" class="tasker-header">
        <input type="text" id="input-task" placeholder="Enter a task">
        <button id="add-task-btn"><i class="fa fa-fw fa-plus"></i>
        </button>
    </div>
    <div class="tasker-body">
        <ul id="tasks"></ul>
    </div>
</div>
<!--END PEN CODE-->
<script type="text/javascript">
(function() {
    'use strict';
    var tasker={
        init: function() {
            this.cacheDom();
            this.bindEvents();
            this.evalTasklist();
        },
        cacheDom: function() {
            this.taskInput=document.getElementById("input-task");
            this.addBtn=document.getElementById("add-task-btn");
            this.tasklist=document.getElementById("tasks");
            this.tasklistChildren=this.tasklist.children;
            this.errorMessage=document.getElementById("error");
        },
        bindEvents: function() {
            this.addBtn.onclick=this.addTask.bind(this);
            this.taskInput.onkeypress=this.enterKey.bind(this);
        },
        evalTasklist: function() {
            var i, chkBox, delBtn;
            //BIND CLICK EVENTS TO ELEMENTS
            for (i=0; i < this.tasklistChildren.length; i +=1) {
                //ADD CLICK EVENT TO CHECKBOXES
                chkBox=this.tasklistChildren[i].getElementsByTagName("input")[0];
                chkBox.onclick=this.completeTask.bind(this, this.tasklistChildren[i], chkBox);
                //ADD CLICK EVENT TO DELETE BUTTON
                delBtn=this.tasklistChildren[i].getElementsByTagName("button")[0];
                delBtn.onclick=this.delTask.bind(this, i);
            }
        },
        render: function() {
            var taskLi, taskChkbx, taskVal, taskBtn, taskTrsh;
            //BUILD HTML
            taskLi=document.createElement("li");
            taskLi.setAttribute("class", "task");
            //CHECKBOX
            taskChkbx=document.createElement("input");
            taskChkbx.setAttribute("type", "checkbox");
            //USER TASK
            taskVal=document.createTextNode(this.taskInput.value);
            //DELETE BUTTON
            taskBtn=document.createElement("button");
            //TRASH ICON
            taskTrsh=document.createElement("i");
            taskTrsh.setAttribute("class", "fa fa-trash");
            //INSTERT TRASH CAN INTO BUTTON
            taskBtn.appendChild(taskTrsh);

            //APPEND ELEMENTS TO TASKLI
            taskLi.appendChild(taskChkbx);
            taskLi.appendChild(taskVal);
            taskLi.appendChild(taskBtn);

            //ADD TASK TO TASK LIST
            this.tasklist.appendChild(taskLi);

        },
        completeTask: function(i, chkBox) {
            if (chkBox.checked) {
                i.className="task completed";
            } else {
                this.incompleteTask(i);
            }
        },
        incompleteTask: function(i) {
            i.className="task";
        },
        enterKey: function(event) {
            if (event.keyCode===13 || event.which===13) {
                this.addTask();
            }
        },
        addTask: function() {
            var value=this.taskInput.value;
            this.errorMessage.style.display="none";

            if (value==="") {
                this.error();
            } else {
                this.render();
                this.taskInput.value="";
                this.evalTasklist();
            }
        },
        delTask: function(i) {
            this.tasklist.children[i].remove();
            this.evalTasklist();
        },
        error: function() {
            this.errorMessage.style.display="block";
        }
    };

    tasker.init();
}());
</script>
</body>
</html>

2.使用JavaScript和CSS创建垂直时间轴(里程碑)



您可以使用javascript初学者创建的第二个小项目是时间轴,许多现代网站都使用该时间轴使网站更具交互性和动态性。

<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>CSS创建垂直时间轴(里程碑)</title>
<style type="text/css">
*,
*::before,
*::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font: normal 16px/1.5 "Helvetica Neue", sans-serif;
  background: #456990;
  color: #fff;
  overflow-x: hidden;
  padding-bottom: 50px;
}  /* INTRO SECTION
–––––––––––––––––––––––––––––––––––––––––––––––––– */

.intro {
  background: #F45B69;
  padding: 100px 0;
}

.container {
  width: 90%;
  max-width: 1200px;
  margin: 0 auto;
  text-align: center;
}

h1 {
  font-size: 2.5rem;
}


/* TIMELINE
–––––––––––––––––––––––––––––––––––––––––––––––––– */

.timeline ul {
  background: #456990;
  padding: 50px 0;
}

.timeline ul li {
  list-style-type: none;
  position: relative;
  width: 6px;
  margin: 0 auto;
  padding-top: 50px;
  background: #fff;
}

.timeline ul li::after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: 0;
  transform: translateX(-50%);
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: inherit;
}

.timeline ul li div {
  position: relative;
  bottom: 0;
  width: 400px;
  padding: 15px;
  background: #F45B69;
}

.timeline ul li div::before {
  content: '';
  position: absolute;
  bottom: 7px;
  width: 0;
  height: 0;
  border-style: solid;
}

.timeline ul li:nth-child(odd) div {
  left: 45px;
}

.timeline ul li:nth-child(odd) div::before {
  left: -15px;
  border-width: 8px 16px 8px 0;
  border-color: transparent #F45B69 transparent transparent;
}

.timeline ul li:nth-child(even) div {
  left: -439px;
}

.timeline ul li:nth-child(even) div::before {
  right: -15px;
  border-width: 8px 0 8px 16px;
  border-color: transparent transparent transparent #F45B69;
}

time {
  display: block;
  font-size: 1.2rem;
  font-weight: bold;
  margin-bottom: 8px;
}


/* EFFECTS
–––––––––––––––––––––––––––––––––––––––––––––––––– */

.timeline ul li::after {
  transition: background .5s ease-in-out;
}

.timeline ul li.in-view::after {
  background: #F45B69;
}

.timeline ul li div {
  visibility: hidden;
  opacity: 0;
  transition: all .5s ease-in-out;
}

.timeline ul li:nth-child(odd) div {
  transform: translate3d(200px, 0, 0);
}

.timeline ul li:nth-child(even) div {
  transform: translate3d(-200px, 0, 0);
}

.timeline ul li.in-view div {
  transform: none;
  visibility: visible;
  opacity: 1;
}


/* GENERAL MEDIA QUERIES
–––––––––––––––––––––––––––––––––––––––––––––––––– */

@media screen and (max-width: 900px) {
  .timeline ul li div {
    width: 250px;
  }
  .timeline ul li:nth-child(even) div {
    left: -289px;
    /*250+45-6*/
  }
}

@media screen and (max-width: 600px) {
  .timeline ul li {
    margin-left: 20px;
  }
  .timeline ul li div {
    width: calc(100vw - 91px);
  }
  .timeline ul li:nth-child(even) div {
    left: 45px;
  }
  .timeline ul li:nth-child(even) div::before {
    left: -15px;
    border-width: 8px 16px 8px 0;
    border-color: transparent #F45B69 transparent transparent;
  }
}
</style>
</head>
<body>
<section class="intro">
  <div class="container">
    <h1>Vertical Timeline ↓</h1>
  </div>
</section>

<section class="timeline">
  <ul>
    <li>
      <div>
        <time>1934</time> demo1
      </div>
    </li>
    <li>
      <div>
        <time>1937</time> demo1
      </div>
    </li>
    <li>
      <div>
        <time>1940</time> demo1
      </div>
    </li>
    <li>
      <div>
        <time>1943</time> demo1
      </div>
    </li>
    <li>
      <div>
        <time>1946</time> demo1
      </div>
    </li>
    <li>
      <div>
        <time>1956</time> demo1
      </div>
    </li>
    <li>
      <div>
        <time>1957</time> demo1
      </div>
    </li>
    <li>
      <div>
        <time>1967</time>demo1
      </div>
    </li>
    <li>
      <div>
        <time>1977</time> demo1
      </div>
    </li>
    <li>
      <div>
        <time>1985</time> demo1
      </div>
    </li>
    <li>
      <div>
        <time>2000</time> demo1
      </div>
    </li>
    <li>
      <div>
        <time>2005</time> demo1
      </div>
    </li>
  </ul>
</section>
<script type="text/javascript">
(function() {

  'use strict';

  // define variables
  var items=document.querySelectorAll(".timeline li");

  // check if an element is in viewport
  // http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport
  function isElementInViewport(el) {
    var rect=el.getBoundingClientRect();
    return (
      rect.top >=0 &&
      rect.left >=0 &&
      rect.bottom <=(window.innerHeight || document.documentElement.clientHeight) &&
      rect.right <=(window.innerWidth || document.documentElement.clientWidth)
    );
  }

  function callbackFunc() {
    for (var i=0; i < items.length; i++) {
      if (isElementInViewport(items[i])) {
        items[i].classList.add("in-view");
      }
    }
  }

  // listen for events
  window.addEventListener("load", callbackFunc);
  window.addEventListener("resize", callbackFunc);
  window.addEventListener("scroll", callbackFunc);

})();
</script>
</body>
</html>

3.用JavaScript构建一个简单的井字游戏



如果您想构建简单而有趣的东西来练习JavaScript知识,那么使用HTML CSS和JS创建TIC TAC TOE游戏对您来说是个不错的选择,该游戏虽然简单但并不容易,因此您需要专注于该项目的逻辑方面,因为它是该项目最具挑战性的部分。

<html>
    <head>
      <meta charset="utf-8" />
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="description" content="">
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <title>FreeCodeCamp: Tictactoe</title>
<style type="text/css">
@import url(https://fonts.googleapis.com/css?family=Yesteryear);
$app-background-color : #508ABB;
$app-row-height : 100%;
$winAnimStartColor : cyan;
$winAnimEndColor : #508ABB;

// html, body, div, span, a, li, td, th {
//  font-family: 'Lato', sans-serif;
//  font-weight: 300;
//
// }

@-webkit-keyframes winAnim{
    0% {
    background-color: $winAnimStartColor;
  }
  100% {
    background-color: $winAnimEndColor;
  }
}
@-moz-keyframes winAnim{
  0% {
    background-color: $winAnimStartColor;
  }
  100% {
    background-color: $winAnimEndColor;
  }
}
@-o-keyframes winAnim {
  0% {
    background-color: $winAnimStartColor;
  }
  100% {
    background-color: $winAnimEndColor;
  }
}
@keyframes winAnim {
  0% {
    background-color: $winAnimStartColor;
  }
  100% {
    background-color: $winAnimEndColor;
  }
}

@keyframes winAnim {
  0% {
    background-color: $winAnimStartColor;
  }
  100% {
    background-color: $winAnimEndColor;
  }
}

*{
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  outline-style:none;/*IE*/
}

.center-box{
    margin : auto;
    position: absolute;
    top : 0;
    right : 0;
    bottom : 0;
    left : 0;
}

html,body{
    //background-image: linear-gradient(to bottom,#dddbd1,#d2dbdc);
    background-color: #d2dbdc;
    height : 100%;
    width  : 100%;
}

.app{
    @extend .center-box;
    width : 80%;
    height : 70%;
    max-width: 550px;
    background-color : $app-background-color;
    box-shadow: 0 5px 30px -5px rgba(0,0,0, .85);
    border-radius: 10px;
    .app-container,
    .app-row{
        height: $app-row-height;
    }
}
.play-box,.symbol-option{
    font-family: 'Yesteryear', cursive;
}

.play-box{
    border-bottom : 2px solid #fff;
    border-right : 2px solid #fff;
    height : $app-row-height / 3;
    cursor: pointer;
    position: relative;
    &.last-right{
        border-right : none;
    }
    &.last-bottom{
        border-bottom : none;
    }
    &.win {
        -webkit-animation: winAnim .2s ease-out infinite;
      -moz-animation:    winAnim .2s ease-out infinite;
      -o-animation:      winAnim .2s ease-out infinite;
      animation:         winAnim .2s ease-out infinite;
        animation : winAnim .5s infinite;
    }
    .symbol{
        @extend .center-box;
        width: 50%;
        height : 50px;
        text-align: center;
        line-height : 50px;
        font-size: 35px;
        color : white;
    }
}

.modal-content{
    .content{
        padding : 15px;
        text-align: center;
        margin : 0;
        &.body{
            line-height: 2;
        }
    }
    .symbol-options{
        width: 200px;
        margin-top: 10px;
        .symbol-option{
            &:first-child{
                margin-right: 10px;
            }
            &:last-child{
                margin-left: 10px;
            }
        }
    }
    .warning-hr{
        margin: 0;
    }
}
</style>
    </head>

    <body>
        <div class="app">
            <div class="container-fluid app-container">
            <div class="row app-row">
                <div class="col-xs-4 play-box" id="0">
                    <div class="symbol"></div>
                </div>
                <div class="col-xs-4 play-box" id="1">
                    <div class="symbol"></div>
                </div>
                <div class="col-xs-4 play-box last-right" id="2">
                    <div class="symbol"></div>
                </div>
                <div class="col-xs-4 play-box" id="3">
                    <div class="symbol"></div>
                </div>
                <div class="col-xs-4 play-box" id="4">
                    <div class="symbol"></div>
                </div>
                <div class="col-xs-4 play-box last-right" id="5">
                    <div class="symbol"></div>
                </div>
                <div class="col-xs-4 play-box last-bottom" id="6">
                    <div class="symbol"></div>
                </div>
                <div class="col-xs-4 play-box last-bottom" id="7">
                    <div class="symbol"></div>
                </div>
                <div class="col-xs-4 play-box last-right last-bottom" id="8">
                    <div class="symbol"></div>
                </div>
            </div>
            </div>
        </div>

        <div class="modal fade app-modal" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel">
          <div class="modal-dialog modal-size">
            <div class="modal-content">
              <h3 class="content heading">Warning!!!</h3>
              <hr class="warning-hr">
              <div class="content body">
                  Please save your time and don't even think you're smart. <br><strong><em>I'M SMARTER THAN YOU! HA-HA-HA!!!</em></strong> <br>
                  Wana try me? Chose : <br>
                  <div class="center-block symbol-options">
                    <button class="symbol-option btn btn-default btn-md" data-dismiss="modal">X</button> OR <button class="symbol-option btn btn-default btn-md" data-dismiss="modal">O</button>
                  </div>
              </div>
            </div>
          </div>
        </div>
<script src="../js/bundled/tictactoe.bundled.js">
        </script>
    </body>
</html>

4.创建一个JavaScript倒数计时器开始停止重置



许多现代网站和博客都使用倒数计时器来显示倒数,例如,我们通过使用倒数计时器来告诉在线商店的访问者,商品价格将在价格上涨后增加销售量。具体时间。

<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>CSS创建垂直时间轴(里程碑)</title>
<style type="text/css">
 /* Variabes */  
$orange: #ffa600;
$grey:#f3f3f3;
$white: #fff;
$base-color:$orange ;


/* Mixin's */  
@mixin transition {
-webkit-transition: all 0.5s ease-in-out;
-moz-transition: all 0.5s ease-in-out;
transition: all 0.5s ease-in-out;
}
@mixin corners ($radius) {
-moz-border-radius: $radius;
-webkit-border-radius: $radius;
border-radius: $radius; 
-khtml-border-radius: $radius; 
}

body {
background:$base-color;
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; 
height:100%;
}

.wrapper {
width: 800px;
margin: 30px auto;
color:$white;
text-align:center;
}

h1, h2, h3 {
  font-family: 'Roboto', sans-serif;
  font-weight: 100;
  font-size: 2.6em;
  text-transform: uppercase;
}

#seconds, #tens{
  font-size:2em;
}

button{
@include corners (5px);
background:$base-color;
color:$white;
border: solid 1px $white;
text-decoration:none;
cursor:pointer;
font-size:1.2em;
padding:18px 10px;
width:180px;
margin: 10px;
 outline: none;
  &:hover{
    @include transition;
    background:$white;
    border: solid 1px $white;
    color:$base-color;
    }
} 
</style>
    </head>
<body>
<div class="wrapper">
<h1>Stopwatch</h1>
<h2>Vanilla JavaScript Stopwatch</h2>
<p><span id="seconds">00</span>:<span id="tens">00</span></p>
<button id="button-start">Start</button>
<button id="button-stop">Stop</button>
<button id="button-reset">Reset</button>
</div> 
<script type="text/javascript">
  window.onload=function () {
  
  var seconds=00; 
  var tens=00; 
  var appendTens=document.getElementById("tens")
  var appendSeconds=document.getElementById("seconds")
  var buttonStart=document.getElementById('button-start');
  var buttonStop=document.getElementById('button-stop');
  var buttonReset=document.getElementById('button-reset');
  var Interval ;

  buttonStart.onclick=function() {
    
     clearInterval(Interval);
     Interval=setInterval(startTimer, 10);
  }
  
    buttonStop.onclick=function() {
       clearInterval(Interval);
  }
  

  buttonReset.onclick=function() {
     clearInterval(Interval);
    tens="00";
    seconds="00";
    appendTens.innerHTML=tens;
    appendSeconds.innerHTML=seconds;
  }
  
   
  
  function startTimer () {
    tens++; 
    
    if(tens < 9){
      appendTens.innerHTML="0" + tens;
    }
    
    if (tens > 9){
      appendTens.innerHTML=tens;
      
    } 
    
    if (tens > 99) {
      console.log("seconds");
      seconds++;
      appendSeconds.innerHTML="0" + seconds;
      tens=0;
      appendTens.innerHTML="0" + 0;
    }
    
    if (seconds > 9){
      appendSeconds.innerHTML=seconds;
    }
  
  }<script src="../js/bundled/tictactoe.bundled.js">
        </script>

}

 </script>
    </body>
</html>

5.用JavaScript创建一个简单的乒乓球游戏



我可以用JavaScript构建游戏吗?答案是肯定的,使用javascript甚至可以创建复杂的游戏,但是在这种情况下,我们将专注于一个简单的游戏,该游戏可让您练习HTML CSS和javascript技能。

<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>使用js调用设备摄像头并实现拍照</title>
<style type="text/css">
  body {
    text-align: center;
}
  </style>
</head>
<body>
    <script type="text/javascript">
      // Global Variables
var DIRECTION={
    IDLE: 0,
    UP: 1,
    DOWN: 2,
    LEFT: 3,
    RIGHT: 4
};

var rounds=[5, 5, 3, 3, 2];
var colors=['#1abc9c', '#2ecc71', '#3498db', '#e74c3c', '#9b59b6'];

// The ball object (The cube that bounces back and forth)
var Ball={
    new: function (incrementedSpeed) {
        return {
            width: 18,
            height: 18,
            x: (this.canvas.width / 2) - 9,
            y: (this.canvas.height / 2) - 9,
            moveX: DIRECTION.IDLE,
            moveY: DIRECTION.IDLE,
            speed: incrementedSpeed || 9
        };
    }
};

// The paddle object (The two lines that move up and down)
var Paddle={
    new: function (side) {
        return {
            width: 18,
            height: 70,
            x: side==='left' ? 150 : this.canvas.width - 150,
            y: (this.canvas.height / 2) - 35,
            score: 0,
            move: DIRECTION.IDLE,
            speed: 10
        };
    }
};

var Game={
    initialize: function () {
        this.canvas=document.querySelector('canvas');
        this.context=this.canvas.getContext('2d');

        this.canvas.width=1400;
        this.canvas.height=1000;

        this.canvas.style.width=(this.canvas.width / 2) + 'px';
        this.canvas.style.height=(this.canvas.height / 2) + 'px';

        this.player=Paddle.new.call(this, 'left');
        this.paddle=Paddle.new.call(this, 'right');
        this.ball=Ball.new.call(this);

        this.paddle.speed=8;
        this.running=this.over=false;
        this.turn=this.paddle;
        this.timer=this.round=0;
        this.color='#2c3e50';

        Pong.menu();
        Pong.listen();
    },

    endGameMenu: function (text) {
        // Change the canvas font size and color
        Pong.context.font='50px Courier New';
        Pong.context.fillStyle=this.color;

        // Draw the rectangle behind the 'Press any key to begin' text.
        Pong.context.fillRect(
            Pong.canvas.width / 2 - 350,
            Pong.canvas.height / 2 - 48,
            700,
            100
        );

        // Change the canvas color;
        Pong.context.fillStyle='#ffffff';

        // Draw the end game menu text ('Game Over' and 'Winner')
        Pong.context.fillText(text,
            Pong.canvas.width / 2,
            Pong.canvas.height / 2 + 15
        );

        setTimeout(function () {
            Pong=Object.assign({}, Game);
            Pong.initialize();
        }, 3000);
    },

    menu: function () {
        // Draw all the Pong objects in their current state
        Pong.draw();

        // Change the canvas font size and color
        this.context.font='50px Courier New';
        this.context.fillStyle=this.color;

        // Draw the rectangle behind the 'Press any key to begin' text.
        this.context.fillRect(
            this.canvas.width / 2 - 350,
            this.canvas.height / 2 - 48,
            700,
            100
        );

        // Change the canvas color;
        this.context.fillStyle='#ffffff';

        // Draw the 'press any key to begin' text
        this.context.fillText('Press any key to begin',
            this.canvas.width / 2,
            this.canvas.height / 2 + 15
        );
    },

    // Update all objects (move the player, paddle, ball, increment the score, etc.)
    update: function () {
        if (!this.over) {
            // If the ball collides with the bound limits - correct the x and y coords.
            if (this.ball.x <=0) Pong._resetTurn.call(this, this.paddle, this.player);
            if (this.ball.x >=this.canvas.width - this.ball.width) Pong._resetTurn.call(this, this.player, this.paddle);
            if (this.ball.y <=0) this.ball.moveY=DIRECTION.DOWN;
            if (this.ball.y >=this.canvas.height - this.ball.height) this.ball.moveY=DIRECTION.UP;

            // Move player if they player.move value was updated by a keyboard event
            if (this.player.move===DIRECTION.UP) this.player.y -=this.player.speed;
            else if (this.player.move===DIRECTION.DOWN) this.player.y +=this.player.speed;

            // On new serve (start of each turn) move the ball to the correct side
            // and randomize the direction to add some challenge.
            if (Pong._turnDelayIsOver.call(this) && this.turn) {
                this.ball.moveX=this.turn===this.player ? DIRECTION.LEFT : DIRECTION.RIGHT;
                this.ball.moveY=[DIRECTION.UP, DIRECTION.DOWN][Math.round(Math.random())];
                this.ball.y=Math.floor(Math.random() * this.canvas.height - 200) + 200;
                this.turn=null;
            }

            // If the player collides with the bound limits, update the x and y coords.
            if (this.player.y <=0) this.player.y=0;
            else if (this.player.y >=(this.canvas.height - this.player.height)) this.player.y=(this.canvas.height - this.player.height);

            // Move ball in intended direction based on moveY and moveX values
            if (this.ball.moveY===DIRECTION.UP) this.ball.y -=(this.ball.speed / 1.5);
            else if (this.ball.moveY===DIRECTION.DOWN) this.ball.y +=(this.ball.speed / 1.5);
            if (this.ball.moveX===DIRECTION.LEFT) this.ball.x -=this.ball.speed;
            else if (this.ball.moveX===DIRECTION.RIGHT) this.ball.x +=this.ball.speed;

            // Handle paddle (AI) UP and DOWN movement
            if (this.paddle.y > this.ball.y - (this.paddle.height / 2)) {
                if (this.ball.moveX===DIRECTION.RIGHT) this.paddle.y -=this.paddle.speed / 1.5;
                else this.paddle.y -=this.paddle.speed / 4;
            }
            if (this.paddle.y < this.ball.y - (this.paddle.height / 2)) {
                if (this.ball.moveX===DIRECTION.RIGHT) this.paddle.y +=this.paddle.speed / 1.5;
                else this.paddle.y +=this.paddle.speed / 4;
            }

            // Handle paddle (AI) wall collision
            if (this.paddle.y >=this.canvas.height - this.paddle.height) this.paddle.y=this.canvas.height - this.paddle.height;
            else if (this.paddle.y <=0) this.paddle.y=0;

            // Handle Player-Ball collisions
            if (this.ball.x - this.ball.width <=this.player.x && this.ball.x >=this.player.x - this.player.width) {
                if (this.ball.y <=this.player.y + this.player.height && this.ball.y + this.ball.height >=this.player.y) {
                    this.ball.x=(this.player.x + this.ball.width);
                    this.ball.moveX=DIRECTION.RIGHT;

                    beep1.play();
                }
            }

            // Handle paddle-ball collision
            if (this.ball.x - this.ball.width <=this.paddle.x && this.ball.x >=this.paddle.x - this.paddle.width) {
                if (this.ball.y <=this.paddle.y + this.paddle.height && this.ball.y + this.ball.height >=this.paddle.y) {
                    this.ball.x=(this.paddle.x - this.ball.width);
                    this.ball.moveX=DIRECTION.LEFT;

                    beep1.play();
                }
            }
        }

        // Handle the end of round transition
        // Check to see if the player won the round.
        if (this.player.score===rounds[this.round]) {
            // Check to see if there are any more rounds/levels left and display the victory screen if
            // there are not.
            if (!rounds[this.round + 1]) {
                this.over=true;
                setTimeout(function () { Pong.endGameMenu('Winner!'); }, 1000);
            } else {
                // If there is another round, reset all the values and increment the round number.
                this.color=this._generateRoundColor();
                this.player.score=this.paddle.score=0;
                this.player.speed +=0.5;
                this.paddle.speed +=1;
                this.ball.speed +=1;
                this.round +=1;

                beep3.play();
            }
        }
        // Check to see if the paddle/AI has won the round.
        else if (this.paddle.score===rounds[this.round]) {
            this.over=true;
            setTimeout(function () { Pong.endGameMenu('Game Over!'); }, 1000);
        }
    },

    // Draw the objects to the canvas element
    draw: function () {
        // Clear the Canvas
        this.context.clearRect(
            0,
            0,
            this.canvas.width,
            this.canvas.height
        );

        // Set the fill style to black
        this.context.fillStyle=this.color;

        // Draw the background
        this.context.fillRect(
            0,
            0,
            this.canvas.width,
            this.canvas.height
        );

        // Set the fill style to white (For the paddles and the ball)
        this.context.fillStyle='#ffffff';

        // Draw the Player
        this.context.fillRect(
            this.player.x,
            this.player.y,
            this.player.width,
            this.player.height
        );

        // Draw the Paddle
        this.context.fillRect(
            this.paddle.x,
            this.paddle.y,
            this.paddle.width,
            this.paddle.height
        );

        // Draw the Ball
        if (Pong._turnDelayIsOver.call(this)) {
            this.context.fillRect(
                this.ball.x,
                this.ball.y,
                this.ball.width,
                this.ball.height
            );
        }

        // Draw the net (Line in the middle)
        this.context.beginPath();
        this.context.setLineDash([7, 15]);
        this.context.moveTo((this.canvas.width / 2), this.canvas.height - 140);
        this.context.lineTo((this.canvas.width / 2), 140);
        this.context.lineWidth=10;
        this.context.strokeStyle='#ffffff';
        this.context.stroke();

        // Set the default canvas font and align it to the center
        this.context.font='100px Courier New';
        this.context.textAlign='center';

        // Draw the players score (left)
        this.context.fillText(
            this.player.score.toString(),
            (this.canvas.width / 2) - 300,
            200
        );

        // Draw the paddles score (right)
        this.context.fillText(
            this.paddle.score.toString(),
            (this.canvas.width / 2) + 300,
            200
        );

        // Change the font size for the center score text
        this.context.font='30px Courier New';

        // Draw the winning score (center)
        this.context.fillText(
            'Round ' + (Pong.round + 1),
            (this.canvas.width / 2),
            35
        );

        // Change the font size for the center score value
        this.context.font='40px Courier';

        // Draw the current round number
        this.context.fillText(
            rounds[Pong.round] ? rounds[Pong.round] : rounds[Pong.round - 1],
            (this.canvas.width / 2),
            100
        );
    },

    loop: function () {
        Pong.update();
        Pong.draw();

        // If the game is not over, draw the next frame.
        if (!Pong.over) requestAnimationFrame(Pong.loop);
    },

    listen: function () {
        document.addEventListener('keydown', function (key) {
            // Handle the 'Press any key to begin' function and start the game.
            if (Pong.running===false) {
                Pong.running=true;
                window.requestAnimationFrame(Pong.loop);
            }

            // Handle up arrow and w key events
            if (key.keyCode===38 || key.keyCode===87) Pong.player.move=DIRECTION.UP;

            // Handle down arrow and s key events
            if (key.keyCode===40 || key.keyCode===83) Pong.player.move=DIRECTION.DOWN;
        });

        // Stop the player from moving when there are no keys being pressed.
        document.addEventListener('keyup', function (key) { Pong.player.move=DIRECTION.IDLE; });
    },

    // Reset the ball location, the player turns and set a delay before the next round begins.
    _resetTurn: function(victor, loser) {
        this.ball=Ball.new.call(this, this.ball.speed);
        this.turn=loser;
        this.timer=(new Date()).getTime();

        victor.score++;
        beep2.play();
    },

    // Wait for a delay to have passed after each turn.
    _turnDelayIsOver: function() {
        return ((new Date()).getTime() - this.timer >=1000);
    },

    // Select a random color as the background of each level/round.
    _generateRoundColor: function () {
        var newColor=colors[Math.floor(Math.random() * colors.length)];
        if (newColor===this.color) return Pong._generateRoundColor();
        return newColor;
    }
};

var Pong=Object.assign({}, Game);
Pong.initialize();
    </script>
</body>
</html>

本篇未完结,请继续看下一篇:手把手教你7个有趣的JavaScript 项目-下「附源码」


推荐JavaScript经典实例学习资料文章

《JavaScript 使用 mediaDevices API 访问摄像头自拍》