详解js中构造流程图的核心技术JsPlumb(2)

前言:上篇详解js中构造流程图的核心技术JsPlumb介绍了下JsPlumb在浏览器里面画流程图的效果展示,以及简单的JsPlumb代码示例。这篇还是接着来看看各个效果的代码说明。

一、设置连线的样式和颜色效果代码示例
大概的效果如图:

这些效果看着很简单,那么,我们如何用代码去实现它呢。上章我们说过,JsPlumb的连线样式是由点的某些属性决定的,既然如此,我们就通过设置点的样式来动态改变连线的样式即可。来看代码:

首先来看看连线类型的那个select

 <div id="btn_linetype" class="divMenuBtn btn-default btn">
  连线类型:
  <select id="sel_linetype" style="width:80px;height:20px">
    <option value="2">直线</option>
    <option value="1">折线</option>
    <option value="3">曲线</option>
  </select>
</div>

在页面初始化的时候注册select的change事件

//全局的空心圆端点样式设置
var hollowCircle = {
  DragOptions: { cursor: 'pointer', zIndex: 2000 },
  endpoint: ["Dot", { radius: 7 }], //端点的形状
  connectorStyle: connectorPaintStyle,//连接线的颜色,大小样式
  connectorHoverStyle: connectorHoverStyle,
  paintStyle: {
    strokeStyle: "#1e8151",
    fillStyle: "transparent",
    radius: 5,
    lineWidth: 2
  },    //端点的颜色样式
  //anchor: "AutoDefault",
  isSource: true,  //是否可以拖动(作为连线起点)
  connector: ["Straight", { stub: [0, 0], gap: 10, cornerRadius: 5, alwaysRespectStubs: true }], //连接线的样式种类有[Bezier],[Flowchart],[StateMachine ],[Straight ]
  isTarget: true,  //是否可以放置(连线终点)
  maxConnections: -1,  // 设置连接点最多可以连接几条线
  connectorOverlays: [["Arrow", { width: 10, length: 10, location: 1 }]]
};

//页面初始化完成之后
$(function () {
  //连线样式下拉框的change事件
  $("#sel_linetype").change(function () {
    var strlinetype = "";
    var strlinecolor = "";
    //设置新添加元素的节点的连线样式
    //直线的样式和样色
    if ($(this).val() == "1") {
      strlinetype = "Flowchart";
      strlinecolor = "red";
      hollowCircle.connector = ["Flowchart", { stub: [0, 0], gap: 10, cornerRadius: 5, alwaysRespectStubs: true }];
    }
    //折线的样式和颜色
    else if ($(this).val() == "2") {
      strlinetype = "Straight";
      strlinecolor = "green";
      hollowCircle.connector = ["Straight", { stub: [0, 0], gap: 10, cornerRadius: 5, alwaysRespectStubs: true }];
    }
    //曲线的样式和颜色
    else if ($(this).val() == "3") {
      strlinetype = "Bezier";
      strlinecolor = "orange";
      hollowCircle.connector = ["Bezier", { stub: [0, 0], gap: 10, cornerRadius: 5, alwaysRespectStubs: true }];
    }
    //设置已经存在的所有的连接点的连线样式
    var arrnode = $("#divCenter").find(".node");
    for (var i = 0; i < arrnode.length; i++) {
      var arrendpoints = jsPlumb.getEndpoints($(arrnode[i]).attr("id"));
      if (arrendpoints == undefined || arrendpoints == null) {
        return;
      }
      var oconnector = arrendpoints[0].connector;
      if (oconnector == null || oconnector == undefined) {
        return;
      }
      oconnector[0] = strlinetype;
      var oconnectstyle = arrendpoints[0].connectorStyle;
      if (oconnectstyle == null || oconnectstyle == undefined) {
        return;
      }
      oconnectstyle.strokeStyle = strlinecolor;
    }
  });
});

