文末
技术是没有终点的,也是学不完的,最重要的是活着、不秃。
零基础入门的时候看书还是看视频,我觉得成年人,何必做选择题呢,两个都要。喜欢看书就看书,喜欢看视频就看视频。
最重要的是在自学的过程中,一定不要眼高手低,要实战,把学到的技术投入到项目当中,解决问题,之后进一步锤炼自己的技术。
自学最怕的就是缺乏自驱力,一定要自律,杜绝“三天打鱼两天晒网”,到最后白忙活一场。
高度自律的同时,要保持耐心,不抛弃不放弃,切勿自怨自艾,每天给自己一点点鼓励,学习的劲头就会很足,不容易犯困。
技术学到手后,找工作的时候一定要好好准备一份简历,不要无头苍蝇一样去海投简历,容易“竹篮打水一场空”。好好的准备一下简历,毕竟是找工作的敲门砖。
拿到面试邀请后,在面试的过程中一定要大大方方,尽力把自己学到的知识舒适地表达出来,不要因为是自学就不够自信,给面试官一个好的印象,面试成功的几率就会大很多,加油吧,骚年!
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
mxClient.defaultBundles.push(mxClient.basePath + '/resources/graph');
}
在创建mxGraph实例时,如果传入了container则会调用init方法进行初始化并创建相应的数据结构:
/**
-
container - DOM结点用于包含graph
*/
mxGraph.prototype.init = function (container) {
this.container = container;// 初始化就地编辑器
this.cellEditor = this.createCellEditor();// 使用视图初始化容器
this.view.init();// 更新当前图形的容器大小
this.sizeDidChange();// 如果鼠标离开容器,则隐藏工具提示并重置工具提示计时器
mxEvent.addListener(container, ‘mouseleave’, mxUtils.bind(this, function () {
if (this.tooltipHandler != null) {
this.tooltipHandler.hide();
}
}));// 自动释放内存
if (mxClient.IS_IE) {
mxEvent.addListener(window, ‘unload’, mxUtils.bind(this, function () {
this.destroy();
}));// 禁用文本的shift-click mxEvent.addListener(container, 'selectstart', mxUtils.bind(this, function (evt) { return this.isEditing() || (!this.isMouseDown && !mxEvent.isShiftDown(evt)); }) );
}
// 如果没有显示初始图形或没有定义形状标签,则在IE8标准模式下缺少最后一个形状和连接预览的解决方法
if (document.documentMode == 8) {
container.insertAdjacentHTML(‘beforeend’, ‘<’ + mxClient.VML_PREFIX + ‘:group’ +
’ style=“DISPLAY: none;”></’ + mxClient.VML_PREFIX + ‘:group>’);
}
};
### 3. 功能性
由于mxGraph定义了很多原型属性,这里不能一一列举,需要的时候可以查看源码。主要关注mxGraph功能性方面有哪些,以及结构如何。
#### 3.1 句柄
mxGraph会在init方法调用之前创建几个句柄用于处理对应的事件,有如下几个句柄:tooltip、panning、connection、graph,不过目前都是关闭的:
mxGraph.prototype.createHandlers = function () {
this.tooltipHandler = this.createTooltipHandler();
this.tooltipHandler.setEnabled(false);
this.selectionCellsHandler = this.createSelectionCellsHandler();
this.connectionHandler = this.createConnectionHandler();
this.connectionHandler.setEnabled(false);
this.graphHandler = this.createGraphHandler();
this.panningHandler = this.createPanningHandler();
this.panningHandler.panningEnabled = false;
this.popupMenuHandler = this.createPopupMenuHandler();
};
#### 3.2 cell重叠
当cell重叠时,mxGraph需要额外进行一些操作记录重叠的cell并更新graph的显示,这样才能实现cell重叠层次的改变:
/**
-
cell - 被叠加的mxCell
-
overlay - 添加到cell上的mxCellOverlay
*/
mxGraph.prototype.addCellOverlay = function (cell, overlay) {
// overlays是实例变量
if (cell.overlays == null) {
cell.overlays = [];
}cell.overlays.push(overlay);
var state = this.view.getState(cell);
// 如果state存在,立即更新cell的重叠显示
// state保存的是cell在graph中的所有状态
if (state != null) {
this.cellRenderer.redraw(state);
}this.fireEvent(new mxEventObject(mxEvent.ADD_OVERLAY,
‘cell’, cell, ‘overlay’, overlay));return overlay;
};
还有其他相关方法:getCellOverlays、removeCellOverlay、removeCellOverlays、clearCellOverlays,这里就不详述具体实现了。
#### 3.3 就地编辑
就地编辑通过在graph中双击触发,可以在双击的地方创建一个文本输入框,具体实现如下:
/**
-
cell - 开始就地编辑的cell
-
evt - 可选的触发编辑的鼠标事件
*/
mxGraph.prototype.startEditingAtCell = function (cell, evt) {
if (evt == null || !mxEvent.isMultiTouchEvent(evt)) {
if (cell == null) {
cell = this.getSelectionCell();// 选中的cell是否可以编辑 if (cell != null && !this.isCellEditable(cell)) { cell = null; } } if (cell != null) { // 触发START_EDITING事件 this.fireEvent(new mxEventObject(mxEvent.START_EDITING, 'cell', cell, 'event', evt)); // 开始编辑 this.cellEditor.startEditing(cell, evt); // 触发EDITING_STARTED事件 this.fireEvent(new mxEventObject(mxEvent.EDITING_STARTED, 'cell', cell, 'event', evt)); }
}
};
还有其他相关方法:getEditingValue、stopEditing、labelChanged、cellLabelChanged、escape,这里就不详述具体实现了。
#### 3.4 事件处理
事件处理方法的具体实现各异,不能一一详述,只需要知道如何触发,以及有什么效果即可,列举几个事件处理函数:
| 方法 | 描述 |
| --- | --- |
| escape | 处理ESC键事件 |
| click | 处理cell上的单击事件 |
| dblClick | 处理cell上的双击事件 |
| tapAndHold | 处理按住cell的事件 |
#### 3.5 Cell样式
cell的样式处理有许多方法,列举几个graph处理cell的方法,这里不详述了:
| 方法 | 描述 |
| --- | --- |
| getCellStyle | 返回表示给定cell样式的键值对的数组 |
| setCellStyle | 设置指定cell的样式。 如果没有给出cell,则改变选中的cell |
| toggleCellStyle | 以给定cell的样式切换给定键的布尔值,并将新值返回为0或1。如果未指定cell,则使用选中的cell |
| setCellStyleFlags | 在指定cell的样式中设置或切换给定键的给定位 |
#### 3.6 Cell的排列和方向
这里涉及处理cell的排列和方向的许多方法,列举一些就不详述了:
| 方法 | 描述 |
| --- | --- |
| alignCells | 使用可选参数作为坐标,根据给定的对齐方式垂直或水平对齐给定cell |
| flipEdge | 在null(或空)和alternateEdgeStyle之间切换给定边的样式。事务正在进行时,此方法将触发mxEvent.FLIP\_EDGE。返回被翻转的边 |
| addImageBundle | 添加指定的mxImageBundle |
| orderCells | 将给定的cell移动到前面或后面。使用cellsOrdered执行更改。事务正在进行时,此方法将触发mxEvent.ORDER\_CELLS |
#### 3.7 分组
graph的分组是一个非常强大的功能,列举一些方法:
| 方法 | 描述 |
| --- | --- |
| groupCells | 将cell添加到给定组中。使用cellsAdded,cellsMoved和cellsResized执行更改。事务正在进行时,此方法将触发mxEvent.GROUP\_CELLS。返回新组。仅当给定cell数组中至少有一个条目时,才会创建组 |
| getBoundsForGroup | 返回用于给定组和子项的边界 |
| createGroupCell | 如果没有为group函数提供组cell,则钩子用于创建组cell以保存给定的mxCells数组 |
#### 3.8 Cell克隆、插入和删除
graph的cell可以克隆、插入,也可以删除,列举一些常用的方法:
| 方法 | 描述 |
| --- | --- |
| cloneCells | 返回给定cell的克隆。克隆是使用mxGraphModel.cloneCells递归创建的。如果Edge的终端不在给定阵列中,则为相应的端分配终端点并移除终端 |
| insertVertex | 使用value作为用户对象并将给定坐标作为新vertex的mxGeometry,将新vertex添加到给定父mxCell中。id和style用于返回的新mxCell的各个属性 |
| removeCells | 如果includeEdges为true,则从graph中移除给定的cell,包括所有连接的edge。使用cellsRemoved执行更改。事务正在进行时,此方法将触发mxEvent.REMOVE\_CELLS。删除的单元格作为数组返回 |
#### 3.9 Cell的可见性
cell能设置它的可见性,用如下两个方法设置:
| 方法 | 描述 |
| --- | --- |
| toggleCells | 如果includeEdges为true,则设置指定cell和所有连接edge的可见状态。使用cellsToggled执行更改。事务正在进行时,此方法将触发mxEvent.TOGGLE\_CELLS。返回可见状态已更改的cell |
| cellsToggled | 设置指定cell的可见状态 |
#### 3.10 折叠
graph的分组以及有些cell是可以折叠的,用如下方法实现:
| 方法 | 描述 |
| --- | --- |
| foldCells | 如果recurse为true,则设置指定cell和所有后代的折叠状态。使用cellsFolded执行更改。事务正在进行时,此方法将触发mxEvent.FOLD\_CELLS。返回折叠状态已更改的cell |
| swapBounds | 在执行交换之前,交换调用updateAlternateBounds的给定cell的几何中的替代边界和实际边界 |
#### 3.11 Cell大小
列举一些改变cell大小的方法:
| 方法 | 描述 |
| --- | --- |
| updateCellSize | 使用cellSizeUpdated更新模型中给定cell的大小。事务正在进行时,此方法将触发mxEvent.UPDATE\_CELL\_SIZE。返回其大小已更新的单元格 |
| getPreferredSizeForCell | 返回给定mxCell的首选宽度和高度,作为mxRectangle。要实现最小宽度,要添加新样式 |
| resizeCell | 使用resizeCells设置给定cell的边界。返回传递给函数的cell |
| resizeChildCells | 相对于cell的当前几何图形,针对给定的新几何图形调整给定cell的子cell的大小 |
#### 3.12 Cell移动
列举一些移动cell的方法:
| 方法 | 描述 |
| --- | --- |
| importCells | 使用move方法克隆并将给定cell插入到图形中,并返回插入的cell。如果通过datatransfer插入cell,则使用此快捷方式 |
| moveCells | 移动或克隆指定的cell,并按给定的数量移动cell或克隆,将它们添加到可选的目标cell中。当鼠标被释放时,evt是鼠标事件。 使用cellsMoved执行更改。事务正在进行时,此方法将触发mxEvent.MOVE\_CELLS。返回已移动的cell |
| translateCell | 转换给定cell的几何图形,并将新的,已转换的几何图形作为原子更改存储在模型中 |
#### 3.13 Cell连接及其约束
列举一些cell连接,和连接约束的方法:
| 方法 | 描述 |
| --- | --- |
| getOutlineConstraint | 返回用于连接到给定状态轮廓的约束 |
| getAllConnectionConstraints | 返回给定终端的所有mxConnectionConstraints的数组。 如果给定终端的形状是mxStencilShape,则返回相应mxStencil的约束 |
| getConnectionPoint | 返回绝对点列表中最近的点或相对终端的中心 |
| connectCell | 在事务正在进行时,使用cellConnected将给定边的指定端连接到给定终端并触发mxEvent.CONNECT\_CELL。返回更新的边缘 |
#### 3.14 追溯
列举一些追溯cell关系的方法:
| 方法 | 描述 |
| --- | --- |
| getCurrentRoot | 返回显示的单元格层次结构的当前根。这是view中mxGraphView.currentRoot的快捷方式 |
| getTerminalForPort | 返回用于给定端口的终端。此实现始终返回父单元格 |
| enterGroup | 使用给定的单元格作为显示的单元格层次结构的根。如果未指定单元格,则使用选择单元格。仅当isValidRoot返回true时才使用该单元格 |
| home | 使用模型的根作为显示的单元层次结构的根,并选择以前的根 |
#### 3.15 graph显示
列举一些graph显示相关的方法:
| 方法 | 描述 |
| --- | --- |
| getGraphBounds | 返回可见图的边界。mxGraphView.getGraphBounds的快捷方式 |
| getCellBounds | 返回给定单元格的缩放,平移边界 |
| refresh | 清除从给定单元格开始的层次结构的所有单元格状态或状态,并验证图形。 这会触发刷新事件作为最后一步 |
| snap | 如果gridEnabled为true,则将给定的数值捕捉到网格 |
| panGraph | 按给定的量移动图表显示。这用于预览平移操作,使用mxGraphView.setTranslate设置视图的持久转换。触发mxEvent.PAN |
| zoomIn | 通过zoomFactor放大图形 |
| zoomOut | 通过zoomFactor缩小图表 |
| center | 将图表置于容器中心 |
#### 3.16 验证
列举一些验证性的方法:
| 方法 | 描述 |
| --- | --- |
| validationAlert | 在对话框中显示给定的验证错误。此实现使用mxUtils.alert |
| isEdgeValid | 检查给定参数的getEdgeValidationError的返回值是否为null |
| validateGraph | 通过验证给定单元格的每个后代或模型的根来验证图形。Context是一个包含完整验证运行的验证状态的对象。使用setCellWarning将验证错误附加到其单元格。在成功验证的情况下返回null,或者在验证失败的情况下返回字符串数组(警告) |
| getCellValidationError | 检查在修改图形时不能强制执行的所有multiplicities,即所有需要至少1个边缘的多重性 |
#### 3.17 graph外观
列举一些graph外观相关的方法:
| 方法 | 描述 |
| --- | --- |
| setBackgroundImage | 设置新的backgroundImage |
| getFoldingImage | 返回用于显示指定单元状态的折叠状态的mxImage。这将为所有边返回null |
| getLabel | 返回表示给定单元格标签的字符串或DOM节点。如果labelsVisible为true,则此实现使用convertValueToString。否则返回一个空字符串 |
#### 3.18 graph行为
列举一些graph行为相关的方法:
| 方法 | 描述 |
| --- | --- |
| isResizeContainer | 设置resizeContainer |
| isCellLocked | 如果无法移动,调整大小,弯曲,断开连接,编辑或选择给定单元格,则返回true。如果locked为false,则对于具有相对几何的所有顶点,此实现返回true |
| getCloneableCells | 返回可在给定单元格数组中导出的单元格 |
#### 3.19 获取Cell
列举一些graph行为相关的方法:
| 方法 | 描述 |
| --- | --- |
| getDefaultParent | 如果两者都为null,则返回defaultParent或mxGraphView.currentRoot或mxGraphModel.root的第一个子子项。此函数返回的值应该用作新单元格(也就是默认图层)的父级 |
| getSwimlane | 返回给定单元格的最近祖先,如果泳道本身是泳道,则返回泳道或给定单元格 |
| getCellAt | 返回与给定父级开始的单元层次结构中给定点(x,y)相交的最底部单元格。 如果给定位置与泳道的内容区域相交,这也将返回泳道。 如果不希望这样,那么如果返回的单元格是泳道,则可以使用hitsSwimlaneContent来确定该位置是在内容区域内还是在泳道的实际标题上 |
#### 3.20 选中
列举一些跟选中相关的方法:
| 方法 | 描述 |
| --- | --- |
| isCellSelected | 如果选择了给定单元格,则返回true |
| isSelectionEmpty | 如果选择为空,则返回true |
| getSelectionCells | 返回所选mxCells的数组 |
#### 3.21 选中状态
列举一些跟选中状态相关的方法:
| 方法 | 描述 |
| --- | --- |
| createHandler | 为给定的单元格状态创建一个新的处理程序。 此实现返回相应单元格的新mxEdgeHandler是边缘,否则返回mxVertexHandler |
| createVertexHandler | 挂钩为给定的mxCellState创建新的mxVertexHandler |
| createEdgeHandler | 挂钩为给定的mxCellState创建新的mxEdgeHandler |
#### 3.22 graph事件
列举一些graph事件相关的方法:
| 方法 | 描述 |
| --- | --- |
| addMouseListener | 向图形事件调度循环添加侦听器。监听器必须实现mouseDown,mouseMove和mouseUp方法,如mxMouseEvent类所示 |
| updateMouseEvent | 如果需要,设置给定wxMouseEvent的图形和graphY属性,并返回事件 |
| getStateForTouchEvent | 返回给定触摸事件的状态 |
## 【mxGraph】源码学习:mxCell
### 1. 概览
mxCell是graph model的元素。它们表示graph中的group、vertex和edge的状态。
对于自定义属性,建议使用XML节点作为cell的值。以下代码可用于创建具有XML节点的cell作为值:
var doc = mxUtils.createXmlDocument();
var node = doc.createElement(‘MyNode’)
node.setAttribute(‘label’, ‘MyLabel’);
node.setAttribute(‘attribute1’, ‘value1’);
graph.insertVertex(graph.getDefaultParent(), null, node, 40, 40, 80, 30);
要使标签起作用,应重写mxGraph.convertValueToString和mxGraph.cellLabelChanged,如下所示:
graph.convertValueToString = function(cell) {
if (mxUtils.isNode(cell.value)) {
return cell.getAttribute(‘label’, ‘’)
}
};
var cellLabelChanged = graph.cellLabelChanged;
graph.cellLabelChanged = function(cell, newValue, autoSize) {
if (mxUtils.isNode(cell.value)) {
// clone正确撤消/重做的值
var elt = cell.value.cloneNode(true);
elt.setAttribute(‘label’, newValue);
newValue = elt;
}
cellLabelChanged.apply(this, arguments);
};
### 2. 构造
mxCell的构造函数如下:
/**
-
value - 表示cell值的可选对象。
-
geometry - 可选的mxGeometry,用于指定几何体。
-
style - 可选的格式化字符串,用于定义样式
*/
function mxCell(value, geometry, style) {
this.value = value;
this.setGeometry(geometry);
this.setStyle(style);if (this.onInit != null) {
this.onInit();
}
}
### 3. 原型属性
列举一些mxCell的原型属性:
// cell的id。默认为null
mxCell.prototype.id = null;
// 用户对象。默认为null
mxCell.prototype.value = null;
// mxGeometry表示cell的几何状态。默认为null
mxCell.prototype.geometry = null;
// 将样式保存为[(stylename|key = value);]形式的字符串。默认值为null
mxCell.prototype.style = null;
// 指定cell是否为vertex。默认值为false
mxCell.prototype.vertex = false;
// 指定cell是否为edge。默认值为false
mxCell.prototype.edge = false;
// 指向父cell
mxCell.prototype.parent = null;
// 指向子cell
mxCell.prototype.children = null;
// 不应在clone中克隆的成员列表。此字段将传递给mxUtils.clone,并且不会在mxCellCodec中保持持久性。
// 这不是所有类的约定,它仅在此类中用于标记瞬态字段,因为js不支持瞬态修饰符。
mxCell.prototype.mxTransient = [‘id’, ‘value’, ‘parent’, ‘source’,
‘target’, ‘children’, ‘edges’];
### 4. 原型方法
除了原型属性的getter和setter外,列举几个方法的实现:
/**
-
将指定的edge插入edge数组并返回edge。将更新edge的相应终端参考
-
edge - 要插入edge数组的mxCell
-
isOutgoing - Boolean,指定边是否外支
*/
mxCell.prototype.insertEdge = function (edge, isOutgoing) {
if (edge != null) {
edge.removeFromTerminal(isOutgoing);
edge.setTerminal(this, isOutgoing);if (this.edges == null || edge.getTerminal(!isOutgoing) != this || mxUtils.indexOf(this.edges, edge) < 0) { if (this.edges == null) { this.edges = []; } this.edges.push(edge); }
}
return edge;
};
/**
-
返回cell的克隆。使用cloneValue克隆用户对象。克隆过程中将忽略mxTransient中的所有字段
*/
mxCell.prototype.clone = function () {
var clone = mxUtils.clone(this, this.mxTransient);
clone.setValue(this.cloneValue());return clone;
};
/**
-
返回cell用户对象的克隆。
*/
mxCell.prototype.cloneValue = function () {
var value = this.getValue();if (value != null) {
总结
面试前要精心做好准备,简历上写的知识点和原理都需要准备好,项目上多想想难点和亮点,这是面试时能和别人不一样的地方。
还有就是表现出自己的谦虚好学,以及对于未来持续进阶的规划,企业招人更偏爱稳定的人。
万事开头难,但是程序员这一条路坚持几年后发展空间还是非常大的,一切重在坚持。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
前端面试题汇总
JavaScript
前端资料汇总