spring-quartz。

导包、配置,不在此介绍。

简单的quartz管理界面,包括触发器的暂停、恢复、删除、修改(暂无),任务的运行、触发添加、创建,删除。

扩展内容:日志的管理,添加和创建触发器的操作(暂无实现)

本文原创,禁止转载。

扩展内容(暂不实现)

前端代码:

<%--
Created by IntelliJ IDEA.
User: ttttt
Date: 2017/5/31
Time: 15:43
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<title>Title</title>
<link rel="stylesheet" type="text/css" href="/bootstrap/css/bootstrap.min.css">
<script type="text/javascript" src="/js/jquery-2.1.1.min.js"/>
<script type="text/javascript" src="/bootstrap/js/bootstrap.min.js"></script>
</head>
<body>
<h1>调度详情</h1>
<table id="table_report" class="table table-striped table-bordered table-hover">
<thead>
<tr>
<!-- th class="text-center">序号</th-->
<th class="text-center">任务组名称</th>
<th class="text-center">定时任务名称</th>
<th class="text-center">触发器组名称</th>
<th class="text-center">触发器名称</th>
<%--<th class="text-center">任务类名</th>--%>
<th class="text-center">触发器描述</th>
<th class="text-center">时间表达式</th>
<th class="text-center">任务状态</th>
<th class="text-center">开始时间</th>
<th class="text-center">上次重启时间</th>
<th class="text-center">上次执行时间</th>
<%--<th class="text-center">下次运行时间</th>--%>
<th class="text-center">操作</th>
</tr>
</thead>
<tbody>
<!-- 开始循环 -->
<c:choose>
<c:when test="${not empty jobInfos && jobInfos.size()>0}">
<c:forEach items="${jobInfos}" var="var" varStatus="vs">
<tr>
<td class='text-center' style="width: auto;">${var.jobGroup}</td>
<td class='text-center' style="width: auto;">${var.jobName}</td>
<td class='text-center' style="width: auto;">${var.triggerGroupName}</td>
<td class='text-center' style="width: auto;">${var.triggerName}</td>
<%--<td class='text-center' style="width: auto;">${var.jobClass}</td>--%>
<td class='text-center' style="width: auto;">${var.description}</td>
<td class='text-center' style="width: auto;">${var.cronExpr}</td>
<td class='text-center' style="width: auto;">
<c:if test="${var.jobStatus == 'NONE'}">
<span class="label">未知</span>
</c:if>
<c:if test="${var.jobStatus == 'NORMAL'}">
<span class="label label-success arrowed">正常运行</span>
</c:if>
<c:if test="${var.jobStatus == 'PAUSED'}">
<span class="label label-warning">暂停状态</span>
</c:if>
<c:if test="${var.jobStatus == 'COMPLETE'}">
<span class="label label-important arrowed-in">完成状态</span>
</c:if>
<c:if test="${var.jobStatus == 'ERROR'}">
<span class="label label-info arrowed-in-right arrowed">错误状态</span>
</c:if>
<c:if test="${var.jobStatus == 'BLOCKED'}">
<span class="label label-danger">锁定状态</span>
</c:if>
</td>
<td class='text-center' style="width: auto;"><fmt:formatDate value="${var.startTime}"
pattern="yyyy-MM-dd HH:mm:ss"/></td>
<td class='text-center' style="width: auto;"><fmt:formatDate value="${var.reStartTime}"
pattern="yyyy-MM-dd HH:mm:ss"/></td>
<td class='text-center' style="width: auto;"><fmt:formatDate value="${var.previousFireTime}"
pattern="yyyy-MM-dd HH:mm:ss"/></td>
<%--<td class='text-center' style="width: auto;"><fmt:formatDate value="${var.nextFireTime}"--%>
<%--pattern="yyyy-MM-dd HH:mm:ss"/></td>--%>
<td class='text-center' style="width: auto;">
<a class="btn btn-sm btn-warning" onclick="pauseJob('${var.triggerName}','${var.triggerGroupName}');">暂停</a>
<a class="btn btn-sm btn-success" onclick="resumeJob('${var.triggerName}','${var.triggerGroupName}');">恢复</a>
<a class="btn btn-sm btn-info" onclick="triggerJob('${var.jobName}','${var.jobGroup}');">修改</a>
<a class="btn btn-sm btn-danger" onclick="deleteJob('${var.triggerName}','${var.triggerGroupName}');">删除</a>
</td><!-- cron,jobName,jobGroupName,triggerName,triggerGroupName -->
</tr>
</c:forEach>
</c:when>
<c:otherwise>
<tr class="main_info">
<td colspan="100" class="text-center">没有相关数据</td>
</tr>
</c:otherwise>
</c:choose>
</tbody>
</table>
<h1>任务详情</h1>
<table id="table_detail_report" class="table table-striped table-bordered table-hover">
<thead>
<tr>
<!-- th class="text-center">序号</th-->
<th class="text-center">任务组名称</th>
<th class="text-center">任务名称</th>
<th class="text-center">任务类名</th>
<th class="text-center">任务描述</th>
<th class="text-center">持久性</th>
<th class="text-center">禁止并发</th>
<th class="text-center">数据更新</th>
<th class="text-center">恢复性</th>
<th class="text-center">关联调度器数量</th>
<th class="text-center">操作</th>
</tr>
</thead>
<tbody>
<!-- 开始循环 -->
<c:choose>
<c:when test="${not empty jobDetailInfos && jobDetailInfos.size()>0}">
<c:forEach items="${jobDetailInfos}" var="var" varStatus="vs">
<tr>
<td class='text-center' style="width: auto;">${var.jobGroup}</td>
<td class='text-center' style="width: auto;">${var.jobName}</td>
<td class='text-center' style="width: auto;">${var.jobClass}</td>
<td class='text-center' style="width: auto;">${var.description}</td>
<td class='text-center' style="width: auto;">
<c:if test="${var.duration}">