其实也就几行代码,设置已经存在和将要拖动到界面上面的端点的连线样式。
二、全选、全选拖动效果代码示例
可以选中元素,批量拖动元素和连线,大概效果:

看看实现代码:
1、初始化的时候注册可选中

$(function () {
  var oRegionSelect = new RegionSelect({
    region: '#divCenter div.node',
    selectedClass: 'seled',
    parentId: "divCenter"
  });
  oRegionSelect.select();
});

2、选中相关方法

var _selectedRegions = [];
//var selProp;

function RegionSelect(selRegionProp) {
  //selProp = selRegionProp;
  this.regions = [];
  this.selProp = selRegionProp;
  this.InitRegions(selRegionProp);
  this.selectedClass = selRegionProp["selectedClass"];
  this.selectedRegion = [];
  this.selectDiv = null;
  this.startX = null;
  this.startY = null;
  this.parentId = selRegionProp["parentId"];
}

RegionSelect.prototype.InitRegions = function () {
  var _self = this;
  _self.regions = [];
  var _regions = document.getElementsBySelector(_self.selProp["region"]);//$("#divCenter > .node");//

  var bSelect = true;
  if (_regions && _regions.length > 0) {
    for (var i = 0; i < _regions.length; i++) {
      _regions[i].onmousedown = function () {
        bSelect = false;
        var evt = window.event || arguments[0];
        if (!evt.shiftKey && !evt.ctrlKey) {
          if ($.inArray(this, _selectedRegions) === -1) {
            // 清空所有select样式
            _self.clearSelections(_regions);
            this.className += " " + _self.selectedClass;
            // 清空selected数组,并加入当前select中的元素
            _selectedRegions = [];
            _selectedRegions.push(this);
          }
        } else {
          if (this.className.indexOf(_self.selectedClass) == -1) {
            this.className += " " + _self.selectedClass;
            _selectedRegions.push(this);
          } else {
            this.className = this.className.replaceAll(_self.selectedClass, "");
            _selectedRegions.remove(this);
          }
        }
        clearEventBubble(evt);
      }
      this.regions.push(_regions[i]);
    }
  }

  if (bSelect) {
    // 清空所有select样式
    _self.clearSelections(_regions);
    // 清空selected数组,并加入当前select中的元素
    _selectedRegions = [];
  }
}

RegionSelect.prototype.select = function () {
  var _self = this;
  var sDivId = _self.parentId;
  var intMousePosition = [0, 0];
  var intOriginalPosition = [0, 0];
  var parentWidth = parseInt(document.getElementById(sDivId).parentElement.offsetWidth);
  var parentHeight = parseInt(document.getElementById(sDivId).parentElement.offsetHeight);
  addEvent("mousedown", function () {
    var evt = window.event || arguments[0];
    var buttonType = evt.buttons || evt.button;
    if (evt.target != undefined) {
      if (evt.target.id !== sDivId) return;
    }
    if (evt.srcElement != undefined) {
      if (evt.srcElement.id !== sDivId) return;
    }
    if (evt.buttons == undefined && buttonType == 0){
      _self.onBeforeSelect(evt, sDivId);
    }
    if (buttonType === 1) {
      _self.onBeforeSelect(evt, sDivId);
    }
    if (buttonType === 2) {
      intMousePosition = [evt.clientX, evt.clientY];
      var movX = parseInt(GetStyle(document.getElementById(sDivId), "left"));
      var movY = parseInt(GetStyle(document.getElementById(sDivId), "top"));
      intOriginalPosition = [movX, movY];
      document.getElementById(sDivId).style.cursor = "move";
    }
    clearEventBubble(evt);
  }, document);

  addEvent("mousemove", function () {
    var evt = window.event || arguments[0];
    //if (evt.target.id !== sDivId) return;
    var buttonType = evt.buttons || evt.button;
    if (evt.buttons == undefined && buttonType == 0) {
      _self.onSelect(evt, sDivId);
    }
    if (buttonType === 1) {
      _self.onSelect(evt, sDivId);
    }
    if (buttonType === 2) {
      var newX = intOriginalPosition[0] + evt.clientX - intMousePosition[0];
      var newY = intOriginalPosition[1] + evt.clientY - intMousePosition[1];
      if (newX >= 0) {
        newX = 0;
      }
      if (newY >= 0) {
        newY = 0;
      }
      $("#" + sDivId).css("left", newX + "px");
      $("#" + sDivId).css("top", newY + "px");
      $("#" + sDivId).css("width", (parentWidth-newX) + "px");
      $("#" + sDivId).css("height", (parentHeight-newY) + "px");

    }
    clearEventBubble(evt);
  }, document);

  addEvent("mouseup", function () {
    var evt = window.event || arguments[0];
    var buttonType = evt.buttons || evt.button;
    if (evt.buttons == undefined && buttonType == 0) {
    }
    if (buttonType === 1) {
    }
      document.getElementById(sDivId).style.cursor = "default";
      _self.onEnd();
  }, document);
}

RegionSelect.prototype.onBeforeSelect = function (evt, sDivId) {
  // 创建模拟 选择框
  var _self = this;
  _self.InitRegions(_self.selProp);
  if (!document.getElementById("selContainer")) {
    this.selectDiv = document.createElement("div");
    this.selectDiv.style.cssText = "position:absolute;width:0px;height:0px;font-size:0px;margin:0px;padding:0px;border:1px dashed #0099FF;background-color:#C3D5ED;z-index:1000;filter:alpha(opacity:60);opacity:0.6;display:none;";
    this.selectDiv.id = "selContainer";
    document.getElementById(sDivId).appendChild(this.selectDiv);
  } else {
    this.selectDiv = document.getElementById("selContainer");
  }

  this.startX = posXY(evt, sDivId).x;
  this.startY = posXY(evt, sDivId).y;
  this.isSelect = true;

}

RegionSelect.prototype.onSelect = function (evt, sDivId) {
  var self = this;
  if (self.isSelect) {
    if (self.selectDiv.style.display == "none") self.selectDiv.style.display = "";

    var posX = posXY(evt, sDivId).x;
    var poxY = posXY(evt, sDivId).y;
    self.selectDiv.style.left = Math.min(posX, this.startX) + "px";
    self.selectDiv.style.top = Math.min(poxY, this.startY) + "px";
    self.selectDiv.style.width = Math.abs(posX - this.startX) + "px";
    self.selectDiv.style.height = Math.abs(poxY - this.startY) + "px";

    var regionList = self.regions;
    for (var i = 0; i < regionList.length; i++) {
      if (self.selectDiv.parentNode.id !== regionList[i].parentNode.id) continue;
      var r = regionList[i], sr = self.innerRegion(self.selectDiv, r);
      if (sr && r.className.indexOf(self.selectedClass) == -1) {
        r.className = r.className + " " + self.selectedClass;
        _selectedRegions.push(r);
      } else if (!sr && r.className.indexOf(self.selectedClass) != -1) {
        r.className = r.className.replaceAll(self.selectedClass, "");
        _selectedRegions.remove(r);
      }

    }
  }
}

RegionSelect.prototype.onEnd = function () {
  var self = this;
  if (self.selectDiv) {
    self.selectDiv.style.display = "none";
  }
  this.isSelect = false;
  //_selectedRegions = this.selectedRegion;
}

// 判断一个区域是否在选择区内
RegionSelect.prototype.innerRegion = function (selDiv, region) {
  var s_top = parseInt(selDiv.style.top);
  var s_left = parseInt(selDiv.style.left);
  var s_right = s_left + parseInt(selDiv.offsetWidth);
  var s_bottom = s_top + parseInt(selDiv.offsetHeight);

  var r_top = parseInt(region.offsetTop);
  var r_left = parseInt(region.offsetLeft);
  var r_right = r_left + parseInt(region.offsetWidth);
  var r_bottom = r_top + parseInt(region.offsetHeight);

  var t = Math.max(s_top, r_top);
  var r = Math.min(s_right, r_right);
  var b = Math.min(s_bottom, r_bottom);
  var l = Math.max(s_left, r_left);

  if (b > t + 5 && r > l + 5) {
    return region;
  } else {
    return null;
  }

}