</c:if>
<c:if test="${!var.duration}">

</c:if>
</td>
<td class='text-center' style="width: auto;">
<c:if test="${var.concurrentExectionDisallowed}">

</c:if>
<c:if test="${!var.concurrentExectionDisallowed}">

</c:if>
</td>
<td class='text-center' style="width: auto;">
<c:if test="${var.persistJobDataAfterExecution}">

</c:if>
<c:if test="${!var.persistJobDataAfterExecution}">

</c:if>
</td>
<td class='text-center' style="width: auto;">
<c:if test="${var.requestsRecovery}">

</c:if>
<c:if test="${!var.requestsRecovery}">

</c:if>
</td>
<td class='text-center' style="width: auto;">${var.triggerCount}</td>
<td class='text-center' style="width: auto;">
<a class="btn btn-sm btn-success"
onclick="triggerJob('${var.jobName}','${var.jobGroup}');">运行一次</a>
<a class="btn btn-sm btn-warning" href="/quartz/addJobTrigger?jobName=${var.jobName}&&jobGroup=${var.jobGroup}">添加调度</a>
<a class="btn btn-sm btn-info" href="/quartz/addJobTrigger?jobName=${var.jobName}&&jobGroup=${var.jobGroup}">创建调度</a>
<a class="btn btn-sm btn-danger" onclick="deleteJobDetail('${var.jobName}','${var.jobGroup}');">删除</a>
</td><!-- cron,jobName,jobGroupName,triggerName,triggerGroupName -->
</tr>
</c:forEach>
</c:when>
<c:otherwise>
<tr class="main_info">
<td colspan="100" class="text-center">没有相关数据</td>
</tr>
</c:otherwise>
</c:choose>
</tbody>
</table>
<h1>添加/修改 调度</h1>
<form class="form-horizontal" action="quartzAdd/add">
<div class="form-group">
<label for="jobName" class="col-sm-1 control-label">任务名称</label>
<div class="col-sm-3">
<input type="text" class="form-control" id="jobName" disabled placeholder="任务名称" value="${jobDetailInfo.jobName}">
</div>
</div>
<div class="form-group">
<label for="jobGroupName" class="col-sm-1 control-label">任务组名称</label>
<div class="col-sm-3">
<input type="text" class="form-control" id="jobGroupName" disabled placeholder="任务组名称" value="${jobDetailInfo.jobGroup}">
</div>
</div>
<div class="form-group">
<label for="jobClass" class="col-sm-1 control-label">任务类</label>
<div class="col-sm-3">
<input type="text" class="form-control" id="jobClass" disabled placeholder="任务类" value="${jobDetailInfo.jobClass}">
</div>
</div>
<c:forEach items="${jobDetailInfo.jobDataMap}" var="var" varStatus="vs">
<div class="form-group">
<label for="jobData${vs.count}" class="col-sm-1 control-label">${var.key} (初始化)</label>
<div class="col-sm-3">
<input type="text" class="form-control" id="jobData${vs.count}" disable placeholder="当前任务值:${var.value}">
</div>
</div>
</c:forEach>
<div class="form-group">
<label for="triggerName" class="col-sm-1 control-label">触发器名称</label>
<div class="col-sm-3">
<input type="text" class="form-control" id="triggerName" placeholder="触发器名称">
</div>
</div>
<div class="form-group">
<label for="triggerGroupName" class="col-sm-1 control-label">触发器组名称</label>
<div class="col-sm-3">
<input type="text" class="form-control" id="triggerGroupName" placeholder="触发器组名称">
</div>
</div>
<div class="form-group">
<label for="cron" class="col-sm-1 control-label">cron表达式</label>
<div class="col-sm-3">
<input type="text" class="form-control" id="cron" placeholder="例如: 0 0/5 * 6L * 1,2 ?">
</div>
</div>
<div class="form-group">
<label class="col-sm-1 control-label">是否立即执行</label>
<div class="col-sm-3">
<label class="radio-inline">
<input type="radio" name="radio" id="inlineRadio1" value="1"> 是
</label>
<label class="radio-inline">
<input type="radio" name="radio" id="inlineRadio2" value="0"> 否
</label>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-1 col-sm-3">
<button type="submit" class="btn btn-default">添加调度</button>
</div>
</div>
</form>
<h1>创建调度</h1>
<form class="form-horizontal" action="quartzAdd/add">
<div class="form-group">
<label for="jobName1" class="col-sm-1 control-label">任务名称</label>
<div class="col-sm-3">
<input type="text" class="form-control" id="jobName1" placeholder="任务名称">
</div>
</div>
<div class="form-group">
<label for="jobGroupName1" class="col-sm-1 control-label">任务组名称</label>
<div class="col-sm-3">
<input type="text" class="form-control" id="jobGroupName1" placeholder="任务组名称">
</div>
</div>
<div class="form-group">
<label for="jobClass1" class="col-sm-1 control-label">任务类</label>
<div class="col-sm-3">
<input type="text" class="form-control" id="jobClass1" disabled placeholder="任务类" value="${jobDetailInfo.jobClass}">
</div>
</div>
<div class="form-group">
<label for="triggerName1" class="col-sm-1 control-label">触发器名称</label>
<div class="col-sm-3">
<input type="text" class="form-control" id="triggerName1" placeholder="触发器名称">
</div>
</div>
<div class="form-group">
<label for="triggerGroupName1" class="col-sm-1 control-label">触发器组名称</label>
<div class="col-sm-3">
<input type="text" class="form-control" id="triggerGroupName1" placeholder="触发器组名称">
</div>
</div>
<div class="form-group">
<label for="cron1" class="col-sm-1 control-label">cron表达式</label>
<div class="col-sm-3">
<input type="text" class="form-control" id="cron1" placeholder="例如: 0 0/5 * 6L * 1,2 ?">
</div>
</div>
<div class="form-group">
<label class="col-sm-1 control-label">是否立即执行</label>
<div class="col-sm-3">
<label class="radio-inline">
<input type="radio" name="radio" id="inlineRadio11" value="1"> 是
</label>
<label class="radio-inline">
<input type="radio" name="radio" id="inlineRadio12" value="0"> 否
</label>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-1 col-sm-3">
<button type="submit" class="btn btn-default">创建调度</button>
</div>
</div>
</form>
<br/>
<script>
function deleteJobDetail(jobName, jobGroup) {
if(confirm("是否删除该任务详情。")){
$.ajax({
type: "POST",
url: "/quartz/deleteJobDetail",
data: {"jobName": jobName, "jobGroup": jobGroup},
success: function (data) {
if(data){
location.reload();
}else{
alert("删除失败。");
}
},
fail: function () {
alert("操作失败。");
}
});
}
}
function triggerJob(jobName, jobGroup) {
if(confirm("是否立即运行一次。")){
$.ajax({
type: "POST",
url: "/quartz/triggerJob",
data: {"jobName": jobName, "jobGroup": jobGroup},
success: function (data) {
if(data){
location.reload();
}else{
alert("删除失败。");
}
},
fail: function () {
alert("操作失败。");
}
});
}
}
function deleteJob(triggerName, triggerGroup) {
if(confirm("是否删除该任务。")){
$.ajax({
type: "POST",
url: "/quartz/deleteJob",
data: {"triggerName": triggerName, "triggerGroup": triggerGroup},
success: function (data) {
if(data){
location.reload();
}else{
alert("删除失败。");
}
},
fail: function () {
alert("操作失败。");
}
});
}
}
function resumeJob(triggerName, triggerGroup) {
$.ajax({
type: "POST",
url: "/quartz/resumeJob",
data: {"triggerName": triggerName, "triggerGroup": triggerGroup},
success: function (data) {
if(data){
location.reload();
}else{
alert("恢复失败。");
}
},
fail: function () {
alert("操作失败。");
}
});
}
function pauseJob(triggerName, triggerGroup) {
$.ajax({
type: "POST",
url: "/quartz/pauseJob",
data: {"triggerName": triggerName, "triggerGroup": triggerGroup},
success: function (data) {
if(data){
location.reload();
}else{
alert("暂停失败。");
}
},
fail: function () {
alert("操作失败。");
}
});
}
</script>
</body>
</html>