RegionSelect.prototype.clearSelections = function (regions) {
  for (var i = 0; i < regions.length; i++) {
    regions[i].className = regions[i].className.replaceAll(this.selectedClass, "");
  }
}

function getSelectedRegions() {
  return _selectedRegions;
}

/*-------------------------------------- 区域选择方法结束 --------------------------------------------*/

function showSelDiv() {
  var selInfo = "";
  var arr = getSelectedRegions();
  for (var i = 0; i < arr.length; i++) {
    selInfo += arr[i].innerHTML + "\n";
  }

  alert("共选择 " + arr.length + " 个文件,分别是:\n" + selInfo);

}

function MoveSelectDiv(event, ui,id) {
  var arr = getSelectedRegions();
  var iMoveLeft = ui.position.left - ui.originalPosition.left;
  var iMoveTop = ui.position.top - ui.originalPosition.top;

  for (var i = 0; i < arr.length; i++) {
    //if (arr[i].id === id) continue;

    if (arr[i].parentNode.id !== document.getElementById(id).parentNode.id) continue;
    var iLeft = parseInt($(arr[i]).attr("bLeft"));
    var iTop = parseInt($(arr[i]).attr("bTop"));
    $(arr[i]).css("left", (iLeft + iMoveLeft) + "px");
    $(arr[i]).css("top", (iTop + iMoveTop) + "px");
  }
}

function startMove() {
  var arr = getSelectedRegions();
  for (var i = 0; i < arr.length; i++) {
    $(arr[i]).attr("bLeft", $(arr[i]).position().left);
    $(arr[i]).attr("bTop", $(arr[i]).position().top);
  }
}

三、对齐、旋转代码示例

//左对齐
function SelectAlignLeft() {
  var arr = getSelectedRegions();
  var iLeft = 0;
  var id = "";

  for (var i = 0; i < arr.length; i++) {
    if (id === "") id = arr[i].parentNode.id;
    if (id !== arr[i].parentNode.id) continue;
    if ($(arr[i]).position().left<iLeft||iLeft===0) {
      iLeft = $(arr[i]).position().left;
    }
  }

  for (var j = 0; j < arr.length; j++) {
    if (id !== arr[j].parentNode.id) continue;
    $(arr[j]).css("left", iLeft + "px");
  }

  jsPlumb.repaintEverything();
}

//居中对齐
function SelectAlignCenter() {
  var arr = getSelectedRegions();
  var iLeft = 0;
  var id = "";

  for (var i = 0; i < arr.length; i++) {
    if (id === "") id = arr[i].parentNode.id;
    if (id !== arr[i].parentNode.id) continue;
    if ($(arr[i]).position().left < iLeft || iLeft === 0) {
      iLeft = $(arr[i]).position().left + parseInt(GetStyle(arr[i],"width")) / 2;
    }
  }

  for (var j = 0; j < arr.length; j++) {
    if (id !== arr[j].parentNode.id) continue;
    $(arr[j]).css("left", (iLeft - parseInt(GetStyle(arr[j],"width")) / 2) + "px");
  }

  jsPlumb.repaintEverything();
}
//右对齐
function SelectAlignRight() {
  var arr = getSelectedRegions();
  var iLeft = 0;
  var id = "";

  for (var i = 0; i < arr.length; i++) {
    if (id === "") id = arr[i].parentNode.id;
    if (id !== arr[i].parentNode.id) continue;
    if ($(arr[i]).position().left + parseInt(GetStyle(arr[i], "width")) > iLeft || iLeft === 0) {
      iLeft = $(arr[i]).position().left + parseInt(GetStyle(arr[i], "width"));
    }
  }

  for (var j = 0; j < arr.length; j++) {
    if (id !== arr[j].parentNode.id) continue;
    $(arr[j]).css("left", (iLeft - parseInt(GetStyle(arr[j], "width"))) + "px");
  }

  jsPlumb.repaintEverything();
}

//上对齐
function SelectAlignTop() {
  var arr = getSelectedRegions();
  var iTop = 0;
  var id = "";

  for (var i = 0; i < arr.length; i++) {
    if (id === "") id = arr[i].parentNode.id;
    if (id !== arr[i].parentNode.id) continue;
    if ($(arr[i]).position().top < iTop || iTop === 0) {
      iTop = $(arr[i]).position().top;
    }
  }

  for (var j = 0; j < arr.length; j++) {
    if (id !== arr[j].parentNode.id) continue;
    $(arr[j]).css("top", iTop + "px");
  }

  jsPlumb.repaintEverything();
}

//垂直居中
function SelectAlignMiddle() {
  var arr = getSelectedRegions();
  var iTop = 0;
  var id = "";

  for (var i = 0; i < arr.length; i++) {
    if (id === "") id = arr[i].parentNode.id;
    if (id !== arr[i].parentNode.id) continue;
    if ($(arr[i]).position().top + parseInt(GetStyle(arr[i], "height")) / 2 < iTop || iTop === 0) {
      iTop = $(arr[i]).position().top + parseInt(GetStyle(arr[i], "height")) / 2;
    }
  }

  for (var j = 0; j < arr.length; j++) {
    if (id !== arr[j].parentNode.id) continue;
    $(arr[j]).css("top", (iTop - parseInt(GetStyle(arr[j], "height")) / 2) + "px");
  }

  jsPlumb.repaintEverything();
}

//下对齐
function SelectAlignBottom() {
  var arr = getSelectedRegions();
  var iTop = 0;
  var id = "";

  for (var i = 0; i < arr.length; i++) {
    if (id === "") id = arr[i].parentNode.id;
    if (id !== arr[i].parentNode.id) continue;
    if ($(arr[i]).position().top + parseInt(GetStyle(arr[i], "height")) > iTop || iTop === 0) {
      iTop = $(arr[i]).position().top + parseInt(GetStyle(arr[i], "height"));
    }
  }

  for (var j = 0; j < arr.length; j++) {
    if (id !== arr[j].parentNode.id) continue;
    $(arr[j]).css("top", (iTop - parseInt(GetStyle(arr[j], "height"))) + "px");
  }

  jsPlumb.repaintEverything();
}

//上下靠拢
function SelectUpColse() {
  var arr = getSelectedRegions();
  var iTop = 0;
  var id = "";
  for (var i = 0; i < arr.length; i++) {
    if (id === "") id = arr[i].parentNode.id;
    if (id !== arr[i].parentNode.id) continue;
    if (iTop === 0) iTop = $(arr[i]).position().top;
    $(arr[i]).css("top", iTop + "px");
    iTop += parseInt(GetStyle(arr[i], "height"));
  }

  jsPlumb.repaintEverything();
}

//左右靠拢
function SelectLeftColse() {
  var arr = getSelectedRegions();
  var iLeft = 0;
  var id = "";
  for (var i = 0; i < arr.length; i++) {
    if (id === "") id = arr[i].parentNode.id;
    if (id !== arr[i].parentNode.id) continue;
    if (iLeft === 0) iLeft = $(arr[i]).position().left;
    $(arr[i]).css("left", iLeft + "px");
    iLeft += parseInt(GetStyle(arr[i], "width"));
  }

  jsPlumb.repaintEverything();

}

//同高
function SelectSameHeight() {
  var arr = getSelectedRegions();
  var iHeigth = 0;
  var id = "";
  for (var i = 0; i < arr.length; i++) {
    if (id === "") id = arr[i].parentNode.id;
    if (id !== arr[i].parentNode.id) continue;
    if (iHeigth === 0) iHeigth = parseInt(GetStyle(arr[i], "height"));
    $(arr[i]).css("height", iHeigth+"px");
  }

  jsPlumb.repaintEverything();
}