Controllere代码:

package com.sky.controller;

import com.sky.bean.JobDetailManage;
import com.sky.bean.JobEntity;
import com.sky.util.QuartzManager;
import com.sky.util.QuartzUtils;
import com.sun.istack.internal.NotNull;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView; import java.util.ArrayList;
import java.util.List;
import java.util.Set; /**
* @author sky
*/
@Controller
public class JobController { private Scheduler quartzScheduler; @RequestMapping("/quartz")
public ModelAndView quartz() {
ModelAndView mv = new ModelAndView();
mv.setViewName("quartz");
JobKey jobKey = JobKey.jobKey("hello4", "group1");
try {
mv.addObject("jobInfos", getSchedulerJobInfo());
mv.addObject("jobDetailInfos", getJobDetailInfos());
mv.addObject("jobDetailInfo", getJobDetailInfo(jobKey));
} catch (SchedulerException e) {
}
return mv;
} //暂停任务
@PostMapping("quartz/pauseJob")
@ResponseBody
public boolean pauseJob(@NotNull String triggerName, @NotNull String triggerGroup) {
TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroup);
try {
quartzScheduler.pauseTrigger(triggerKey);
} catch (SchedulerException e) {
System.out.println(e.getMessage());
}
return true;
} //恢复任务
@PostMapping("quartz/resumeJob")
@ResponseBody
public boolean resumeJob(@NotNull String triggerName, @NotNull String triggerGroup) throws Exception {
TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroup);
quartzScheduler.resumeTrigger(triggerKey);
return true;
} //删除任务
@PostMapping("quartz/deleteJob")
@ResponseBody
public boolean deleteJob(@NotNull String triggerName, @NotNull String triggerGroup) throws Exception {
JobKey jobKey = JobKey.jobKey(triggerName, triggerGroup);
TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroup);
quartzScheduler.pauseTrigger(triggerKey);
return quartzScheduler.unscheduleJob(triggerKey);
} //立即运行任务
@PostMapping("quartz/triggerJob")
@ResponseBody
public boolean triggerJob(@NotNull String jobName, @NotNull String jobGroup) throws Exception {
JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
quartzScheduler.triggerJob(jobKey);
return true;
} //删除任务详情
@PostMapping("quartz/deleteJobDetail")
@ResponseBody
public boolean deleteJobDetail(@NotNull String jobName, @NotNull String jobGroup) throws Exception {
JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
List<Trigger> triggers = (List<Trigger>) quartzScheduler.getTriggersOfJob(jobKey);
if (triggers.size() > 0) {
return false;
}
return quartzScheduler.deleteJob(jobKey);
} // @SuppressWarnings("unchecked")
private List<JobEntity> getSchedulerJobInfo() throws SchedulerException {
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
quartzScheduler = schedulerFactory.getScheduler(); List<JobEntity> jobInfos = new ArrayList<JobEntity>();
List<String> triggerGroupNames = quartzScheduler.getTriggerGroupNames();
for (String triggerGroupName : triggerGroupNames) {
Set<TriggerKey> triggerKeySet = quartzScheduler.getTriggerKeys(GroupMatcher.triggerGroupEquals(triggerGroupName));
for (TriggerKey triggerKey : triggerKeySet) {
Trigger t = quartzScheduler.getTrigger(triggerKey);
JobEntity jobInfo = new JobEntity();
if (t instanceof CronTrigger) {
CronTrigger trigger = (CronTrigger) t;
jobInfo.setCronExpr(trigger.getCronExpression());
} else if (t instanceof SimpleTrigger) {
SimpleTrigger trigger = (SimpleTrigger) t;
jobInfo.setCronExpr(trigger.getRepeatCount() + 1 + "-" + trigger.getTimesTriggered() + "(" + trigger.getRepeatInterval() + ")"); }
JobKey jobKey = t.getJobKey();
JobDetail jd = quartzScheduler.getJobDetail(jobKey);
jobInfo.setJobName(jobKey.getName());
jobInfo.setJobGroup(jobKey.getGroup());
jobInfo.setTriggerName(triggerKey.getName());
jobInfo.setTriggerGroupName(triggerKey.getGroup());
jobInfo.setNextFireTime(t.getNextFireTime());
jobInfo.setPreviousFireTime(t.getPreviousFireTime());
jobInfo.setStartTime(t.getStartTime());
jobInfo.setEndTime(t.getEndTime());
jobInfo.setJobClass(jd.getJobClass().getCanonicalName());
jobInfo.setDescription(t.getDescription()); Trigger.TriggerState triggerState = quartzScheduler.getTriggerState(t.getKey());
jobInfo.setJobStatus(triggerState.toString());// NONE无, NORMAL正常, PAUSED暂停, COMPLETE完全, ERROR错误, BLOCKED阻塞
JobDataMap map = quartzScheduler.getJobDetail(jobKey).getJobDataMap();
// jobInfo.setCount(Integer.parseInt((String) map.get("count")));
if (null != map) {
jobInfo.setJobDataMap(map);
} else {
jobInfo.setJobDataMap(new JobDataMap());
}
jobInfos.add(jobInfo);
}
}
return jobInfos;
} // @SuppressWarnings("unchecked")
private List<JobDetailManage> getJobDetailInfos() throws SchedulerException {
List<JobDetailManage> jobDetailInfos = new ArrayList<JobDetailManage>(); for (String groupName : quartzScheduler.getJobGroupNames()) {
for (JobKey jobKey : quartzScheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName))) {
jobDetailInfos.add(getJobDetailInfo(jobKey));
}
}
return jobDetailInfos;
} // @SuppressWarnings("unchecked")
private JobDetailManage getJobDetailInfo(JobKey jobKey) throws SchedulerException {
JobDetail jobDetail = quartzScheduler.getJobDetail(jobKey);
List<Trigger> triggers = (List<Trigger>) quartzScheduler.getTriggersOfJob(jobKey); if(jobDetail != null){
JobDetailManage jobDetailManage = new JobDetailManage();
jobDetailManage.setJobName(jobKey.getName());
jobDetailManage.setJobGroup(jobKey.getGroup());
jobDetailManage.setDescription(jobDetail.getDescription());
jobDetailManage.setDuration(jobDetail.isDurable());
jobDetailManage.setJobClass(jobDetail.getJobClass().getCanonicalName());
jobDetailManage.setJobDataMap(jobDetail.getJobDataMap());
jobDetailManage.setPersistJobDataAfterExecution(jobDetail.isPersistJobDataAfterExecution());
jobDetailManage.setConcurrentExectionDisallowed(jobDetail.isConcurrentExectionDisallowed());
jobDetailManage.setRequestsRecovery(jobDetail.requestsRecovery());
jobDetailManage.setTriggerCount(triggers.size()); return jobDetailManage;
}
return null;
}
}

  