//同宽
function SelectSameWidth() {
  var arr = getSelectedRegions();
  var iWidth = 0;
  var id = "";
  for (var i = 0; i < arr.length; i++) {
    if (id === "") id = arr[i].parentNode.id;
    if (id !== arr[i].parentNode.id) continue;
    if (iWidth === 0) iWidth = parseInt(GetStyle(arr[i], "width"));
    $(arr[i]).css("width", iWidth + "px");
  }

  jsPlumb.repaintEverything();

}

//旋转
function SelectClockwise(index) {
  var arr = getSelectedRegions();
  //var iWidth = 0;
  //var id = "";
  for (var i = 0; i < arr.length; i++) {
    //if (id === "") id = arr[i].parentNode.id;
    //if (id !== arr[i].parentNode.id) continue;
    var sIndex= arr[i].style.transform.replace("rotate(", "").replace("deg)", "");
    var iNum = 0;
    if (sIndex) iNum = parseInt(sIndex);
    $(arr[i]).css("transform", "rotate(" + (iNum + index)%360 + "deg)");

    var points = jsPlumb.getEndpoints(arr[i]);
  }

  jsPlumb.repaintEverything();

}
//删除选中
function DeleteSelect() {
  var arr = getSelectedRegions();
  for (var i = 0; i < arr.length; i++) {
    jsPlumb.remove(arr[i],true);
    //var points = jsPlumb.getEndpoints(arr[i]);
    //for (var j = 0; j < points.length; j++) {
    //  jsPlumb.deleteEndpoint(points[j]);
    //}
    //arr[i].parentNode.removeChild(arr[i]);
    }

  jsPlumb.repaintEverything();

}

function GetStyle(obj, attr) {
  if (obj.currentStyle) {
    return obj.currentStyle[attr]; //只适用于IE
  }
  else {
    return getComputedStyle(obj, false)[attr];  //只适用于FF,Chrome,Safa
  }
  return obj.style[attr]; //本人测试在IE和FF下没有用,chrome有用
}

代码可能有点乱,待整理。上章有博友就找我要过源码,这次出来一个初级的版本,希望可以帮助大家更好的学习流程图的核心技术JsPlumb。

(0)

相关推荐

  • JavaScript中使用Callback控制流程介绍

    javascript中随处可见的callback对于流程控制来说是一场灾难,缺点显而易见: 1.没有显式的return,容易产生多余流程,以及由此引发的bug. 2.造成代码无限嵌套,难以阅读. 下面就来说说怎么解决避免上述的问题. 第一个问题是一个习惯问题,在使用callback的时候往往会让人忘了使用return,这种情况在使用coffee-script的时候尤甚(虽然它在编译成javascript时会自行收集最后的数据作为返回值,但是这个返回值并不一定代表你的初衷).看看下面的例子. 复制

  • 详解js中构造流程图的核心技术JsPlumb

    项目里面用到了Web里面的拖拽流程图的技术JsPlumb,其实真不算难,不过项目里面用HTML做的一些类似flash的效果,感觉还不错,在此分享下. 一.效果图展示 1.从左边拖动元素到中间区域,然后连线 2.连线类型可以自定义:这里定义为直线.折线.曲线.实际项目中根据业务我们定义为分装线.分装支线.总装线等 3.鼠标拖动区域选中元素,并且选中元素统一拖动位置. 4.对选中的元素左对齐. 5.对选中元素居中对齐 6.右对齐 7.上对齐 8.垂直居中对齐 9.下对齐 10.根据第一个选中的元素上

  • js查错流程归纳

    归纳是为了更好的理解.受jQuery "Discussion"(http://docs.jquery.com/Discussion)页面启发,平时同事有问题找我帮忙解决问题,往往都是很小的问题,这种情况他们并不是缺乏解决问题的知识,而是需要找到问题的办法.人总是乐于助人的,能有个好的查错流程可以过滤掉很多简单的小问题^^. 1.确保您的页面元素标记是有效的 2.使用调试工具(例如:Firebug),看看是否有异常 3.引用文件或依赖模块或方法是否有效 4.减少到最小测试用例(保持删除的

  • JavaScript程序中的流程控制语句用法总结

    条件判断语句 1.if语句 if (condition) statement1 else statement2 其中的condition条件可以是任意表达式,而且对这个表达式的求值结果不一定是布尔值.ECMAScript会自动调用Boolean()转换函数将这个表达式的结果转换为一个布尔值.如果对condition求值的结果为true,则执行statement1,如果对condition求值结果为false,则执行statement2.这两个语句既可以是一行代码,也可以是一个代码块(推荐). i

  • 详解JavaScript的流程控制语句

    JS的核心ECMAScript规定的流程控制语句和其他的程序设计语言还是蛮相似的.我们选择一些实用的例子来看 一下这些语句.顺序结构我们在这里就不再提到,直接说条件和循环以及其他语句. 一.条件选择结构        条件选择语句用于基于不同的条件来执行不同的动作,通常在写代码时,总是需要为不同的决定来执行不同的 动作,可以在代码中使用条件语句来完成该任务.        在JavaScript中,我们可使用以下条件语句: if 语句:只有当指定条件为true时,使用该语句来执行代码 <!DOC

  • 整理Javascript流程控制语句学习笔记

    1.做判断(if语句) if语句是基于条件成立才执行相应代码时使用的语句. 语法: if(条件){ 条件成立时执行代码 } 例子:假设你应聘web前端技术开发岗位,如果你会HTML技术,你面试成功,欢迎加入公司. <script type="text/javascript"> var mycarrer = "HTML"; if (mycarrer == "HTML"){ document.write("你面试成功,欢迎加入公

  • ExtJs事件机制基本代码模型和流程解析

    代码实现的目的:为一个自定义的类的某个属性在使用它时候,触发某个事件. 该程序的效果:点击输入按钮,弹出一个脚本提示输入框让用户输入他的姓名,确定后,用户录入的姓名会显示在页面的姓名文本框中,并且页面标题变成和姓名一致,接着再弹出脚本提示输入框让用户输入性别,录入完毕并点击确定后,用户录入的性别将会显示在页面的性别文本框里. 复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" &quo

  • 关于js拖拽上传 [一个拖拽上传修改头像的流程]

    如今现代的浏览器已经有很多支持拖拽文件读取操作,其优点不再复述.前端时间利用拖拽改进了一下网站的头像上传流程,对其中的要点和实践体会做一点总结. 先看一下总体视图:1. 文件拖拽接受区域要有明显的标示,并且要尽可能的大(由于版面的原因,这个界面的拖放盒子并不大).可以用虚线框盒子等样式吸引用户拖拽文件.最好有明显的文字提示和图标配合. 2. 在交互体验上当文件拖入浏览器窗口时,可以用拖放区变换背景颜色等向用户发起放置操作邀请. 实现代码: 复制代码 代码如下: doc.bind({ 'drage

  • 详解js中构造流程图的核心技术JsPlumb(2)

    前言:上篇详解js中构造流程图的核心技术JsPlumb介绍了下JsPlumb在浏览器里面画流程图的效果展示,以及简单的JsPlumb代码示例.这篇还是接着来看看各个效果的代码说明. 一.设置连线的样式和颜色效果代码示例 大概的效果如图: 这些效果看着很简单,那么,我们如何用代码去实现它呢.上章我们说过,JsPlumb的连线样式是由点的某些属性决定的,既然如此,我们就通过设置点的样式来动态改变连线的样式即可.来看代码: 首先来看看连线类型的那个select <div id="btn_line

  • 详解JS中的对象字面量

    前言 在 ES6 之前,js中的对象字面量(也称为对象初始化器)是非常基础的.可以定义两种类型的属性: 键值对{name1: value1} 获取器{ get name(){..} }和 设置器{ set name(val){..}}的计算属性值 var myObject = { myString: 'value 1', get myNumber() { return this._myNumber; }, set myNumber(value) { this._myNumber = Number

  • 详解js中的几种常用设计模式

    工厂模式 function createPerson(name, age){ var o = new Object(); // 创建一个对象 o.name = name; o.age = age; o.sayName = function(){ console.log(this.name) } return o; // 返回这个对象 } var person1 = createPerson('ccc', 18) var person2 = createPerson('www', 18) 工厂函数

  • 详解js中的原型,原型对象,原型链

    理解原型 我们创建的每一个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法.看如下例子: function Person(){ } Person.prototype.name = 'ccc' Person.prototype.age = 18 Person.prototype.sayName = function (){ console.log(this.name); } var person1 = ne

  • 详解JS中的compose函数和pipe函数用法

    compose函数 compose函数可以将需要嵌套执行的函数平铺,嵌套执行就是一个函数的返回值将作为另一个函数的参数.我们考虑一个简单的需求:这个需求很简单,直接一个计算函数就行: const calculate = x => (x + 10) * 10; let res = calculate(10); console.log(res); // 200 但是根据我们之前讲的函数式编程,我们可以将复杂的几个步骤拆成几个简单的可复用的简单步骤,于是我们拆出了一个加法函数和一个乘法函数: cons

  • 详解JS中的reduce fold unfold用法

    fold(reduce) 说说reduce吧, 很喜欢这个函数,节省了不少代码量,而且有一些声明式的雏形了,一些常见的工具函数,flatten,deepCopy,mergeDeep等用reduce实现的很优雅简洁.reduce也称为fold,本质上就是一个折叠数组的过程,把数组中的多个值经过运算变成一个值,每次运算都会有一个函数处理,这个函数就是reduce的核心元素,称之为reducer,reducer函数是个2元函数,返回1个单值,常见的add函数就是reducer const addRed

  • 详解JS中你不知道的各种循环测速

    前言 在测试循环速度之前,我们先来创建一个有 100 万数据的数组: const len = 100 * 10000; const arr = []; for (let i = 0; i < len; i++) { arr.push(Math.floor(Math.random() * len)); } 测试环境为: 1.电脑:iMac(10.13.6): 2.处理器:4.2 GHz Intel Core i7: 3.浏览器:Chrome(89.0.4389.82) 1. for 循环 for

  • 一文详解JS中的事件循环机制

    目录 前言 1.JavaScript是单线程的 2.同步和异步 3.事件循环 前言 我们知道JavaScript 是单线程的编程语言,只能同一时间内做一件事,按顺序来处理事件,但是在遇到异步事件的时候,js线程并没有阻塞,还会继续执行,这又是为什么呢?本文来总结一下js 的事件循环机制. 1.JavaScript是单线程的 JavaScript 是一种单线程的编程语言,只有一个调用栈,决定了它在同一时间只能做一件事.在代码执行的时候,通过将不同函数的执行上下文压入执行栈中来保证代码的有序执行.在

  • 实例详解JS中的事件循环机制

    目录 一.前言 二.宏.微任务 三.Tick 执行顺序 四.案例详解 1.掺杂setTimeout 2.掺杂微任务,此处主要是Promise.then 3.掺杂async/await 一.前言 之前我们把react相关钩子函数大致介绍了一遍,这一系列完结之后我莫名感到空虚,不知道接下来应该更新有关哪方面的文章.最近想了想,打算先回归一遍JS基础,把一些比较重要的基础知识点回顾一下,然后继续撸框架(可能是源码.也可能补全下全家桶).不积跬步无以至千里,万丈高楼咱们先从JS的事件循环机制开始吧,废话

随机推荐