JobDetailManage类:

package com.sky.bean;

import org.quartz.JobDataMap;

/**
* @author sky
*/
public class JobDetailManage {
private String jobName;
private String jobGroup;
private String description;
private Boolean duration;
private String jobClass;
private JobDataMap jobDataMap;
private Boolean concurrentExectionDisallowed;
private Boolean persistJobDataAfterExecution;
private Boolean requestsRecovery;
private Integer triggerCount; //get set
}

  

JobEntity类:

package com.sky.bean;

import org.quartz.JobDataMap;

import java.util.Date;

/**
* 调度器信息
*
* @author sky
*/
public class JobEntity {
private int jobId;
private String jobType;
private String jobGroup;
private String jobName;
private String triggerName;
private String triggerGroupName;
private String cronExpr;
private String description;
private Date previousFireTime;
private Date nextFireTime;
private String jobStatus;
private Date startTime;
private Date endTime;
private Date reStartTime;
private String jobClass;
private int count;
private JobDataMap jobDataMap; //get set
}

  

简单的quartz 可视化监听管理界面的更多相关文章

  1. oracle配置监听图形界面不出来解决方法

    ROOT用户下,执行 xhost +   然后再切换到oracle用户运行netca DISPLAY 在Linux/Unix类操作系统上, DISPLAY用来设置将图形显示到何处. 直接登陆图形界面或 ...

  2. 作业引擎quartz.net --- 监听链

    针对多个作业:如何描述各个跑批任务之间的顺序,紧前.紧后关系,实现灵活调度.例如:A完成则B开始,B完成C开始. 对quartz.net 进行了查阅,能实现如上业务,如下图: 测试代码: using ...

  3. PLSQL连接Oracle64监听和服务的配置!

    前言: 这里不会涉及到太多关于版本问题的解决,只是简单提一下基本的监听和服务配置问题的解决,让你可以快速的用PLSQL连接上你自己创建的Oracle数据库(这里示例数据库名为ORCL); 版本问题: ...

  4. Android中如何监听GPS开启和关闭

    转自 chenming 原文 Android中如何监听GPS开启和关闭   摘要: 本文简单总结了如何监听GPS开关的小技巧 有时需要监听GPS的开关(这种需求并不多见).实现的思路是监听代表 GPS ...

  5. Linux下修改Oracle监听地址

    如果你的服务器换了ip怎么办? 如果你的服务器换了名字怎么办? 以前的小伙伴怎么办? 以前的老客户怎么办? 没关系,简单教你修改监听地址,老朋友随便找! 想要修改监听地址首先要找到两个文件,确定两样东 ...

  6. OC - 18.监听iPhone的网络状态

    使用系统的方法来监听网络状态 系统的方法是通过通知机制来实现网络状态的监听 实现网络状态监听的步骤 定义Reachability类型的成员变量来保存网络的状态 @property (nonatomic ...

  7. android 监听短信数据库,制作短信控制工具,控制别人的手机!!(一)

    序言:本程序示例本着简洁易懂的目的,只做了简单的功能实现,需要用户启动应用,收到短信才有效果.作者将会在后面的(二)篇中加入服务后台运行.自动启动功能,实现一个真正的短信控制工具.本文的目的很简单,让 ...

  8. JS监听组合按键

    有些时候,我们需要在网页上,增加一些快捷按键,方便用户使用一些常用的操作,比如:保存,撤销,复制.粘贴等等. 下面简单梳理一下思路: 我们所熟悉的按键有这么集中类型: 单独的按键操作,如:delete ...

  9. 原生javascript实现类似jquery on方法的行为监听

    原生javascript有addEventListener和attachEvent方法来注册事件,但有时候我们需要判断某一行为甚至某一函数是否被执行了,并且能够获取前一行为的参数,这个时候就需要其他方 ...

随机推荐

  1. POJ-1113 Wall 计算几何 求凸包

    题目链接:https://cn.vjudge.net/problem/POJ-1113 题意 给一些点,求一个能够包围所有点且每个点到边界的距离不下于L的周长最小图形的周长 思路 求得凸包的周长,再加 ...

  2. POJ 2228 Naptime(DP+环形处理)

    题解 这题一眼望去DP. 发现自己太智障了. 这题想的是O(n^3m)的. 环形处理只会断环成链....然后DP也想的不好. 我们先考虑如果除去环这题该怎么做? dp[i][j][0/1]代表到第i小 ...

  3. 一个 VUE 组件:实现子元素 scroll 父元素容器不跟随滚动(兼容PC、移动端)

    介绍 我们经常遇到一种情况.当滑动滚动条区域时,子元素滚动条到底部或顶部时就会触发父级滚动条,父级滚动条同理会继续向上触发,直至body容器.这是浏览器默认的滚动行为. 但是很多情况,我们想要子元素滚 ...

  4. 紫书 例题11-9 UVa 1658 (拆点+最小费用流)

    这道题要求每个节点只能经过一次,也就是结点容量为1, 要拆点, 拆成两个点, 中间连一条弧容量为1, 费用为0. 因为拆成两个点, 所以要经过原图中的这个节点就要经过拆成的这两个点, 又因为这两个点的 ...

  5. LaTeX 表格

    本系列文章由 @YhL_Leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/50066137 一些LaTeX中表格的使 ...

  6. COGS——T 1578. 次小生成树初级练习题

    http://www.cogs.pro/cogs/problem/problem.php?pid=1578 ☆   输入文件:mst2.in   输出文件:mst2.out   简单对比时间限制:1 ...

  7. Oracle创建用户以及备份还原数据库操作

    -- Create the user create user XX identified by "" default tablespace USERS temporary tabl ...

  8. Java - Thinking in Java 第2章 一切都是对象

    Java是"纯粹"的面向对象的语言. 操作的标示符是对象的一个引用, new是创建一个对象. 存储位置: 寄存器\堆栈(引用)\堆(new)\常量存储(程序代码内部)\非RAM存储 ...

  9. angularjs ng-app

    <!DOCTYPE HTML> <html ng-app> //ng-app是初始化指令,整个页面都会被angularjs解析,写在div或者其他标签上表示只是局部的div和标 ...

  10. 8.最佳的MongoDB客户端管理工具

    转自:https://blog.csdn.net/chszs/article/details/51348248