").replace(/ /g, " ");
_text.trim() != "" && U.UF.E.textFormat(_text, editor); //文字格式化处理
U.UF.EV.stopDefault(); //去除默认事件
return _text.trim();
}
/* 粘贴的处理
*
* @param text {string} 需要处理的文字
* @param range {object} 光标对象
*
*/
U.UF.E.textFormat = function (text, editor) {
var _editor = editor || this.editor;
var _range = U.UF.E.getRangeAt(), //获取光标选取
_div = $$("div", { "innerHTML": text, "style": { "display": "none" } }, U.selectEl("body")[0]), //内容
_frag = U.UF.E.unifiedFormat(_div); //获取拆分的值
U.UF.E.insertContent(_frag, _range, _editor); //调用指定位置插入内容的函数
//获取table进行初始化
var _table = U.selectEl('table', _editor);
//表格处理 写在这里
for (var i = _table.length - 1; i >= 0; i--) {
U.UF.E.table.load(_table[i]);
}
U.selectEl(_div).remove(); //删除div元素
}
/* 在指定位置插入内容
*
* @param el {element} 插入的元素 frag临时标签
* @param range {object} 光标对象
*
*/
U.UF.E.insertContent = function (el, range, editor) {
range = range || U.UF.E.getRangeAt(); //获取光标选取
//html5浏览器
if (window.getSelection) {
//if (window.getSelection && el.textContent) {
var _i, //循环变量
_frag,
_stylecsstext,
_span,
_child = el.childNodes, //获取插入元素的所有孩子节点
_lastchild, //记录最后一个孩子节点变量
_extractcontent, //记录删除选区内容
_record,
_focusel,
_frag = $$("frag"), //创建frag 临时标签
_startline = range.startContainer == editor ? editor.children[0] : U.UF.E.getLineElement(range.startContainer), //选择的行
_endline = range.endContainer == editor ? editor.children[0] : U.UF.E.getLineElement(range.endContainer), //选择的列
_selection = window.getSelection()//获取选区函数
;
if (editor.innerHTML == "") {
_record = { addLine: [] };
for (_i = 0; _i < _child.length;) {
_record.addLine.push(_child[_i].id);
//循环把选区内容元素插入到临时标签中
editor.appendChild(_child[_i]);
}
U.UF.E.elementFocus(range, editor.children[0], true); //重新聚焦元素
editor.editor.recordHTML = editor.children[editor.children.length - 1].outerHTML;
}
else {
_record = { updateLine: [_startline.id], addLine: [] };
//移除选取的内容
range.deleteContents(); //移除文字
_selection.removeAllRanges(); //移除选取
//剪切区域移除br标签,反正br导致多次换行
// U.selectEl("br", _startline).remove(); //移除所有的br标签
// U.selectEl("br", _endline).remove(); //移除所有的br标签
_lastchild = _endline.lastChild; //获取结束行最后一个元素
//粘贴的第一行有内容的处理
if (_lastchild && (_lastchild.innerHTML != undefined || _lastchild.data != undefined)) {
_stylecsstext = (_lastchild.style || _lastchild.parentNode.style).cssText; //首行的样式处理
_focusel = _child[_child.length - 1].childNodes[_child[_child.length - 1].childNodes.length - 1] || _child[_child.length - 1]; //剪切后最后聚焦的元素
//结束行是向前插入,先把结束好的文字剪切走
try {
range.setEnd(_lastchild, _lastchild.innerHTML != undefined ? 1 : _lastchild.data.length); //设置光标结束的位置
}
catch (e) {
range.setEnd(_lastchild, 0); //设置光标结束的位置
}
_extractcontent = range.extractContents(); //记录删除选区内容
//把最后一行选取的内容如果是文本那么转化成span标签 _extractcontent.childNodes[0].nodeType == 3 && U.UF.E.validElement(_extractcontent)
if (_extractcontent.childNodes.length == 1) {
//重新创建一个新的粘贴信息
_frag = $$("frag");
_span = $$("span", { "style": { "cssText": _stylecsstext }, "innerHTML": _extractcontent.textContent }, _frag);
//_span.appendChild(_extractcontent);
_extractcontent = _frag;
}
//如果选取最后一行的内容是div说明是整行的处理
if (_extractcontent.childNodes[0] && _extractcontent.childNodes[0].tagName == "DIV") {
//把行元素所有的元素添加到粘贴元素李
for (_i = 0; _i < _extractcontent.childNodes[0].childNodes.length; _i) {
//样式的设置
_extractcontent.childNodes[0].childNodes[_i].style.cssText = _extractcontent.childNodes[0].style.cssText + ";" + _extractcontent.childNodes[0].childNodes[_i].style.cssText;
_child[_child.length - 1].appendChild(_extractcontent.childNodes[0].childNodes[_i]);
}
}
//否则就是内容
else {
_child[_child.length - 1].appendChild(_extractcontent); //将选区内容元素插入到选区最后一个节点
}
//第一行添加
for (_i = 0; _i < el.childNodes[0].childNodes.length; _i) {
_startline.appendChild(el.childNodes[0].childNodes[_i]); //设置第一行的内容为插入元素的内容
}
}
//否则其他的情况
else if (_child[0]) {
//设置起始行的样式为选区孩子节点的第一个元素的样式
_startline.style.cssText += " " + U.UF.E.getRemainAttr(_child[0]);
//设置起始行的内容为插入元素的第一个孩子节点的内容
_startline.innerHTML = _child[0].innerHTML;
_focusel = _startline;
}
//循环中间行添加处理
for (_i = 1; _i < _child.length;) {
_record.addLine.push(_child[_i].id);
//循环把选区内容元素插入到临时标签中
_frag.appendChild(_child[_i]);
}
U.selectEl(_startline.parentNode).append(_frag, 0, U.selectEl(_startline).next()[0]); //添加到选择行的后面
U.UF.E.elementFocus(range, _focusel, true); //重新聚焦元素
var _focusline = U.UF.E.getLineElement(_focusel);
if (_focusline != _startline) {
editor.editor.recordRange = range;
}
editor.editor.recordHTML = _focusline.outerHTML;
}
U.UF.E.operationNotice(_record, editor);
clearTimeout(editor.editor.interval); //取消计时更新
}
//低版本的ie兼容
else {
range.pasteHTML(el.outerHTML); //添加选取文字
}
};
/* 元素全选聚焦
*
* @param range {object} range光标对象
* @param el {element} 编辑的元素
*
*/
U.UF.E.elementFocus = function (range, el, islast) {
//html5得到光标的处理
if (window.getSelection) {
var _selection = window.getSelection(); //选择选取的处理
range.selectNodeContents(el); //添加选取的光标
_selection.removeAllRanges(); //移除所有的光标
_selection.addRange(range); //把聚焦元素的光标添加进去
//判断光标是否放在最后面
if (islast) {
range.collapse(false);
}
}
//ie系列的处理,ie系列不支持win.getSelection,有自己独特的属性
else {
range.moveToElementText(el); //光标移动到指定的元素位置
range.select(); //聚焦选择
}
};
/* 创建贯标
*
*
*/
U.UF.E.createRnage = function () {
//html5得到光标的处理
if (window.getSelection) {
return document.createRange();
}
//ie系列的处理,ie系列不支持win.getSelection,有自己独特的属性
else {
return document.body.createTextRange();
}
}
/* 初始化光标处理,要求光标必须聚焦到编辑区域里,否则这里获取就会失败
*
* @param win {window} 编辑的域
* @return {object} 光标编辑对象
*
*/
U.UF.E.getRangeAt = function (win) {
var _selection, //选取对象
_range //光标对象
;
win = win || window; //获取创建光标的域
//html5得到光标的处理
if (win.getSelection) {
_selection = win.getSelection(); //获取选取对象
//当获取选取中有光标的处理
if (_selection.rangeCount) {
_range = _selection.getRangeAt(0); //返回选区的处理
}
}
//ie系列的处理,ie系列不支持win.getSelection,有自己独特的属性
else {
_selection = win.document.selection; //获取选取对象
_range = _selection.createRange(); //光标对象
}
return _range; //光标的处理
};
/* 替换选区内容处理,可添加元素html代码。
*
* @param str {string} 需要插入的文字
* @param range {object} range光标对象
* @param islast {boolean} 是否聚焦到最后
* @return {object} 光标编辑对象
*/
U.UF.E.addRange = function (str, range, islast) {
range = range || U.UF.E.getRangeAt(); //获取光标处理
//html5得到光标的处理
if (window.getSelection) {
var _selection = window.getSelection(), //获取选取对象
_frag = range.createContextualFragment(str); //创建选取
range.deleteContents(); //移除文字
_selection.removeAllRanges(); //移除选取
range.insertNode(_frag); //插入需要写入的内容
//判断光标是否放在最后面
if (islast) {
range.collapse(false);
}
_selection.addRange(range); //把替换的文章添加到当前指定的选取中
}
//ie系列的处理,ie系列不支持win.getSelection,有自己独特的属性
else {
range.select(); //选取聚焦
range.pasteHTML(str); //添加选取文字
//判断光标是否放在最后面
if (islast) {
range.collapse(false);
}
}
//上面重新操作光标后,需要重新聚焦
return U.UF.E.getRangeAt();
};
/* 在光标中获取现在聚焦的元素
*
* @param range {object} range光标对象
*/
U.UF.E.getRangeElement = function (range) {
//html5得到光标的处理
if (range.commonAncestorContainer) {
return range.commonAncestorContainer;
}
//ie系列的处理,ie系列不支持win.getSelection,有自己独特的属性
else {
//正常选择元素获取元素的处理
if (range.parentElement) {
return range.parentElement();
}
//图片无法像上面的方法一样获取元素,需要通过commonParentElement获取元素
else {
return range.commonParentElement();
}
}
};
/* 重新选中指定的光标
*
* @param range {object} range光标对象
*/
U.UF.E.reSelectRange = function (range) {
//html5得到光标的处理
if (window.getSelection) {
var _selection = window.getSelection(); //获取选取对象
_selection.removeAllRanges(); //移除选取
_selection.addRange(range); //光标重新聚焦处理
}
//ie系列的处理,ie系列不支持win.getSelection,有自己独特的属性
else {
range.select(); //选取聚焦
}
};
/* 设置编辑样式
*
* @param attr {object} 给指定的光标设置样式
* @param range {object} 非必传参数 range光标对象
* */
U.UF.E.setRangeStyle = function (attr, range, editor) {
range = range || U.UF.E.getRangeAt(); //获取光标处理
if (range.startContainer == range.endContainer && range.startOffset == range.endOffset) {
return true;
}
var _i, //循环变量定义
_textstyle, //记录文本样式
_isdel, //是否删除
_start = range.startContainer, //选区起始元素
_end = range.endContainer, //选区结束元素
_startoffset = range.startOffset, //开始位置
_endoffset = range.endOffset, //结束位置
_startline = U.UF.E.getLineElement(_start), //获取选区起始行元素
_endline = U.UF.E.getLineElement(_end), //获取选区结束行元素
_frag = $$("frag") //创建临时元素 用于做记录d
;
editor = editor || _startline.parentNode; //编辑区域元素
if (!editor.editor) { return; }
var _record = U.UF.E.getUpdateLine(_startline, _endline, editor); //得到修改记录
//判断是否选区在同一行
if (_startline != _endline) {
//不同行处理
var _rangselect = range.extractContents().childNodes; //获取选区的所有元素
//记录新选区的起始元素
_start = _rangselect[0].childNodes[0];
//记录文字装饰样式
_textstyle = attr["text-decoration"] || attr["textDecoration"];
//第一行样式设置
U.UF.E.setStyle(attr, _rangselect[0], true);
if (attr.cssText == "") {
_startline.style.cssText = "";
}
//设置样式后的元素循环添加到第一行中
while (_rangselect[0].childNodes[0]) {
_startline.appendChild(_rangselect[0].childNodes[0]);
}
//如果存在文字装饰样式
if (_textstyle) {
//标记设置的样式中是否已存在 存在为1 不存在为 0
_isdel = (attr["text-decoration"] || attr["textDecoration"] || "").indexOf(_textstyle) > -1 ? 1 : 0;
attr["text-decoration"] = _textstyle;
}
//循环除第一行和最后一行的每一行的处理
for (_i = 1; _i < _rangselect.length - 1;) {
//设置每一行的样式
U.UF.E.setStyle(attr, _rangselect[_i], _isdel);
if (_textstyle) {
attr["text-decoration"] = _textstyle;
}
if (attr.cssText == "") {
_rangselect[_i].style.cssText = "";
}
//追加到临时标签中
_frag.appendChild(_rangselect[_i]);
}
//最后一行样式设置
U.UF.E.setStyle(attr, _rangselect[_rangselect.length - 1], _isdel);
//获取选区最后一行元素
var _end = _rangselect[_rangselect.length - 1].childNodes[_rangselect[_rangselect.length - 1].childNodes.length - 1];
//设置样式后的元素循环添加到最后一行中
while (_rangselect[_rangselect.length - 1].childNodes[0]) {
U.selectEl(_endline).append(_rangselect[_rangselect.length - 1].childNodes[_rangselect[_rangselect.length - 1].childNodes.length - 1], 0, _endline.firstChild);
}
if (attr.cssText == "") {
_endline.style.cssText = "";
}
range.insertNode(_frag); //插入需要写入的内容
U.UF.E.setRange(_start, _end || _start, 0, 1, range); //设置选区 重新聚焦
}
//同行处理
//同行且选择的父级为块级元素
else if (_start == _end && (_start.parentNode.tagName.toLowerCase() == "span" || _start.parentNode.tagName.toLowerCase() == "a")) {
var _parentspan = _start.parentNode; //获取起始标签的上级元素
var _tagname = _parentspan.tagName.toLowerCase() == "a" ? "a" : "span"; //判断创建的块级元素TagName
var _startsplitel = U.UF.E.splitText(_start, _startoffset); //将起始标签拆分成新的起始文本标签 返回剩余的标签
var _endsplitel = U.UF.E.splitText(_startsplitel, _endoffset - _startoffset); //在剩余标签中拆分成选中和结束两块文本标签
//如果第一个文本标签存在内容则创建新的span标签
if (_start.data) {
//创建新的span标签 该标签为起始span标签(选区前的span标签)
var _span = $$(_tagname, {
"style": { "cssText": U.UF.E.getRemainAttr(_parentspan) },
"innerHTML": _start.data
});
//如果为a标签则设置href属性
if (_tagname == "a") {
_span.href = _parentspan.href;
}
//替换起始文本标签为起始span标签
_parentspan.replaceChild(_span, _start);
}
//创建新的块级元素 该标签为选区的span标签
var _rangspan = $$(_tagname, {
"style": { "cssText": U.UF.E.getRemainAttr(_parentspan) },
"innerHTML": _startsplitel.data
});
//处理样式后进行设置块级元素中
U.selectEl(_rangspan).css(U.UF.E.setSpecialAttr(_rangspan, attr));
//如果为a标签则设置href属性
if (_tagname == "a") {
_rangspan.href = _parentspan.href;
}
//替换选区文本标签为选区span标签
_parentspan.replaceChild(_rangspan, _startsplitel);
//如果结束文本标签存在内容则创建新的span标签
if (_endsplitel.data) {
//创建新的span标签 该标签为结束span标签(选区后的span标签)
var _span1 = $$(_tagname, {
"style": { "cssText": U.UF.E.getRemainAttr(_parentspan) },
"innerHTML": _endsplitel.data
});
//如果为a标签则设置href属性
if (_tagname == "a") {
_span1.href = _parentspan.href;
}
//替换结束文本标签为结束span标签
_parentspan.replaceChild(_span1, _endsplitel);
}
//将替换的元素追加到临时元素中
for (i = 0; i < _parentspan.childNodes.length;) {
_frag.appendChild(_parentspan.childNodes[i]);
}
//替换原有元素为修改的元素
_parentspan.parentNode.replaceChild(_frag, _parentspan);
//设置选区
U.UF.E.setRange(_rangspan, _rangspan, 0, _startsplitel.data ? 1 : 0, range);
}
//起始元素和结束元素相等 且本身就为块级元素的处理
else if (_end == _start && _start.tagName && (_start.tagName.toLowerCase() == "span" || _start.tagName.toLowerCase() == "a")) {
//记录原有的样式属性
U.UF.E.getRemainAttr(_start);
//处理样式后设置到起始元素中
U.selectEl(_start).css(U.UF.E.setSpecialAttr(_start, attr));
}
//当行跨元素
else {
var _rangselect = range.extractContents(); //获取选区的所有元素
U.UF.E.setStyle(attr, _rangselect, true); //直接调用设置样式函数 true表示为第一层
range.insertNode(_rangselect); //将设置的元素插入到光标位置
}
//获取修改行的信息处理
U.UF.E.operationNotice(_record, editor);
};
/* 设置样式
*
* @param startline {element} 修改样式修改行
* @param endline {element} 修改样式结束行
*/
U.UF.E.getUpdateLine = function (startline, endline, edit) {
var _record = { updateLine: [] }; //记录
//循环找所有影响的行
while (startline) {
_record.updateLine.push(startline.id); //修改行记录
//向下寻找
if (startline != endline) {
startline = startline.nextElementSibling;
}
else {
startline = false;
}
}
//返回修改记录
return _record;
};
/* 设置样式
*
* @param attr {object} 给指定的光标设置样式
* @param el {object} 设置样式的元素
* @param istop {boolean} 是否为第一层标记
*/
U.UF.E.setStyle = function (attr, el, istop) {
var _nowattr, //记录当前属性 该变量的作用主要用于记录新的样式
_nowspan, //记录当前元素的span元素
_newspan, //记录新的span元素
_textstyle = attr["text-decoration"] || attr["textDecoration"],
_span = U.UF.E.getTagNameElement(el); //获取块级元素
var _spanText = _span && _span.innerHTML; //获取行级元素的innerHTML
//根据内容是否相等 判断是否选择整个span标签
if (_span && _spanText == el.data) {
_nowattr = U.UF.E.setSpecialAttr(_span, attr); //整理特殊样式
U.selectEl(_span).css(_nowattr); //设置样式
}
//如果设置样式的元素不为整个span标签
else {
var _rangselect = el.childNodes; //获取设置样式元素下的所有子级
//循环给每一个子级添加样式
for (var i = 0; i < _rangselect.length; i++) {
//是第一层且为第一个元素是处理样式
if (istop === true && !i) {
U.UF.E.setSpecialAttr(_rangselect[i], attr); //设置最后需要设置的值
//设置istop 设置后的功能为判断是否需要设置
istop = (attr["text-decoration"] || attr["textDecoration"] || "").indexOf(_textstyle) > -1 ? 1 : 0;
}
//如果存在文字装饰属性
if (attr["text-decoration"] || attr["textDecoration"]) {
//需要添加样式的处理
if (istop === 1) {
//如果为元素节点且存在文字装饰属性 并且不等于inherit和node
if (_rangselect[i].style && _rangselect[i].style["text-decoration"] && _rangselect[i].style["text-decoration"] != "inherit" && _rangselect[i].style["text-decoration"] != "none") {
//修改设置的属性为原有样式加当前样式
attr["text-decoration"] = _rangselect[i].style["text-decoration"].replace(_textstyle, "") + " " + _textstyle;
}
//否则则直接设置为当前样式
else {
attr["text-decoration"] = _textstyle;
}
}
//需要删除的处理
else if (istop === 0) {
//判断是否为元素节点
//如果是元素节点
if (_rangselect[i].style) {
//判断是否存在当前样式
//如果存在则去除当前样式
if (_rangselect[i].style["text-decoration"].indexOf(_textstyle) > -1) {
//去除当前样式
attr["text-decoration"] = _rangselect[i].style["text-decoration"].replace(_textstyle, "");
//去除完毕后如果为空则设置为inherit
if (attr["text-decoration"] == "") {
attr["text-decoration"] = "inherit";
}
}
//不存在时直接替换
else {
attr["text-decoration"] = _rangselect[i].style["text-decoration"];
}
}
//否则直接设置为inherit(继承父级属性)
else {
attr["text-decoration"] = "inherit";
}
}
}
//根据是否存在tagName(标签名) 判断是否为元素节点
//如果为元素节点则直接设置样式
if (_rangselect[i].tagName) {
U.selectEl(_rangselect[i]).css(attr); //设置样式
}
//否则则创建新的span标签 并替换原有是元素
else if (_rangselect[i].nodeValue) {
//创建新的span标签
_newspan = $$("span", {
"innerHTML": _rangselect[i].nodeValue,
"style": attr
});
//替换原有是元素
_rangselect[i].parentNode.replaceChild(_newspan, _rangselect[i]);
}
}
}
};
/* 特殊样式处理
*
* @param element {element} 被继承样式的元素
* @param attr {object} 当前的样式属性
*/
U.UF.E.setSpecialAttr = function (element, attr) {
var _key, //for in 循环的key值
_newvalue, //新的值
_value; //当前值
if (element.style) {
//循环没个样式
for (_key in attr) {
if (attr[_key] == "") {
attr[_key] = "";
}
else {
//判断是否为文字装饰样式属性
if (_key == "text-decoration" || _key == "textDecoration") {
//获取当前元素该样式的值
_value = element.style[_key];
//获取的样式有值且不为继承属性时
if (_value && _value != "inherit" && _value != 'none') {
//删除样式中的属性
_newvalue = _value.replace(attr[_key], "");
//如果替换后为空则设置为继承
if (_newvalue == "") {
attr[_key] = "inherit";
}
//否则如果替换后的值相等则将值设置进去
else if (_newvalue == _value) {
attr[_key] = attr[_key] + " " + _value;
}
//如果不等于则设置为新的值
else {
attr[_key] = _newvalue;
}
}
}
//否则如果设置的样式等于原本的样式 则设置为继承属性
else if (attr[_key] == element.style[_key] && "font-weight|fontWeight|font-style|fontStyle|".indexOf(_key) > -1) {
attr[_key] = "inherit";
}
}
}
}
//返回处理好后的属性
return attr;
};
/* 把一个text标签进行拆分
*
* @param node {element} 元素节点
* @param offset {number} 拆分的位置
*/
U.UF.E.splitText = function (node, offset) {
//如果拆分文字的位置等于总的长度,那么就在最后面添加空文本。
if (offset == node.nodeValue.length) {
var next = document.createTextNode('');
U.selectEl(node.parentNode).append(next, null, node);
return next;
}
var retval = node.splitText(offset);
return retval;
};
/* 获取到行元素
*
* @param el {element} 选取元素
*/
U.UF.E.getLineElement = function (el) {
var _mel = el,
_tagname = el.tagName ? el.tagName.toLowerCase() : ""; //获取元素的标签名
//循环得到行元素
while (el && _tagname != "body" && (_tagname != "div" || !(el.id && el.id.length == "37"))) {
el = el.parentNode;
if (el) {
_tagname = el.tagName ? el.tagName.toLowerCase() : ""; //标签名
}
};
return (el && el.id) ? el : null;
};
/* 获取到块级元素
*
* @param {element} 选取元素
*/
U.UF.E.getTagNameElement = function (node, tagname) {
tagname = tagname || 'span';
while (node) {
if (node.nodeName.toLocaleLowerCase() === tagname) {
return node;
} else if (node.nodeName.toLocaleLowerCase() === 'div' && !node.inline) {
return null;
}
node = node.parentNode;
}
};
/* 设置行的样式,如居中,局左,局右,设置编号等等功能
*
* @param {object} range光标对象
* @param {object} 给指定的光标设置样式
*/
U.UF.E.setLineStyle = function (style, range) {
if ($('.U_UF_E_Picture_dragDot')[0]) {//清除图片拉伸的的虚拟框
U.selectEl('.U_UF_E_Picture_dragDot')[0].style.display = "none";
}
range = range || U.UF.E.getRangeAt(); //获取光标处理
var _rangeline,
_start = range.startContainer
_td = U.selectEl(_start).Parent({ "tagName": "TD" }); //起始选区
//判断居中的元素是不是td标签
if (_td && _td.tagName == "TD") {
_rangeline = [_td];
}
else {
_rangeline = U.UF.E.getRangeLineElement(range);
}
var i = 0; //设置循环变量
for (i = 0; i < _rangeline.length; i++) { //循环设置样式
U.selectEl(_rangeline[i]).css(style); //设置样式
}
U.UF.E.reSelectRange(range);
return range; //返回选区对象
};
/* 获取选区行元素
*
* @param range {object} range光标对象
* */
U.UF.E.getRangeLineElement = function (range) {
range = range || U.UF.E.getRangeAt(); //获取光标处理
var _start = range.startContainer, //起始选区
_end = range.endContainer, //结束选区
_stratline = U.UF.E.getLineElement(_start), //起始选行
_endline = U.UF.E.getLineElement(_end), //结束选行
_nextline = U.selectEl(_stratline).next()[0], //下一行
_rangeline = [_stratline]; //选中行记录
if (_stratline != _endline) { //如果起始行不等于结束行则证明选择多行
while (_nextline) { //循环记录选择的每一行
_rangeline.push(_nextline); //添加到选择行记录中
if (_nextline != _endline) { //如果依旧不等于结束行 则证明未获取完毕
_nextline = U.selectEl(_nextline).next()[0]; //修改下一行变量
} else { //直至等于为止
_nextline = false;
}
}
}
return _rangeline;
}
/* 设置字体方向
*
* @param direction {string} 方向 left center right
* */
U.UF.E.textAlign = function (direction) {
U.UF.E.setLineStyle({ 'text-align': direction });
};
/* 设置光标位置
*
* @param {element} 选区起始元素
* @param {element} 选区结束元素
* @param {number} 起始位置
* @param {number} 结束位置
* @param {number} 光标对象
*/
U.UF.E.setRange = function (startel, endel, start, end, range) {
range = range || U.UF.E.getRangeAt(); //获取光标处理
//html5处理光标选取的处理
if (window.getSelection) {
//判断光标没有聚焦到制定的元素上,就无法设置焦点,这里需要处理聚焦问题。
if (startel == endel && range.startContainer != startel) {
range.selectNodeContents(startel); //由于位置要还原制定span标签中
}
range.setStart(startel, start); //设置光标开始的位置
range.setEnd(endel, end); //设置光标结束的位置
}
//ie系列的处理,ie系列不支持win.getSelection,有自己独特的属性
else {
var _range1 = document.body.createTextRange(), //创建一个光标1
_range2 = document.body.createTextRange(); //创建一个光标2
_range1.moveToElementText(startel); //光标放在开始的地方
_range1.moveStart("character", startel); //给光标设置
_range2.moveToElementText(endel); //光标放在结束的地方
_range2.moveStart("character", end); //设置光标结束区域的位置
_range1.setEndPoint("EndToStart", _range2); //光标1和光标2接连在一起形成选取
_range1.select(); //选择
range = _range1;
}
return range;
}
/* 格式整理,只整理第一层和第二层
*
* @param el {element} 整理的内容元素
*/
U.UF.E.unifiedFormat = function (el) {
var _i, //循环
_float,
_tagname,
_removeTagName = ['head', 'meta', 'script', 'link', 'style', 'title'], //需要移除的的标签
_frag = $$("frag"), //创建临时记录内容标签
_div, //行
_child = el.childNodes; //获取子级,改子级全部为行
//清除多余的元素
U.UF.E.unifiedFormat.remove(el);
//循环处理每一行
for (_i = 0; _i < _child.length; _i++) {
_display = _child[_i].currentStyle ? _child[_i].currentStyle.display : ""; //是否为行标签的处理
_tagname = _child[_i].tagName ? _child[_i].tagName.toLowerCase() : ""; //标签名
_float = _child[_i].currentStyle ? _child[_i].currentStyle.float : ""; //是否为行标签的处理
//附件不进行过滤
if (_child[_i].className == "U_MD_O_attachment") {
U.selectEl(_child[_i]).appendTo(_frag);
continue;
}
//行元素的处理
if (!_div || (_display != "" && _display != "inline") && (_float != "left" || _float != "right")) {
//所有的行标签的处理
//创建行标签
_div = $$("div", { "id": "e" + Guid.newGuid(), "style": { "cssText": U.UF.E.getRemainAttr(_child[_i]) } }, _frag);
}
//调用非行元素处理函数 即不为第一层的处理
U.UF.E.unifiedFormat.next(_child[_i], true, _div);
if (!_div.childNodes.length && _frag.childNodes.length > 1) {
U.selectEl(_div).remove();
}
}
//返回处理后的临时元素
return _frag;
};
/* 格式整理,过滤标签
*
* @param el {element} 整理的内容元素
*/
U.UF.E.unifiedFormat.remove = function (el) {
var _i, //循环
_tagname, //标题名
_removeTagName = ['head', 'meta', 'script', 'link', 'style', 'title'], //需要移除的的标签
_child = el.childNodes; //获取子级,改子级全部为行
//循环处理每一行
for (_i = 0; _i < _child.length; _i++) {
_tagname = _child[_i].tagName ? _child[_i].tagName.toLowerCase() : ""; //标签名
//过去注释标签 nodeType为8 则为注释标签
if (_child[_i].nodeType === 8 || (_child[_i].nodeType == 3 && _child[_i].data.trim() == "")) {
_child[_i].remove();
_i--;
continue;
}
//删除过滤的标签
if (_removeTagName.indexOf(_tagname) >= 0) {
U.selectEl(_child[_i]).remove();
_i--;
continue;
}
}
}
/* 非第一行之后的所有内容处理
*
* @param el {element} 处理的元素
* @param top {boolean} 是否为第二层标记 如果为第二层则所有标签直接修改为span标签 否则需要进行拆分
* @return 处理后的结果集
* */
U.UF.E.unifiedFormat.next = function (el, top, fragel) {
var _i, _j, //循环变量
_float,
_display, //记录元素真实的display属性 用于判断是否为行级元素
_tagname, //记录元素的tagName
_nowspan, //记录当前span
_tdchild, //用于子级
_fraga = $$("frag"),
_frag = fragel, //$$("frag"), //用于记录整理后的内容的临时标签
_span, //用于记录块级整理后的内容
_childcsstext, //用于记录获取到的自己的样式
_child = el.childNodes, //获取处理元素子级
_tagname = el.tagName ? el.tagName.toLowerCase() : "",
_cssText = (top.style ? top.style.cssText : "") + ";" + fragel.style.cssText + (_tagname == "img" ? "" : U.UF.E.getRemainAttr(el)); //获取处理元素的样式 用户继承当前样式使用
//清除多余的元素
U.UF.E.unifiedFormat.remove(el);
//如果存在子级的处理
if (_child.length) {
//循环处理每一个子级
for (_i = 0; _i < _child.length; _i++) {
_span = null; //循环重新赋值
//整理当前元素需继承的样式 父级样式 + 当前元素原有样式
_childcsstext = _cssText + ";" + (_child[_i].tagName == "IMG" ? "" : U.UF.E.getRemainAttr(_child[_i]));
_display = _child[_i].currentStyle ? _child[_i].currentStyle.display : ""; //是否为行标签的处理
_float = _child[_i].currentStyle ? _child[_i].currentStyle.float : ""; //是否为行标签的处理
//特殊标签添加样式
//加粗
if (_tagname == "b") {
_childcsstext += ";font-weight: bold;";
}
//斜体
else if (_tagname == "i") {
_childcsstext += ";font-style: italic;";
}
//下划线
else if (_tagname == "u") {
_childcsstext += ";text-decoration: underline;";
}
//删除线
else if (_tagname == "s") {
_childcsstext += ";text-decoration: line-through;";
}
//如果是附件的处理
if (el.className == "U_MD_O_attachment_wrapper") {
}
//如果当前标签为a标签或者top为字符串(当top为字符串时表明存在href属性需要替换为a标签)
else if (_tagname == "a" || (U.UF.C.isElement(top) && top.tagName == "A")) {
//重新设置top值
// top = U.UF.C.isString(top) ? top : el.href;
//设置name属性 用于传递使用
_child[_i].name = _child[_i].name || top.name || el.name || "";
//设置href属性 用于传递使用
_child[_i].href = _child[_i].href || top.href || el.href;
//创建a标签 并设置属性
_span = $$("a", {
"name": _child[_i].name,
"href": _child[_i].href || "javascript:void(0)",
"style": { "cssText": _childcsstext }
}, _fraga);
}
//style样式标签处理
else if (_tagname == "style") {
el = U.selectEl(el).clone(true); //克隆style标签
el.appendTo(_frag); //天机到临时记录标签中
//创建新的行
arguments[2] = _frag = fragel = $$("div", {
"id": "e" + Guid.newGuid(),
"style": { "cssText": _childcsstext }
}, fragel.parentNode);
break; //终止整个循环
}
//table表格标签处理 表格固定为行标签
else if (_tagname == "table") {
if (_frag.innerHTML) {
//创建新的行标签
_span = $$("div", {
"id": "e" + Guid.newGuid(),
"style": { "cssText": _childcsstext }
}, fragel.parentNode);
}
else {
_span = _frag;
}
//克隆当前表格元素
el = U.selectEl(el).clone(true);
//将表格添加到行中
el.appendTo(_span);
//获取所有td节点
_tdchild = U.selectEl("td", el[0]);
//循环保存td节点的内容 过滤表格内的样式
for (_j = 0; _j < _tdchild.length; _j++) {
_tdchild[_j].innerHTML = _tdchild[_j].innerText;
}
//创建新的行
arguments[2] = _frag = fragel = $$("div", {
"id": "e" + Guid.newGuid(),
"style": { "cssText": _childcsstext }
}, fragel.parentNode);
break; //终止整个循环
}
//行元素的处理
else if ((_display != "" && _display != "inline") && (_float != "left" || _float != "right") && _child[_i].innerHTML.trim() != "") {
if (_frag.innerHTML) {
//创建新的行
arguments[2] = _frag = fragel = $$("div", {
"id": "e" + Guid.newGuid(),
"style": { "cssText": _childcsstext }
}, fragel.parentNode);
}
else {
fragel.style.cssText += _childcsstext;
}
}
//否则则为块级元素
else {
_span = $$("span", { "style": { "cssText": _childcsstext } }, _fraga);
}
//进入判断是否依然存在子级 直到处理所有元素为止
var _nowspan = U.UF.E.unifiedFormat.next(_child[_i], _span || top, fragel);
//如果span元素的处理,说明下面只有文本元素的处理
if (_span) {
if (_nowspan.children.length) {
//替换记录标签中的块级标签元素
_fraga.replaceChild(_nowspan, _span);
_frag.appendChild(_fraga);
}
//如果有下级元素的处理
else if (_nowspan.childNodes.length) {
_span.appendChild(_nowspan);
_frag.appendChild(_fraga);
}
else {
U.selectEl(_span).remove();
}
}
else if (_nowspan) {
//替换记录标签中的块级标签元素
_fraga.appendChild(_nowspan);
_frag.appendChild(_fraga);
}
}
}
//如果不存在子级的处理
else {
//是否为第二层标记
if (top == true) {
if (_tagname == "img") {
var _img = U.selectEl(el).clone(true)[0];
_img.style.maxWidth = "100%";
_img.onerror = function () {
this.src = "/img/editorError.png";
this.width = 150;
this.height = 112;
}
_span = $$("span", {
"style": { "cssText": top.style.cssText }, //继承处理元素的样式
//判断是否为a标签如果是则将a标签直接记录 不是则获取内容 !!!!!!!!!注释有问题
"innerHTML": el.innerHTML != null ? el.innerHTML : el.data
});
_span.appendChild(_img);
_frag.appendChild(_span);
}
else {
//如果是则直接创建span块级标签,并添加到记录标签中
$$("span", {
"style": { "cssText": _cssText }, //继承处理元素的样式
//判断是否为a标签如果是则将a标签直接记录 不是则获取内容
"innerHTML": el.innerHTML != null ? el.innerHTML : el.data
}, _frag);
}
}
//如果不为第二层标记
else {
//且存在内容则直接创建文本节点,并添加到记录标签中
if (el.data) {
_fraga.appendChild(document.createTextNode(el.data));
}
//否则则直接克隆该元素,并添加到记录标签中 不做处理 该情况出现在img标签
else if (_tagname == "img") {
var _img = U.selectEl(el).clone(true)[0];
_img.style.maxWidth = "100%";
_img.onerror = function () {
this.src = "/img/editorError.png";
this.width = 150;
this.height = 112;
}
_span = $$("span", {
"style": { "cssText": top.style.cssText }, //继承处理元素的样式
//判断是否为a标签如果是则将a标签直接记录 不是则获取内容
"innerHTML": el.innerHTML != null ? el.innerHTML : el.data
});
_span.appendChild(_img);
_fraga.appendChild(_span);
}
}
}
//返回处理后的元素集合
return _fraga;
};
/* 获取指定的css元素 暂无使用
*
* @param ele {element} 被获取的元素
* */
U.UF.E.getRemainAttr = function (ele) {
//如果存在不存在样式 则返回空
if (!ele || !ele.style) {
return '';
}
//需要删除的属性
var _removeattr = ['position', 'width', 'height', 'background-image', 'border', 'min-height', 'float', 'min-width', 'display', 'padding', 'margin']; //
var _i; //循环变量定义
//循环将需要删除的属性的值设置为空
for (_i = 0; _i < _removeattr.length; _i++) {
//设置为空
ele.style[_removeattr[_i]] = "";
}
//返回设置后的样式
return ele.style.cssText;
};
/* 清除格式
*
* @param range {object} range光标对象
* */
U.UF.E.clearStyle = function (range) {
range = range || U.UF.E.getRangeAt(); //获取光标
var _start = range.startContainer, //选区起始元素
_end = range.endContainer, //选区结束元素
_startline = U.UF.E.getLineElement(_start), //获取选区起始行元素
_endline = U.UF.E.getLineElement(_end); //获取选区结束行元素
//同行相同的样式
if (_startline == _endline && range.toString() == _startline.innerText) {
for (var i = 0; i < _startline.childNodes.length; i++) {
if (_startline.childNodes[i].nodeName !== "#text") {
_startline.childNodes[i].style.cssText = "font-family: 微软雅黑; font-weight: normal; font-size: 10.5pt; line-height: 2;";
}
}
} else {
U.UF.E.setRangeStyle({ "cssText": "" }, range); //设置清空样式
}
U.UF.E.reSelectRange(range);
};
/* 添加超链接
*
* @param el {object} a标签对象
* @param range {object} range光标对象
* */
U.UF.E.addHref = function (el, range) {
U.selectEl("#U_UF_E_herfAlert").remove();
range = range || U.UF.E.getRangeAt(); //获取光标
var _start = range.startContainer, //获取选区起始元素
_end = range.endContainer, //获取选区结束元素
_selectel = range.cloneContents(), //获取选区的所有元素
_startline = U.UF.E.getLineElement(_start), //获取选区起始行元素
_endline = U.UF.E.getLineElement(_end); //获取选区结束行元素
el = el || U.UF.E.getTagNameElement(range.startContainer, "a");
//判断是否跨行选择
if (_startline !== _endline || U.selectEl('img', _selectel)[0]) {
//如果是则提示无法添加A标签
U.UF.UI.alertClick('选择范围横跨多个段落或存在图片,因此无法编辑');
} else {
var _box = $$('div'); //创建Confirm最大层div
if (el) {//判断是否有el
_text = el.innerHTML; //获取文本
_href = el.href; //获取超链接
var _textinput = $$('div', { innerHTML: '
文本 ', "style": { "line-height": "25px", "margin": "40px 41px 17px" } }, _box); //创建文本区域
var _hrefinput = $$('div', { innerHTML: '
链接 ', "style": { "margin": "0px 41px 27px", "line-height": "25px" } }, _box); //创建链接区域
U.UF.UI.confirm(_box, U.UF.C.closure(U.UF.E.addHref.confirm, [range, _hrefinput, _textinput, _text, el])); //创建Confirm
} else {
//否则执行添加A标签操作
_a = U.selectEl('a', _selectel)[0], //获取选区中的第一个a标签
_href = _a ? _a.href : '', //如果存在则已第一个a标签做为href
_text = range.toString(); //获取选区的文字
var _textinput = $$('div', { innerHTML: '
文本 ', "style": { "line-height": "25px", "margin": "40px 41px 17px" } }, _box); //创建文本区域
var _hrefinput = $$('div', { innerHTML: '
链接 ', "style": { "margin": "0px 41px 27px", "line-height": "25px" } }, _box); //创建链接区域
U.UF.UI.confirm(_box, U.UF.C.closure(U.UF.E.addHref.confirm, [range, _hrefinput, _textinput, _text])); //创建Confirm
}
}
};
/**
* Excel确定添加A标签
* @param _cellList 为选中的单元集合
* @param hrefinput {element} 链接区域元素
* @param textinput {element} 文本区域元素
* @param text {string} 选区文本记录
*/
U.UF.E.addHref.excelConfirm = function (_cellList, hrefinput, textinput, text) {
href = U.selectEl('input', hrefinput)[0].value; //获取输入的href
if (U.UF.S.Url.test(href)) { //判断链接是否合理
var _newtext = U.selectEl('input', textinput)[0].value; //获取当前文本
//被修改则直接删除选区 创建a标签直接添加
if (_cellList[0]) {
$$('a', { href: href, innerHTML: _newtext, target: "_blank" }, _cellList[0]); //创建A标签
_cellList[0].removeChild(_cellList[0].children[0]); //删除原来的文本,由创建的A标签代替
} else {
$$('a', { href: href, innerHTML: _newtext, target: "_blank" }, _cellList[0]); //创建A标签
}
}
else {
//提示链接存在有误
U.alert('输入的链接有误,无法添加');
}
};
/**
* 确定添加A标签
* @param range {object} range光标对象
* @param hrefinput {element} 链接区域元素
* @param textinput {element} 文本区域元素
* @param text {string} 选区文本记录
* @param el {object} a标签对象
*/
U.UF.E.addHref.confirm = function (range, hrefinput, textinput, text, el) {
href = U.selectEl('input', hrefinput)[0].value; //获取输入的href
if (new RegExp(/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/).test(href)) { //判断链接是否合理
var _newtext = U.selectEl('input', textinput)[0].value; //获取当前文本
var _start = range.startContainer, //获取选区起始元素
_end = range.endContainer, //获取选区起始元素
_startspan = U.UF.E.getTagNameElement(_start, 'span'),
_endspan = U.UF.E.getTagNameElement(_end, 'span');
if (el) {//判断是否有el参数(修改)
el.innerHTML = _newtext; //替换文本
el.href = href; //替换超链接
} else {
var _frag = $$('frag');
if (_newtext !== text) { //判断文本是否被修改
//被修改则直接删除选区 创建a标签直接添加
_frag = $$('a', { href: href, innerHTML: _newtext, target: "_blank" }); //创建A标签
} else {
var _selectel = range.extractContents(), //获取选区的所有元素
_rangselect = _selectel.childNodes; //获取选区的子级
var _text = _rangselect.innerHTML || _rangselect.data;
if (_newtext.trim() == "") {
$$('a', { href: href, innerHTML: href, style: { cssText: _startspan.style.cssText }, target: "_blank" }, _frag); //创建A标签
} else {
var i, _csstext;
//循环处理每一个元素
for (i = 0; i < _rangselect.length; i++) {
if (_rangselect[i].nodeType == 3) {
_csstext = i == _rangselect.length ? U.UF.E.getTagNameElement(_startspan, 'span').style.cssText : U.UF.E.getTagNameElement(_end, 'span').style.cssText;
$$("a", { href: href, innerHTML: _rangselect[i].data, style: { cssText: _csstext }, target: "_blank" }, _frag);
} else {
$$("a", { href: href, innerHTML: _rangselect[i].innerHTML, style: { cssText: _rangselect[i].style.cssText }, target: "_blank" }, _frag);
}
}
}
}
_frag = U.UF.E.unifiedFormat(_frag); //进行格式整理
_frag.firstChild.firstChild.setAttribute("target", "_blank");
if (_startspan.innerHTML == "") {
U.selectEl(_startspan).remove();
}
if (_endspan.innerHTML == "") {
U.selectEl(_startspan).remove();
}
U.UF.E.insertContent(_frag, range, U.selectEl('#U_MD_O_H_wordEditor')[0]); //调用指定位置插入内容的函数
}
}
else {
//提示链接存在有误
U.alert('输入的链接有误,无法添加');
return false;
}
};
/* 超链接点击
*
*/
U.UF.E.addHref.click = function (e) {
if (document.getElementById('U_UF_E_herfAlert')) {//如果有弹框则删除
document.getElementById('U_UF_E_herfAlert').remove();
}
U.UF.EV.stopBubble(e);
var parent = U.selectEl("#U_MD_O_R_Parent")[0]; //获取编辑区
var _hyperlinkalert = $$('div', {
id: "U_UF_E_herfAlert",
style: {
"min-width": "250px", "max-width": "360px", height: "34px", background: "rgba(255,255,255,1)", border: "1px solid rgba(243,243,243,1)", "box-shadow": "0px 5px 5px 0px rgba(45,45,45,0.1)",
"border-radius": "2px", "line-height": "34px", "font-size": "12px", "font-family": "MicrosoftYaHei", "font-weight": "400", color: "rgba(48,126,209,1)", width: "fit-content",
width: "-webkit-fit-content", width: "-moz-fit-content", position: "absolute", zIndex: "999"
}
}, parent); //创建超链接弹框
var _link = $$('a', {
innerHTML: e.target.href,
style: {
"overflow": "hidden", "text-overflow": "ellipsis", "white-space": "nowrap", cursor: "pointer",
"max-width": "212px", "float": "left", "margin-left": "10px", "font-size": "14px"
}
}, _hyperlinkalert); //超链接按钮
var _rightButton = $$('div', { classname: "out_2", style: { "float": "right" } }, _hyperlinkalert);
var _unlink = $$('div', { innerHTML: "取消链接", style: { "float": "left", "margin-left": "20px", "margin-right": "10px", cursor: "pointer" } }, _rightButton); //取消链接按钮
var _modify = $$('div', { innerHTML: "修改", style: { "float": "left", "margin-left": "10px", "margin-right": "10px", cursor: "pointer" } }, _rightButton); //修改按钮
_link.onclick = function () {//链接的点击事件
U.UF.EV.stopBubble(e);
parent.blur();
window.open(e.target.href); //打开目标路径
}
_unlink.onclick = function () {//取消链接的点击事件
U.UF.EV.stopBubble(e);
e.target.parentElement.replaceChild($$('span', { innerText: e.target.innerText }), e.target);
_hyperlinkalert.remove(); //删除超链接弹框
parent.blur();
}
_modify.onclick = function () {//修改的点击事件
U.UF.EV.stopBubble(e);
U.UF.E.addHref(e.target); //修改弹框
parent.blur();
_hyperlinkalert.remove(); //删除超链接弹框
}
/*_hyperlinkalert.style.left = e.target.offsetLeft + "px";
_hyperlinkalert.style.top = e.target.offsetTop + 20 + "px"; //弹框的定位*/
//弹框的定位
console.log("超链接的位置", e.target.offsetLeft, e.target.offsetTop);
console.log("光标的位置", e.clientX, e.clientY);
console.log("滚动过的高度", U.selectEl('#U_MD_O_W_E_body')[0].offsetTop);
var EditorScrollTop = U.selectEl('#U_MD_O_R_Parent')[0].parentNode.scrollTop; //滚动高度
var EditorOffsetTop = U.selectEl('#U_MD_O_W_E_body')[0].offsetTop; //编辑器距窗口顶端的距离
_hyperlinkalert.style.left = e.clientX + "px";
_hyperlinkalert.style.top = e.clientY + EditorScrollTop - EditorOffsetTop + 12 + "px";
}
/* 在键盘输入的过程中处理
*
* @param editor {element} 编辑器的对象
*/
U.UF.E.key = function (editor) {
editor.editor.idarr = U.UF.E.key.getLineIdArr(editor); //初始化默认的行
//将定义的//将定义的方法做为对象的onkeydown方法
editor.onkeydown = function (e) {
if (!editor.editor.recordOpera.range) {
U.UF.E.recordRangeIndex(editor); //记录range处理
}
U.UF.E.key.keyDown(e, editor);
};
//失焦处理
editor.onblur = function (e) {
U.UF.E.key.blur(e, editor);
};
//将定义的方法做为对象的onkeyup方法
editor.onkeyup = function (e) {
U.UF.E.key.keyUp(e, editor);
};
//点击事件的处理
editor.onmouseup = function (e) {
U.UF.E.key.keyUp(e, editor, true);
};
editor.onclick = function (e) {
setTimeout(function () {
U.UF.E.key.click(e, editor);
}, 0);
};
//点击记录
editor.onmousedown = function (e) {
setTimeout(function () {
U.UF.E.recordRangeIndex(editor); //记录range处理
}, 0);
};
//粘贴处理
editor.onpaste = function (e) {
var _text = U.UF.E.onpaste(e, editor); //获取text的处理
//如果text有值则不粘贴图片
if (!_text) {
U.UF.E.pasteImage(e, editor);
}
};
editor.ondragenter = U.UF.E.pasteImage.ignoreDrag;
editor.ondragover = U.UF.E.pasteImage.ignoreDrag;
editor.ondrop = U.UF.E.pasteImage.drop;
// U.selectEl(editor).bind({ });
};
/* 定义click方法
*
* @param e {event} event对象
* @param editor {element} 编辑器对象
* */
U.UF.E.key.click = function (e, edit) {
var _nowel, _range = U.UF.E.getRangeAt(), //获取处理的光标
_startel = U.UF.E.getLineElement(_range.startContainer) //开始元素
if (_startel != (_nowel = U.UF.E.getLineElement(edit.editor.recordRange.startContainer))) {
edit.editor.recordHTML = _startel.outerHTML;
}
edit.editor.recordRange = _range;
U.selectEl('#U_UF_E_herfAlert').remove();
if (e.target.tagName == "A") { //如果点击标签为A标签
if (e.ctrlKey == true) { //Ctrl键是否按下
window.open(e.target.href); //打开超链接
} else {
U.UF.E.addHref.click(e);
}
}
else if (e.target.tagName == "IMG" && e.target.offsetParent.className != "U_MD_F_D") { //如果点击的元素为图片元素,且不是好友聊天状态中
edit.imgStretch.img = e.target; //记录当前图片到拉伸对象中
U.UF.E.picture.stretch.setPosition(edit.imgStretch, e); //定位显示拉伸区域
} else {//其余情况
edit.imgStretch.stretch.style.display = "none"; //影藏拉伸框
}
}
/* 定义blur方法
*
* @param e {event} event对象
* @param editor {element} 编辑器对象
* */
U.UF.E.key.blur = function (e, edit) {
var _range = U.UF.E.getRangeAt(); //获取处理的光标
if (_range) {
var _startel = U.UF.E.getLineElement(_range.startContainer); //开始元素
_oldstartel = U.UF.E.getLineElement(edit.editor.recordRange.startContainer); //获取上一步操作所在的行
if (_startel) {
edit.editor.recordRange = _range; //记录光标对象
edit.editor.recordHTML = _startel.outerHTML; //记录内容 以此判断内容是否发送变化
edit.editor.log && console.log({ updateLine: [_startel.id] }, "在哪行失焦的");
if (_oldstartel && _oldstartel.id != "U_MD_O_H_wordEditor" && _startel == _oldstartel && _oldstartel.outerHTML != edit.editor.recordHTML) {
U.UF.E.operationNotice({ updateLine: [_startel.id] }, edit);
clearTimeout(edit.editor.interval); //取消计时更新
}
}
}
}
/* 定义onkey方法
*
* @param e {event} event对象
* */
U.UF.E.key.keyDown = function (e, edit) {
var _range = U.UF.E.getRangeAt(); //获取处理的光标
if (!_range) { return; }
var _el,
_oldstartel,
_line,
_result,
_startel = U.UF.E.getLineElement(_range.startContainer), //开始元素
_endel = U.UF.E.getLineElement(_range.endContainer); //结束元素
var _code = e.keyCode || e.which || e.charCode; //键盘码
if (_startel && _endel) {
if (e.ctrlKey || e.metaKey) {
edit.editor.recordRange = _range; //记录光标对象
switch (_code) {
case 90: //撤销(后退)
U.UF.E.key.undo(e, edit);
return;
case 89: //重做(前进)
U.UF.E.key.redo(e, edit);
return;
}
}
//判断光标是否存在的处理
clearTimeout(edit.editor.interval); //继续编辑的话直接取消计时器
//可能一直按着删除键,那么第一行给删除就添加第一行
if (edit.childNodes.length == 0) {
_result = U.UF.E.key.addDelLine(edit, _range); //删除最后一行后添加删除元素
//判断选区中是否有内容,那么就会处理删除操作
edit.editor.idarr = U.UF.E.key.getLineIdArr(edit); //获取当前文档的id集合
//记录关闭记录
edit.editor.log && console.log(_result, "内容被情况默认添加行");
//记录最新的行
edit.editor.recordRange = _range; //记录光标对象
edit.editor.recordHTML = U.UF.E.getLineElement(_range.startContainer).outerHTML; //记录内容 以此判断内容是否发送变化
//添加新行的处理
U.UF.E.operationNotice(_result, edit);
return;
}
//如果是删除行的处理
if (_code == 9) {
_range.deleteContents(); //移除文字
var _frag = $$("frag");
var _fragel = $$('div', { innerHTML: " " });
_frag.appendChild(_fragel.childNodes[0]);
U.selectEl(_fragel).remove();
_range.insertNode(_frag); //插入需要写入的内容
U.UF.E.setRange(_range.endContainer, _range.endContainer, _range.endOffset, _range.endOffset, _range); //设置选区 重新聚焦
U.UF.EV.stopDefault(); //阻止浏览器默认行为
return;
}
//回车处理
if (_code === 13) {
if (!U.UF.E.getTagNameElement(_range.commonAncestorContainer, 'table')) {
_result = U.UF.E.key.addLine(_range); //调用方法,新建行
//判断选区中是否有内容,那么就会处理删除操作
edit.editor.idarr = U.UF.E.key.getLineIdArr(edit); //获取当前文档的id集合
U.UF.EV.stopDefault(); //阻止浏览器默认行为
//记录关闭记录
edit.editor.log && console.log(_result, "更新换行的行,添加新的行");
//记录最新的行
edit.editor.recordRange = _range; //记录光标对象
edit.editor.recordHTML = U.UF.E.getLineElement(_range.startContainer).outerHTML; //记录内容 以此判断内容是否发送变化
//添加新行的处理
U.UF.E.operationNotice(_result, edit);
}
}
else {
edit.editor.recordDownHTML = _startel.outerHTML; //记录内容 以此判断内容是否发送变化
if (_startel == _endel && edit.editor.recordRange.endOffset != edit.editor.recordRange.startOffset) {
setTimeout(U.UF.C.closure(function (startel, edit) {
if (edit.editor.recordHTML != startel.outerHTML) {
var _result = { updateLine: [_startel.id] };
U.UF.E.operationNotice(_result, edit);
edit.editor.log && console.log(_result, "存在选区的输入,即时更新");
edit.editor.recordHTML = startel.outerHTML;
edit.editor.recordRange = U.UF.E.getRangeAt();
}
}, [_startel, edit]), 0);
clearTimeout(edit.editor.interval); //取消计时更新
}
_line = U.UF.E.key.getLineIdArr(edit); //获取
_result = U.UF.E.diff(_line, edit.editor.idarr); //对比得到删除的值
edit.editor.idarr = _line; //删除信息
//换行后回调的处理
if (_result.deleteLine.length) {
U.UF.E.operationNotice(_result, edit);
edit.editor.log && console.log(_result, "未松开删除按钮时,删除了行");
if (_result.updateLine[0]) {
edit.editor.recordHTML = U.selectEl("#" + _result.updateLine[0])[0].outerHTML;
edit.editor.recordRange = _range;
}
}
//没有任何特殊处理等待一点五秒的处理
else {
//普通的编辑那边等待记录,1.5秒后告诉用户修改信息
edit.editor.interval = setTimeout(function () {
if (edit.editor.recordHTML != _startel.outerHTML) {
//回调处理
U.UF.E.operationNotice({ updateLine: [_startel.id] }, edit);
edit.editor.log && console.log({ updateLine: [_startel.id] }, "超时更新行");
//记录当前的行
edit.editor.recordRange = _range; //记录光标对象
edit.editor.recordHTML = _startel.outerHTML; //记录内容 以此判断内容是否发送变化
}
}, 1000);
}
}
}
};
/* 定义键盘离开事件
*
* @param e {event} event对象
* */
U.UF.E.key.keyUp = function (e, edit, click) {
var _range = U.UF.E.getRangeAt(); //获取处理的光标
var _code = e.keyCode || e.which || e.charCode; //键盘码
if (e.ctrlKey == false) {
U.selectEl(edit).removeClass('U_MD_O_ctrlPress');
}
if (_range) {
var _line,
_result,
_oldstartel,
_startel = U.UF.E.getLineElement(_range.startContainer), //开始元素
_endel = U.UF.E.getLineElement(_range.startContainer); //结束元素
//判断第一层是否被删除掉,如果不是
if (edit.childNodes.length == 0) {
_result = U.UF.E.key.addDelLine(edit, _range); //删除最后一行后添加删除元素
//判断选区中是否有内容,那么就会处理删除操作
edit.editor.idarr = U.UF.E.key.getLineIdArr(edit); //获取当前文档的id集合
//记录关闭记录
edit.editor.log && console.log(_result, "内容被情况默认添加行");
//记录最新的行
edit.editor.recordRange = _range; //记录光标对象
edit.editor.recordHTML = U.UF.E.getLineElement(_range.startContainer).outerHTML; //记录内容 以此判断内容是否发送变化
//添加新行的处理
U.UF.E.operationNotice(_result, edit);
return;
}
_oldstartel = U.UF.E.getLineElement(edit.editor.recordRange.startContainer); //记录之前开始的行
//开始位置切换了,那么就要把开始位置作为修改行
if (_oldstartel && (_oldstartel != edit && _oldstartel != _startel || (_startel == _oldstartel && _startel.outerHTML != edit.editor.recordDownHTML))) {
if (edit.editor.recordHTML != _oldstartel.outerHTML) {
var _result = { "updateLine": [_oldstartel.id] };
U.UF.E.operationNotice(_result, edit);
edit.editor.log && console.log(_result, "光标切换且内容发送变化时");
clearTimeout(edit.editor.interval); //取消计时更新
}
edit.editor.recordRange = _range;
edit.editor.recordHTML = _startel.outerHTML;
}
if (_code > 36 && _code < 41) {
U.UF.E.recordRangeIndex(edit); //记录range处理
}
_line = U.UF.E.key.getLineIdArr(edit); //获取
_result = U.UF.E.diff(_line, edit.editor.idarr);
edit.editor.idarr = _line;
//删除行的处理
if (_result.deleteLine.length) {
U.UF.E.operationNotice(_result, edit);
edit.editor.log && console.log(_result, "删除了行");
var _range = U.UF.E.getRangeAt();
edit.editor.recordRange = _range;
edit.editor.recordHTML = U.UF.E.getLineElement(_range.commonAncestorContainer).outerHTML;
clearTimeout(edit.editor.interval); //取消计时更新
}
U.UF.E.formatBrush(edit, false); //格式刷工具未启用状态 记录当前光标所在位置的文字样式
}
};
/* 把编辑器里面的内容转换为数组,数组的id为div的id。
*
* @param edit {element} 编辑器元素
* @return 数组
* */
U.UF.E.key.getLineIdArr = function (edit) {
var _i,
_arr = [];
//循环添加子元素
for (_i = 0; _i < edit.childNodes.length; _i++) {
//判断是否是行元素,只有行元素才记录
if (edit.childNodes[_i].tagName && edit.childNodes[_i].tagName.toLowerCase() === "div") {
//记录id和innerHTML
_arr.push({ "id": edit.childNodes[_i].id, "innerHTML": edit.childNodes[_i].outerHTML });
}
}
return _arr;
};
/* 比较编辑器列删除方法
*
* @param arr 进行比较的数组一
* @param arr 进行比较的数组二
*/
U.UF.E.diff = function (arr1, arr2) {
var temp = []; //临时数组1
var temparray = []; //临时数组2
var _i, _j; //循环变量
var _updateLine = [];
for (_i = 0; _i < arr1.length; _i++) {
temp[arr1[_i].id] = true; //把数组B的值当成临时数组1的键并赋值为真
}
for (_j = 0; _j < arr2.length; _j++) {
//同时把数组A的值当成临时数组1的键并判断是否为真,如果不为真说明没重复,就合并到一个新数组里,这样就可以得到一个全新并无重复的数组
if (!temp[arr2[_j].id]) {
if (_updateLine.length == 0) {
_updateLine.push(arr2[_j - 1].id);
}
temparray.push(arr2[_j].id);
}
}
return {
updateLine: _updateLine,
deleteLine: temparray
}; //返回差异值
}
/* 添加删除后的空行
*
* @param 编辑器元素
* @param range 可选
* @returns {*} 返回id
*/
U.UF.E.key.addDelLine = function (edit, range) {
var _range = range || U.UF.E.getRangeAt(), //获得光标的位置
_el = $$("div", { id: edit.editor.idarr[0] ? edit.editor.idarr[0].id : "e" + Guid.newGuid(), innerHTML: "
" }, edit); //重新创建第一行,值为原第一行的id
_range.selectNodeContents(_el); //将光标重选中添加的内容
_range.collapse(true); //向右折叠光标选区,设置结束点和开始点相同地方
return { addLine: [_el.id] };
}
/* 添加行
*
* @param range 可选
* @returns {*} 返回id
*/
U.UF.E.key.addLine = function (range) {
var _txtnode, //换行后的文本内容
_range = range || U.UF.E.getRangeAt(), //获得光标的位置
_startline = U.UF.E.getLineElement(_range.startContainer), //得到起始行的div
_el = $$('div', { id: "e" + Guid.newGuid(), style: { cssText: _startline.style.cssText } }), //需要添加的新元素
_result = {} //添加行后会影响变化的值
;
//删除已经选中的内容
if (_range.startOffset != _range.endOffset && _range.startContainer.innerHTML !== "
") {
_range.deleteContents();
}
_range.setEnd(_startline, _startline.childNodes.length); //设置光标结束点的位置
_txt = _range.extractContents(); //剪切文本处理
if ($("img", _txt)[0]) {
_txtnode = _txt;
}
//判断选取是否有内容,若有返回内容,反之添加一个br标签占位
else if (_txt.textContent.trim() === '') { //如果没有内容那么就添加一个br标签
_txtnode = $$('span', { style: { cssText: (_startline.lastChild && _startline.lastChild.style) ? _startline.lastChild.style.cssText : "" }, innerHTML: "
" });
}
//设置内容
else {
_txtnode = _txt;
}
//如果回车行的内容为"",且没有存在有效元素 那么就记录原有样式创建默认行
if (_startline.innerText == '' && !U.UF.E.validElement(_startline)) {
var _clone = _txtnode.nodeName == "SPAN" ? _txtnode : U.selectEl('span', _txtnode)[0]; //获取可克隆样式元素
var _content = _clone ? U.selectEl(_clone).clone()[0] : $$('span', { innerHTML: "
" }); //创建内容
_content.innerHTML = "
"; //设置默认内容
U.selectEl(_content).appendTo(_startline); //追加
}
_el.appendChild(_txtnode); //添加到创建的div里面
U.UF.E.insertAfter(_el, _startline); //添加到选中的div下面
_range.selectNodeContents(_el); //将光标重选中添加的内容
_range.collapse(true); //向右折叠光标选区,设置结束点和开始点相同地方
_result.addLine = [_el.id]; //添加新的行
_result.updateLine = [_startline.id]; //结束新的行
return _result; //返回添加的id
};
/* 判断某个元素内是否存在有效元素(存在内容、存在图片等),过滤无用元素(空span)
*
* @param el {element} 父级元素
* @returns {boole} 返回是否存在有效元素
*/
U.UF.E.validElement = function (el) {
var i, //定义循环变量
_children = el.children, //获取子级
_valid = false; //默认为没有有效元素
for (i = 0; i < _children.length; i++) { //循环处理
if (_children[i].nodeName == "BR") {
continue; //BR标签默认不做处理
}
else if (_children[i].nodeName == "IMG" || _children[i].innerText.length > 0 || ($('img', _children[i])[0] && _children[i].innerText.length == 0)) { //存在内容、存在图片则为有效元素
_valid = true;
}
else { //过滤无用标题
U.selectEl(_children[i]).remove();
i--;
}
}
return _valid; //返回结果
}
/* 在元素之后插入
*
* @param newEl {element} 插入的元素
* @param targetEl {element} 插入比对位置的元素
* */
U.UF.E.insertAfter = function (newEl, targetEl) {
//插入比对位置的元素的父级元素
var parentEl = targetEl.parentNode;
//如果当前元素的父级元素的最后一个元素为插入比对位置的元素
if (parentEl.lastChild === targetEl) {
//则使用appendChild直接添加到最后
parentEl.appendChild(newEl);
} else {
//否则则采用insertBefore 添加到插入比对位置的元素的上一个元素后
parentEl.insertBefore(newEl, targetEl.nextSibling);
}
//返回插入的元素
return newEl;
};
/* 复制格式
*
* 效果:把选区内的第一个或开始位置的字体样式复制,赋值到常量里
* */
U.UF.E.formatBrush = function (el, pattern) {
el = el || U.selectEl('#U_MD_O_H_wordEditor')[0];
if (U.UF.E.formatBrush.callBack && U.UF.E.formatBrush.pattern) {
U.UF.E.formatBrush.pattern = undefined;
U.selectEl(el).bind('mouseup', U.UF.E.formatBrush.callBack);
return;
}
var _style = pattern == false ? el.editor.recordRangeStyle : el.editor.brushStyle;
var range = U.UF.E.getRangeAt();
//获取选区
var _start = range.startContainer;
//选区开始位置
if (_start.nodeName == "DIV") {
//如果选区开始节点是div的话,代表添加过样式之类的
if (!range.cloneContents().children[0]) { //如果光标不能存在元素
_style = { // 情况格式刷数据
"font-family": "",
"font-size": "",
"font-weight": "",
"font-style": "",
"text-decoration": "",
"color": "",
"background-color": ""
};
pattern == false && (_style["text-align"] = "", _style["name"] = "");
return;
}
//获取选区内的第一个块状节点,的第一个文档节点
//_start = range.cloneContents().children[0].firstChild;
}
//循环常量brushstyle 刷子样式
var _value;
_start = _start.nodeType == 1 ? _start : _start.parentElement;
for (var name in _style) {
//把相应的样式名字,内容,赋值给相应的常量值
if (name == "font-size") {
_value = (parseFloat(_start.currentStyle[name]) * 72 / el.editor.dpi).toFixed(1) + "pt";
} else {
_value = _start.currentStyle[name];
}
_style[name] = _value;
}
if (pattern !== false) { //判断是否为默认记录样式处理
U.UF.E.formatBrush.pattern = pattern;
if (pattern !== true) {
U.selectEl(el).unbind("mouseup", U.UF.E.formatBrush.callBack); //是否单次取消
U.UF.E.formatBrush.callBack = function () { //设置鼠标起开处理
U.UF.E.fomatBrushNext(el); //设置样式
U.UF.E.formatBrush.pattern == undefined && U.selectEl(el).unbind("mouseup", U.UF.E.formatBrush.callBack); //是否单次取消
};
U.selectEl(el).bind('mouseup', U.UF.E.formatBrush.callBack);
}
}
else {
_style["text-align"] = U.UF.E.getLineElement(_start).currentStyle.textAlign;
_style["name"] = U.UF.E.getLineElement(_start).getAttribute('name');
U.UF.C.isFunction(el.editor.styleState) && el.editor.styleState(el.editor.recordRangeStyle);
}
};
/* 粘贴复制的样式
*
* 效果: 把常量复制到样式,粘贴到编辑器中
* */
U.UF.E.fomatBrushNext = function (el) {
U.UF.E.setRangeStyle({ "cssText": '' });
//在赋值相应的样式
U.UF.E.setRangeStyle(el.editor.brushStyle);
};
/* 附件功能
*
* @param input {element} input文件域元素
* @param editor {element} 编辑器元素
*/
U.UF.E.attachment = function (input, editor) {
if (input.files.length) { //判断是否存在文件
var _range = U.UF.E.getRangeAt(); //获取光标处理
U.UF.UP.inputUpload([input], 'http://disk.1473.cn/USUpfile.ashx?typename=UseStudioEditor&UserId=FA92AAC5-4134-449F-9659-0DC12F4F68E9', function (r) { //调用统一上传处理
var _file, _filetype, _input = r.context[0];
var _imgtype = /.*(jpg|png|gif|jpeg|JPG|PNG|GIF|JPEG|bmp|BMP)$/;
var _filearray = []; //记录上传图片的数组
if (Object.prototype.toString.call(r.value[0]) != "[object Array]") { //根据返回值类型判断是否多图上传
_filearray = [r.value]; //单图用数组则直接记录
} else {
_filearray = r.value; //多图则直接替换即可
}
var _el, _frag = $$('frag');
for (i = 0; i < _filearray.length; i++) { //循环评接拼接
_file = _input.files[i];
_filetype = _file.name.substring(_file.name.lastIndexOf('.') + 1, _file.name.length); //获取文件后缀名
if (_filetype.match(_imgtype)) {//图片类型处理
_el = $$("div", {}, _frag);;
$$('span', { innerHTML: '
' }, _el);
}
else { //其余文件类型处理
_el = U.UF.E.attachment.create(_file, _filearray[i][0], _filetype);
U.selectEl(_el).appendTo(_frag);
}
}
_frag = U.UF.E.unifiedFormat(_frag); //进行格式整理
U.UF.E.insertContent(_frag, _range, editor || U.selectEl('#U_MD_O_H_wordEditor')[0]); //调用指定位置插入内容的函数
}, [input]);
}
}
/* 创建附件
*
* @param input {element} input文件域元素
* @param editor {element} 编辑器元素
*/
U.UF.E.attachment.create = function (file, fileinfo, type) {
//, style: { "text-align": "center"}
var _attachment = $$("div", { className: "U_MD_O_attachment", id: "e" + Guid.newGuid(), contenteditable: "false" }),
_wrapper;
var _imgtype = /.*(jpg|png|gif|jpeg|bmp)$/;
//图片类型处理
if (type.match(_imgtype)) {
$$('span', { innerHTML: '
' }, _attachment);
} else {
var _videotype = /.*(mp4|avi|wmv|ogg|webm|mpg|mpeg)$/;
var _musictype = /.*(mp3|wav|mid|midi)$/;
$$("span", { innerHTML: "" }, _attachment);
_wrapper = $$("span", { contenteditable: "false" }, _attachment);
//音乐类型处理
if (type.match(_videotype)) {
$$('video', { src: "http://fs.1473.cn/" + fileinfo, controls: "controls", style: { "width": "530px", "height": "300px" } }, _wrapper);
}
//视频类型处理
else if (type.match(_musictype)) {
$$('audio', { src: "http://fs.1473.cn/" + fileinfo, controls: "controls" }, _wrapper);
}
//其余文件类型处理
else {
_wrapper.className = "U_MD_O_attachment_wrapper";
$$('span', { "className": "U_MD_O_attachment_wrapper_img", contenteditable: "false" }, _wrapper);
var _info = $$("span", { className: "U_MD_O_attachment_fileinfo", contenteditable: "false" }, _wrapper);
$$("span", { innerHTML: U.UF.E.attachment.fileNameSplice(file.name), contenteditable: "false" }, _info);
$$("span", { innerHTML: U.UF.C.computeFileSize(file.size), contenteditable: "false" }, _info);
$$("a", {
"href": "/Pages/Download.htm?id=" + fileinfo[2], //下载路径地址
fileid: fileinfo[2], //文件id
name: file.name, //文件名称
type: file.name.substring(file.name.lastIndexOf('.') + 1, file.name.length), //文件后缀名
target: "_blank",
innerHTML: "打开",
contenteditable: "false"
}, _wrapper);
}
$$("span", { innerHTML: "" }, _attachment);
}
return _attachment;
}
/* 获取附件名
*
* @param input {string} 文件名字
* @param editor {number} 最大长度
*/
U.UF.E.attachment.fileNameSplice = function (name, maxlength) {
maxlength = maxlength || 30;
var i, _index = 0, _gblen = 0, _start = "", _end = "";
for (i = 0; i < name.length; i++) {
if (name.charCodeAt(i) > 127 || name.charCodeAt(i) == 94) {
_gblen += 2;
} else {
_gblen++;
}
_gblen < maxlength / 2 - 2 && (_start += name[i]);
}
if (_gblen > maxlength) {
i = name.length;
while (_index < maxlength / 2 - 2) {
if (name.charCodeAt(i) > 127 || name.charCodeAt(i) == 94) {
_index += 2;
} else {
_index++;
}
_end = name[name.length - _index] + _end;
i--;
}
name = _start + "..." + _end;
}
return name;
}
/* 图片插入控件 效果:插入图片
*
* @param input {element} input文件域元素
* @param editor {element} 编辑器元素
*/
U.UF.E.picture = function (input, editor) {
if (input.files.length) { //判断是否存在文件
var _range = U.UF.E.getRangeAt(); //获取光标处理
U.UF.UP.inputUpload([input], 'http://disk.1473.cn/USUpfile.ashx?typename=UseStudioEditor&UserId=FA92AAC5-4134-449F-9659-0DC12F4F68E9', function (r) { //调用统一上传处理
var _input = r.context[0];
var _imgarray = []; //记录上传图片的数组
if (Object.prototype.toString.call(r.value[0]) != "[object Array]") { //根据返回值类型判断是否多图上传
_imgarray = [r.value]; //单图用数组则直接记录
} else {
_imgarray = r.value; //多图则直接替换即可
}
//调用上传图片控件
var _img = ''; //设置img元素字符串
for (i = 0; i < _imgarray.length; i++) { //循环评接拼接
// $$("span", { innerHTML: "" }, _attachment);
_img += '
'; //图片元素拼接
}
U.UF.E.textFormat(_img, editor || U.selectEl('#U_MD_O_H_wordEditor')[0]); //生成img元素
}, [input]);
}
}
/* word复制粘贴图片及拖拽图片函数
*
* @param e {event} 事件对象
* @param editor {element} 编辑器元素
*/
U.UF.E.pasteImage = function (e, editor) {
e.preventDefault(); //阻止默认事件
var files = e.clipboardData.files; //获取文件列表
if (files.length && e.clipboardData.types.indexOf('Files') > -1) {
var filebtn = $$('input', { type: "file" }) //新建文件域
filebtn.files = files; //获取文件列表
U.UF.E.picture(filebtn); //上传图片
filebtn.remove(); //删除文件域
}
else {
return true;
}
}
/* 阻止拖拽默认事件
*
* @param e {event} 事件对象
*/
U.UF.E.pasteImage.ignoreDrag = function (e) {
//因为我们在处理拖放,所以应该确保没有其他元素会取得这个事件
e.stopPropagation();
e.preventDefault();
}
/* 拖拽上传处理
*
* @param e {event} 事件对象
*/
U.UF.E.pasteImage.drop = function (e) {
//取消事件传播及默认行为
e.stopPropagation();
e.preventDefault();
//取得拖进来的文件
var data = e.dataTransfer;
var files = data.files;
//将其传给真正的处理文件的函数
var filebtn = $$('input', { type: "file" })
filebtn.files = files;
U.UF.E.picture(filebtn, this);
filebtn.remove();
}
/* 拉伸处理
*
* @param el {element} 编辑器元素
*/
U.UF.E.picture.stretch = function (el) {
var _breadth = 12;
if (!el.imgStretch) {
var _img = $$("div", {
style: { display: "none", border: "1px dashed #535353", position: "absolute", minWidth: "30px", minHeight: "30px" }
}, document.body);
var _csstext = "width:" + _breadth + "px; height:" + _breadth + "px;position:absolute;z-index:999;background:url('/EditorImage/yuan1.png') no-repeat";
var _deviant = -_breadth / 2;
//创建虚拟框
el.imgStretch = {
//拉伸区域
stretch: _img,
//左上的按钮
nw: $$("div", { name: "nw", style: { cssText: _csstext, top: _deviant + "px", left: _deviant + "px", cursor: "nw-resize" } }, _img),
//右上的按钮
ne: $$("div", { name: "ne", style: { cssText: _csstext, top: _deviant + "px", right: _deviant + "px", cursor: "ne-resize" } }, _img),
//左下的按钮
sw: $$("div", { name: "sw", style: { cssText: _csstext, bottom: _deviant + "px", left: _deviant + "px", cursor: "sw-resize" } }, _img),
//右下的按钮
se: $$("div", { name: "se", style: { cssText: _csstext, bottom: _deviant + "px", right: _deviant + "px", cursor: "se-resize" } }, _img),
//上的按钮
n: $$("div", { name: "n", style: { cssText: _csstext, top: _deviant + "px", left: "calc(50% - " + -_deviant + "px)", cursor: "n-resize" } }, _img),
//下的按钮
s: $$("div", { name: "s", style: { cssText: _csstext, bottom: _deviant + "px", left: "calc(50% - " + -_deviant + "px)", cursor: "s-resize" } }, _img),
//左的按钮
w: $$("div", { name: "w", style: { cssText: _csstext, left: _deviant + "px", top: "calc(50% - " + -_deviant + "px)", cursor: "w-resize" } }, _img),
//右的按钮
e: $$("div", { name: "e", style: { cssText: _csstext, right: _deviant + "px", top: "calc(50% - " + -_deviant + "px)", cursor: "e-resize" } }, _img),
//左边的拖动虚拟线
l: $$("div", { name: "l", style: { position: "absolute", cursor: "e-resize", left: "-1px", width: "3px", height: "100%" } }, _img),
//右边的拖动虚拟线
r: $$("div", { name: "r", style: { position: "absolute", cursor: "e-resize", right: "-1px", width: "3px", height: "100%" } }, _img),
//顶部的拖动虚拟线
t: $$("div", { name: "t", style: { position: "absolute", cursor: "n-resize", top: "-1px", width: "100%", height: "3px" } }, _img),
//底部的拖动虚拟线
b: $$("div", { name: "b", style: { position: "absolute", cursor: "n-resize", bottom: "-1px", width: "100%", height: "3px" } }, _img),
maxWidth: U.selectEl(el)[0].offsetWidth
};
}
//绑定拖拽事件
new U.UF.E.picture.stretch.bindEvent(el);
};
/* 拉伸事件绑定
*
* @param el {element} 编辑器元素
*/
U.UF.E.picture.stretch.bindEvent = function (el) {
this.el = el; //设置编辑器元素
this.init(); //初始化设置
}
/* 拖拽方法
*
*/
U.UF.E.picture.stretch.bindEvent.prototype = {
//初始化
init: function () {
for (key in this.el.imgStretch) { //绑定所有可拉伸区域事件
key !== "stretch" && key !== "maxWidth" && this.el.imgStretch[key].addEventListener('mousedown', this.mouseDown.bind(this)); //绑定事件
}
document.body.addEventListener('mousemove', this.mouseMove.bind(this)); //绑定事件
document.body.addEventListener('mouseup', this.mouseUp.bind(this)); //绑定事件
},
//鼠标按下事件
mouseDown: function (e) {
this.name = e.target.name; //记录元素标识
this.stratX = e.clientX; //起始位置X
this.stratY = e.clientY; //起始位置Y
this.down = true; //按下标识
},
//鼠标移动事件
mouseMove: function (e) {
if (this.down) { //如果鼠标按下
//计算移动的坐标距离
var _moveX = e.clientX - this.stratX;
var _moveY = this.stratY - e.clientY;
var _click = this.name; //获取点击名称
//判断是否可以拉伸
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
//清空移动的数据
if (_click.length == 2 || _click == "w" || _click == "e" || _click == "l" || _click == "r") {
//如果是右方的拖动就移动距离相反
(_click == "w" || _click == "sw" || _click == "nw" || _click == "l") && (_moveX = -_moveX);
//处理虚拟框的宽高,和圆圈位置
U.UF.E.picture.stretch.moveX(this.el, this.el.imgStretch, _moveX);
}
if (_click.length == 2 || _click == "n" || _click == "s" || _click == "t" || _click == "b") {
//如果是上方的拖动就移动距离相反
(_click == "n" || _click == "nw" || _click == "ne" || _click == "t") && (_moveY = -_moveY)
//处理虚拟框的宽高,和圆圈位置
U.UF.E.picture.stretch.moveY(this.el.imgStretch, _moveY);
}
//设置新的对比起始位置
this.stratX = e.clientX;
this.stratY = e.clientY;
}
},
//鼠标松开事件
mouseUp: function (e) {
if (this.down) { //如果鼠标已按下
var _imgstretch = this.el.imgStretch; //获取拉伸元素集合
_imgstretch.img.style.width = _imgstretch.stretch.offsetWidth + "px"; //赋值
_imgstretch.img.style.height = _imgstretch.stretch.offsetHeight + "px"; //赋值
U.UF.E.picture.stretch.setPosition(_imgstretch, e); //执行点击事件重新定位
this.down = false; //设置按下标识结束
}
}
}
/* 设置拉伸框位置
*
* @param obj {object} 拉伸对象
* @param event [event} 事件对象
*/
U.UF.E.picture.stretch.setPosition = function (obj, event) {
var _stretch = obj.stretch; //拉伸盒子元素
var _imgel = obj.img; //被拉伸图片
//显示虚拟框,设置虚拟框的位置,大小
_stretch.style.display = "block"; //显示拉伸元素
var _imgelattr = _imgel.getBoundingClientRect(); //获取位置大小属性
if (event.clientX == event.pageX && event.clientY == event.pageY) { //当页面没有滚动时
_stretch.style.left = _imgelattr.left + "px"; //设置值
_stretch.style.top = _imgelattr.top + U.selectEl('body')[0].scrollTop + "px"; //设置值
} else {
var _offset = U.UF.E.picture.parentOfferset(_imgel, { "offsetLeft": 0, "offsetTop": 0 }); //获取父亲层的边距
_stretch.style.left = _imgel.offsetLeft + _offset.offsetLeft + parseInt($(_imgel).css("padding-left")) + "px"; //设置值
_stretch.style.top = _imgel.offsetTop + _offset.offsetTop + parseInt($(_imgel).css("padding-top")) + "px"; //设置值
}
_stretch.style.width = _imgelattr.width - 2 + "px"; //设置宽度
_stretch.style.height = _imgelattr.height - 2 + "px"; //设置高度
var _objattr = _stretch.getBoundingClientRect(); //获取位置大小属性
var _breadth = obj.n.offsetWidth / 2; //计算远点大小偏移值
obj.n.style.left = _objattr.width / 2 - _breadth + "px"; //设置顶部中心原点居中
obj.w.style.top = _objattr.height / 2 - _breadth + "px"; //设置底部中心原点居中
obj.s.style.left = _objattr.width / 2 - _breadth + "px"; //设置左部中心原点居中
obj.e.style.top = _objattr.height / 2 - _breadth + "px"; //设置右部中心原点居中
}
/* 左右拖拽方法
*
* @param el [element} 编辑器对象
* @param obj {object} 拉伸对象
* @param moveX [int} 移动距离
*/
U.UF.E.picture.stretch.moveX = function (el, obj, moveX) {
var _stretch = obj.stretch; //拉伸盒子元素
if ((parseInt(_stretch.style.width) + moveX < obj.maxWidth && parseInt(_stretch.style.width) + moveX > 30)) { //判断拉伸后是否超出限制
var _align = el.editor ? el.editor.recordRangeStyle["text-align"] : ""; //获取对齐方式
switch (_align) { //判断对齐方式
case "end": //end 为 right
case "right": //居右处理
_stretch.style.left = _stretch.offsetLeft - moveX + 'px'; //设置left值
U.selectEl(_stretch)[0].style.width = parseInt(_stretch.style.width) + moveX + "px"; //设置宽度
break;
case "center": //居中处理
_stretch.style.width = parseInt(_stretch.style.width) + moveX + 'px'; //设置宽度
_stretch.style.left = parseFloat(_stretch.style.left) - moveX / 2 + 'px'; //设置偏左值
break;
default: //居左处理
_stretch.style.width = parseInt(_stretch.style.width) + moveX + "px"; //设置宽度
}
obj.n.style.left = obj.s.style.left = _stretch.offsetWidth / 2 - obj.s.offsetWidth / 2 + "px"; //设置顶部 底部原点居中
}
};
/* 上下拖拽方法
*
* @param obj {object} 拉伸对象
* @param moveX [int} 移动距离
*/
U.UF.E.picture.stretch.moveY = function (obj, moveY) {
var _stretch = obj.stretch; //拉伸盒子元素
//变化虚拟框的宽度
_stretch.style.height = _stretch.offsetHeight - 2 - moveY + "px";
//变化左、右按钮的位置
obj.w.style.top = obj.e.style.top = _stretch.offsetHeight / 2 - obj.w.offsetWidth / 2 + 'px';
};
/* 得到父亲层的边距
*
* @param obj {object} 拉伸对象
* @param moveX [int} 移动距离
* @return {object} 返回父亲层的边距
*/
U.UF.E.picture.parentOfferset = function (obj, json) {
var _offset = {};
//判断父亲层的左边距是否为空
if (obj.offsetParent.offsetLeft != 0) {
//如果有就赋值
_offset.offsetLeft = obj.offsetParent.offsetLeft;
} else {
//没有就赋值0
_offset.offsetLeft = 0;
}
//判断父亲层的上边距是否为空
if (obj.offsetParent.offsetTop != 0) {
//如果有就赋值
_offset.offsetTop = obj.offsetParent.offsetTop;
} else {
//没有就赋值0
_offset.offsetTop = 0;
}
json.offsetLeft = _offset.offsetLeft + json.offsetLeft;
json.offsetTop = _offset.offsetTop + json.offsetTop;
//如果 父亲层的左边距和上边距都为0 代表,没有边距了可以返回了
if (_offset.offsetTop == 0 && _offset.offsetLeft == 0) {
return json;
} else {
return U.UF.E.picture.parentOfferset(obj.offsetParent, json);
}
}
//#region 协同的处理
/*
* word 消息类
* 参数一 : id 行id
* 参数二 : type 操作类型
* 参数三 : content 行内容
* 参数四 : next 下一行
*/
U.UF.E.editInfo = function (id, content, next) {
var _data = {
id: id, //操作ID
content: content, //内容
nextId: next //下一行ID
};
return _data;
};
/*
* 协同的处理
* @param e {event} event对象
* @param e {element} 编辑器对象
*/
U.UF.E.operationNotice = function (operaRecord, editor) {
var _opera = {}; //记录操作记录
//是否有添加行的处理
if (operaRecord.addLine) {
_opera.addLine = U.UF.E.addLineMessage(operaRecord.addLine, editor); //得到操作行的协同记录
}
//是否有修改行的处理
if (operaRecord.updateLine) {
_opera.updateLine = U.UF.E.updateLineMessage(operaRecord.updateLine, editor); //得到修改行的协同记录
}
//是否有删除行的处理
if (operaRecord.deleteLine) {
_opera.deleteLine = U.UF.E.deleteLineMessage(operaRecord.deleteLine, editor); //得到删除行的协同记录
}
//记录前进后退
U.UF.E.setRecord(operaRecord, editor);
//协同回调
if (U.UF.C.isFunction(editor.editor.operaNotice)) {
editor.editor.operaNotice(_opera);
}
}
/*
* 添加行
* @param {array} 添加行的对象
* @param {element} 编辑器对象
*/
U.UF.E.addLineMessage = function (array, edit) {
var _i,
_nextlineid,
_el,
_editinfo,
_message = []
;
//循环添加行,获取数据
for (_i = 0; _i < array.length; _i++) {
_el = U.selectEl('#' + array[_i])[0]; //获取添加行的元素
_nextlineid = (_nextlineid = U.selectEl('#' + array[_i])[0].nextElementSibling) ? _nextlineid.id : null; //判断是否有下一行有返回id ,没有返回null
_editinfo = U.UF.E.editInfo(array[_i], _el.outerHTML, _nextlineid); //初始化word信息处理
_message.push(_editinfo); //添加数据
}
return _message;
};
/*
* 修改行内容
* @param {array} 添加行的对象
* @param {element} 编辑器对象
*/
U.UF.E.updateLineMessage = function (array, edit) {
var _i,
_el,
_editinfo,
_message = [];
for (_i = 0; _i < array.length; _i++) {
_el = U.selectEl('#' + array[_i])[0]; //获取修改行的信息
_editinfo = U.UF.E.editInfo(array[_i], _el.outerHTML, null); //初始化word信息处理
_message.push(_editinfo); //添加数据
}
return _message;
};
/*
* 删除行
* @param {array} 删除的行
* @param {element} 编辑器对象
*/
U.UF.E.deleteLineMessage = function (array, edit) {
var _i,
_editinfo,
_message = []
;
for (_i = 0; _i < array.length; _i++) {
_editinfo = U.UF.E.editInfo(array[_i], "", null); //初始化word信息处理
_message.push(_editinfo); //添加数据
}
return _message;
};
//#endregion
//#region 前进后退方案
/*
* 添加前进后退内容(当)
* @param {array} 添加行的对象
* @param {element} 编辑器对象
*/
U.UF.E.setRecord = function (opera, editor) {
if (editor.editor.isrecord && editor.editor.recordOpera && editor.editor.recordOpera.range) {
editor.editor.recordsEditor.splice(editor.editor.recordsEditorIndex, editor.editor.recordsEditor.length - editor.editor.recordsEditorIndex);
editor.editor.recordsEditorIndex = editor.editor.recordsEditor.length;
//插入记录
editor.editor.recordsEditor.push({
"opera": opera,
"recordLine": editor.editor.recordOpera
});
editor.editor.recordsEditorIndex++;
//重新记录
editor.editor.recordOpera = { "line": U.UF.E.key.getLineIdArr(editor) };
U.UF.E.recordRangeIndex(editor);
}
editor.editor.isrecord = true;
}
/*
* 记录光标位置和内容
* @param {array} 添加行的对象
* @param {element} 编辑器对象
*/
U.UF.E.recordRangeIndex = function (editor) {
//编辑器的光标处理
var _range = U.UF.E.getRangeAt(); //得到光标
if (_range) {
var _startel = U.UF.E.getLineElement(_range.startContainer), //开始行
_endel = U.UF.E.getLineElement(_range.endContainer) //结束行
;
if (_startel && _endel) {
//开始和结束行的处理
editor.editor.recordOpera.range = {
"startid": _startel.id,
"endid": _endel.id,
"endOffset": _range.endOffset, //
"startOffset": _range.startOffset,
"start": U.UF.E.getElementByAncestorsIndex(_startel, _range.startContainer),
"end": U.UF.E.getElementByAncestorsIndex(_endel, _range.endContainer)
};
}
}
}
/*
* 记录
* @param {Element} 祖先元素
* @param {Element} 子元素
*/
U.UF.E.getElementByAncestorsIndex = function (el, childel) {
var i, j, _child, _cindex;
//获取开始位置的处理
if (el !== childel) {
_child = el.childNodes;
for (i = 0; i < _child.length; i++) {
//聚焦到子元素下的处理
if (_child[i] == childel) {
_cindex = i;
break;
}
//聚焦到子子元素的处理
else if (U.UF.EL.isChild(_child[i], childel)) {
_child = _child[i].childNodes;
//循环子元素得到位置
for (j = 0; j < _child.length; j++) {
if (_child[j] == childel) {
_cindex = [i, j];
break;
}
}
}
}
}
return _cindex;
}
/* 定义撤销(后退)函数
*
* @param e {event} event对象
* @param editor {element} 编辑器对象
* */
U.UF.E.key.undo = function (e, editor) {
var i, j, k,
_info,
_operarecord = {},
_index = editor.editor.recordsEditorIndex - 1,
_record,
_line;
if (_index > -1 && editor.editor.recordsEditor.length >= _index) {
_record = editor.editor.recordsEditor[_index];
_line = _record.recordLine.line;
//如果存在记录
if (_record.recordLine) {
for (i in _record.opera) {
switch (i) {
//添加行的处理,如果是
case "addLine":
//如果是后退添加行,那么直接删除
for (j = 0; j < _record.opera[i].length; j++) {
U.UF.E.deleteEditorLine(_record.opera[i][j]);
}
break;
case "updateLine":
//如果是后退添加行,那么直接删除
for (j = 0; j < _record.opera[i].length; j++) {
U.UF.E.updateEditorLine({ "id": _record.opera[i][j], "content": U.UF.E.getLineContentById(_line, _record.opera[i][j]) });
}
break;
case "deleteLine":
//如果是后退添加行,那么直接删除
for (j = 0; j < _record.opera[i].length; j++) {
_info = U.UF.E.getLineInfoById(_line, _record.opera[i][j]); //获取行信息
U.UF.E.addEditorLine({ "nextId": _info.next ? _info.next.id : null, "content": _info.info.innerHTML }, editor); //删除后添加回信息
}
break;
}
}
U.UF.E.setRecordRange(_record.recordLine.range); //设置光标
//如果是最后的测回,那么添加一个可前进的记录
if (editor.editor.recordsEditor.length == _index + 1) {
U.UF.E.setRecord(_record.opera, editor); //重新记录
}
editor.editor.recordsEditorIndex--;
editor.editor.isrecord = false;
}
}
//取消浏览器默认事件
U.UF.EV.stopDefault();
}
/* 定义重做(前进)函数
*
* @param e {event} event对象
* @param editor {element} 编辑器对象
* */
U.UF.E.key.redo = function (e, editor) {
var i, j, k,
_info,
_operarecord = {},
_index = editor.editor.recordsEditorIndex,
_record,
_line;
if (_index > -1 && _index < editor.editor.recordsEditor.length) {
_record = editor.editor.recordsEditor[_index];
_line = _record.recordLine.line;
//如果存在记录
if (_record.recordLine) {
for (i in _record.opera) {
switch (i) {
//添加行的处理,如果是
case "addLine":
//如果是后退添加行,那么直接删除
for (j = 0; j < _record.opera[i].length; j++) {
_info = U.UF.E.getLineInfoById(_line, _record.opera[i][j]); //获取行信息
U.UF.E.addEditorLine({ "nextId": _info.next ? _info.next.id : null, "content": _info.info.innerHTML }, editor); //删除后添加回信息
}
break;
case "updateLine":
//如果是后退添加行,那么直接删除
for (j = 0; j < _record.opera[i].length; j++) {
U.UF.E.updateEditorLine({ "id": _record.opera[i][j], "content": U.UF.E.getLineContentById(_line, _record.opera[i][j]) });
}
break;
case "deleteLine":
//如果是后退添加行,那么直接删除
for (j = 0; j < _record.opera[i].length; j++) {
U.UF.E.deleteEditorLine(_record.opera[i][j]);
}
break;
}
}
U.UF.E.setRecordRange(_record.recordLine.range); //设置光标
editor.editor.isrecord = false;
editor.editor.recordsEditorIndex++;
}
}
//取消浏览器默认事件
U.UF.EV.stopDefault();
}
/* 光标聚焦
*
* @param e {object} 自定义光标对象
*/
U.UF.E.setRecordRange = function (range) {
var _startel,
_start,
_endel,
_end;
//光标开始位置和开始元素的处理
if (range.startid && U.selectEl("#" + range.startid)[0]) {
_start = range.startOffset; //开始位置
//开始元素的获取
if (range.start.length) { //如果是#text标签的处理
_startel = U.selectEl("#" + range.startid)[0].childNodes[range.start[0]].childNodes[range.start[1]];
}
else { //如果是span标签的处理
_startel = U.selectEl("#" + range.startid)[0].childNodes[range.start];
}
}
//光标结束位置的处理
if (range.endid && U.selectEl("#" + range.endid)[0]) {
_end = range.endOffset; //结束的位置
//结束元素的获取
if (range.start.length) { //如果是#text标签的处理
_endel = U.selectEl("#" + range.endid)[0].childNodes[range.end[0]].childNodes[range.end[1]];
}
else {//如果是span标签的处理
_endel = U.selectEl("#" + range.endid)[0].childNodes[range.end];
}
}
//选择光区聚焦
U.UF.E.setRange(_startel, _endel, _start, _end)
}
/* 设置记录内容
*
* @param e {event} event对象
* @param editor {element} 编辑器对象
*/
U.UF.E.getLineContentById = function (line, id) {
for (var i = 0; i < line.length; i++) {
if (line[i].id == id) {
return line[i].innerHTML;
}
}
return "";
}
/* 获取行信息
*
* @param e {array} 行数组
* @param editor {string} id
*/
U.UF.E.getLineInfoById = function (line, id) {
for (var i = 0; i < line.length; i++) {
if (line[i].id == id) {
return { "pre": line[i - 1], "next": line[i + 1], "info": line[i] }
}
}
return null;
}
/*
* 根据操作记录撤回或者前进修改信息
* @param {object} 操作的行
*/
U.UF.E.updateEditorLine = function (opera) {
//判断修改的元素是否存在
if ($('#' + opera.id)[0]) {
U.selectEl('#' + opera.id)[0].outerHTML = opera.content;
}
else {
console.log('updateError', opera.id);
}
};
/*
* 根据操作记录撤回或者前进删除信息
* @param {object} 操作的行
*/
U.UF.E.deleteEditorLine = function (opera) {
//删除行的处理
U.selectEl('#' + opera.id).remove();
};
/*
* 根据操作记录撤回或者前进添加信息
* @param {object} 操作的行
* @param {element} 编辑器元素
*/
U.UF.E.addEditorLine = function (opera, editor) {
editor = editor || U.selectEl('#U_MD_O_H_wordEditor')[0]; //
var _next,
_line = $$("div", {}, editor);
//判断有没有nextid,nextid是否存在
if (opera.nextId && (_next = U.selectEl('#' + opera.nextId))[0]) {
_next.Parent().insertBefore(_line, _next[0]); //有的话插入在nexid 元素前
}
U.selectEl(_line)[0].outerHTML = opera.content; //替换内容
}
//#endregion
;
///
//处理元素属性设置。HTML元素大小及定位
Namespace.register("U.UF.EL");
/*
** 作用:获取元素的定位位置
** @param {element} el 需要获取元素的定位位置的元素
** @return {array} arr 返回元素的位置的数组
*/
U.UF.EL.getElementPosition = function (el) {
var _key, //获取元素的class值
_arr = [0, 0]//获取需要返回的元素的定位位置的top和left值
while (el && (el = el.offsetParent)) {//循环是否有el这个元素 //如果position的值为static,则获取该元素的父级元素,继续执行获取position的值,进行判断是否元素有定位位置
_key = U.UF.EL.getStyle(el, "position"); //通过U.UF.EL.getStyle函数,获取元素的position的值
//判断元素的position的值是什么
if (_key != "static") {//如果position的值不为static,则执行下面内容
_arr[0] += el.offsetTop; //获取元素的定位位置的上距
_arr[1] += el.offsetLeft; //获取元素的定位位置的左距
}
}
return _arr; //如果已经获取了元素的定位位置的上距和左距,就返回一个拥有元素定位位置的数组
}
/**
*
*
* @param {element} el 元素
* @param {string} 获取长或者宽的属性
* @return {number} 返回元素宽度
*/
U.UF.EL.getElementRealWidth = function (el) {
var _offset; //存储元素拖动后的offset属性
//获取元素的当前宽度,并且转化为整型
_offset = parseInt(Math.min(el.offsetWidth, el.scrollWidth, el.clientWidth));
//判断是否获取到了宽度属性
if (_offset <= 0) {
_offset = parseInt(el.style.height); //获取元素的样式中的高度并且转化为整型
}
//返回元素宽度
return _offset;
}
/**
*
* 作用:获取元素的真实高度
* @param {element} 需要获取真实高度的元素
* @param {string} 获取长或者宽的属性
* @return {number} 返回元素高度
*/
U.UF.EL.getElementRealHeight = function (el) {
var _offset; //存储元素拖动后的offset属性
//获取元素的当前高度,并且转化为整型
_offset = parseInt(Math.min(el.offsetHeight, el.scrollHeight, el.clientHeight));
//判断是否获取到了高度属性
if (_offset <= 0) {
_offset = parseInt(el.style.height); //获取元素的样式中的高度并且转化为整型
}
//返回元素高度
return _offset;
}
/**
* 获取元素的位置大小
*
* @param {element} el 元素
* @return {object} 返回元素的位置 函数内有详细的注释
*/
U.UF.EL.getElementInfo = function (el) {
var _elgetbc = el.getBoundingClientRect(), //获取
_elp = U.UF.EL.offsetParent(el);
// ancestorscrollbartop
// ancestorscrollbarleft
// scrollheight
// scrollwidth
// clientheight
// clientwidth
// clienttop
// clientleft
// offsetheight
// offsetwidth
// offsetleft
// offsettop
// boundingheight
// boundingwidth
// boundingtop
// boundingleft
// boundingbottom
// boundingright
return {
ancestorscrollbartop: (document.documentElement.scrollTop) + _elp.scrollTop, //滚动条top位置
ancestorscrollbarleft: (document.documentElement.scrollLeft) + _elp.scrollLeft, //滚动条left位置
SH: el.scrollHeight, //包含滚动掉的高度
SW: el.scrollWidth, //包含滚动条的长度
SL: el.scrollLeft, //滚动条向左的位置
ST: el.scrollTop, //滚动条向右的位置
CH: el.clientHeight, //页面不包含 border padding宽度
CW: el.clientWidth, //页面不包含 border padding长度
CT: el.clientTop, //页面margin + top的高度
CL: el.clientLeft, //页面margin + left的长度
OH: el.offsetHeight, ///页面包含 border padding宽度
OW: el.offsetWidth, //页面包含 border padding长度
OL: el.offsetLeft, //页面left的长度
OT: el.offsetTop, //页面top的高度
BCRH: _elgetbc.bottom - _elgetbc.top, //元素的显示高度
BCRW: _elgetbc.right - _elgetbc.left, //元素的显示长度
BCRT: _elgetbc.top, //元素的显示top
BCRL: _elgetbc.left, //元素的显示left
BCRB: _elgetbc.bottom, //元素的显示bottom
BCRR: _elgetbc.right //元素的显示right
}
}
/*
** 作用:获取元素offsetParent
** @param {element} el1 获取需要开始寻找的元素
** @param {boolean} b 是否要从上级开始找起,true为真,false为假
** @param {string} str 规定的position值
** return {element} el2 返回offsetParent
*/
U.UF.EL.offsetParent = function (el1, b, str) {
var _str, //存放获取所需要的样式
_el1 = document.body; //获取body部分的整体元素
//while循环语句,之所以不用for循环,是因为for循环需要知道循环的次数,而while则用语不知道循环的次数,只要达到条件,就跳出循环
while (el1 && el1 != _el1) {//循环条件为:是否拥有开始寻找的元素并且开始寻找的元素不超出body部分
_str = U.UF.EL.getStyle(el1, "position"); //通过U.UF.EL.getStyle()这个函数获取元素所需要的样式
//判断语句,判断获取的元素样式是否存在,并且样式的key值不为"static",或者是获取的元素样式是规定的position值
if ((!str && _str != "static") || (_str == str)) {//如果满足两个条件之一
break; //则跳出循环
}
el1 = el1.offsetParent; //如果不满足,则获取开始传值的元素的父级元素,继续向上一级寻找是否有需要的规定的position值
}
return el1; //跳出循环后,则返回offsetParent值
}
/*
** 作用:根据ID获取指定的祖先元素
** @param {element} el 获取当前的元素
** @param {string} str 祖先元素的id
** @return {element} 返回祖先元素
*/
U.UF.EL.getAncestor = function (el, str) {
//循环条件,是否有当前元素,并且,当前元素的id不等于祖先元素的id
while (el && !(el == str || el.id == str)) {//符合条件
el = el.parentNode; //获取当前元素的父级元素,并且把当前元素的父级元素赋值为当前元素,并继续循环
}
return el; //如果循环出拥有id的祖先元素,则返回祖先元素
}
/*
** 作用:获取不为文字子节点的元素子节点
** @param {element} el 当前的元素
** @param {string} str 获取父亲元素的id
** @return {array} 返回获取所有子节点的数组
*/
U.UF.EL.getChildrenNoText = function (el, str) {
var i, //用于循环,获取所有子节点
_arr = []; //用于存放获取到的子节点,并且返回
for (i = 0; i < el.length; i++) {
//nodeType属性返回以数字值返回指定集结点的节点类型,如果节点是元素节点,则nodeType属性将返回1
//判断是否拥有父级元素的id,或者是检索需要的id是否存在
if (el[i].nodeType == 1 && (!str || str.indexOf(el[i].tagName.toLowerCase()) == -1)) {//如果满足两个条件,则证明是元素子节点
_arr.push(el[i]); //给获取子节点的数组的末尾添加获取到的元素子节点
}
}
return _arr; //返回数组和数组新的长度
}
/*
** 作用:获取当前元素上级的可编辑的元素
** @param {element} el 当前元素
*/
U.UF.EL.getAncestorEditElement = function (el) {
var _el1 = document.body; //获取body部分的元素,不包括body以外的元素
while (el && _el1 != el) {//while循环语句,条件为拥有当前元素,并且当前元素不超出body部分
if (el.tagName) {//判断当前元素是否有标签名
//判断是检索中是否当前元素是否拥有可编辑的元素,大于-1则证明有可编辑的元素
//或者判断元素中是否有contentEditable = true,如果有,证明也是可编辑的div元素
if ("textarea,input".indexOf(el.tagName.toLocaleLowerCase()) > -1 || el.contentEditable == "true") {
break; //如果符合条件,则结束循环
}
}
el = U.selectEl(el).Parent(); //如果没有标签名或者是没有可编辑的元素,则获取当前元素的父级元素,继续判断
}
return el; //如果有可编辑的元素,则返回当前元素
}
/*
** 作用:判断元素是否是上级元素的子元素
** @param {element} el1 该元素的父级元素
** @param {element} el2 需要判断的元素
** @return {boolean} b 获取元素的大小,判断是否是上级元素的子元素
*/
U.UF.EL.isChild = function (el1, el2) {
//判断是否拥有两个传值,一个是需要判断的元素,一个是该元素的父级元素
if (el1 && el2) {//如果有需要的元素和父级元素,则进行程序的运行
//判断是否ie chrome兼容
if (el1.contains) {//如果兼容
//判断父级元素是否拥有需要判断的子元素
if (el1.contains(el2)) {//如果父级元素有需要判断的子元素
return true; //返回true
}
}
//判断是否为Firefox的兼容
else if (el1.compareDocumentPosition) {//如果是Firefox的兼容,compareDocumentPosition返回的是一个数值
//判断el2位于el1的哪个位置,双!!感叹号表示把数据类型转换为bool类型
if (!(!!(el1.compareDocumentPosition(el2)))) {//如果父级元素有需要判断的子元素
return true; //返回true
}
}
}
return false; //返回false
}
/*
** 作用:判断元素位于指定的位置第几个
** @param {element} el 需要判断位置的当前元素
*/
U.UF.EL.indexOfParent = function (el) {
var _el = U.selectEl(el).Parent(); //获取当前元素的父级元素
var _el2 = U.selectEl(_el).Child(); //获取当前元素的父级元素的所有的子元素
return _el2.indexOf(el); //通过indexOf检索元素在指定元素的第几个位置
}
/*
** 作用:判断元素的属性是自定义属性还是系统属性,true是自定义属性,false是系统属性
** @param {element} el 当前需要判断的元素
** @param {string} str 判断元素的属性
** @return {number} 位置
*/
U.UF.EL.isCustomAttributes = function (el, str) {
el = el || $$("div"); //获取当前需要判断的元素
var _att = el.attributes; //获取当前元素的属性集合
//判断当前元素是否拥有属性
if (_att) {//如果当前元素拥有属性
//判断当前元素的属性集合是否有需要判断的元素属性,这是IE6-7的兼容
if (_att[str]) {//如果有需要判断的元素属性
return _att[str].expando == true; //则判断的元素属性是自定义属性
} else {//是否为自定义属性
//返回元素的属性的类型和值都不为空或者当前元素的指定元素为undefined
return el.getAttribute(str) !== null || el[str] === void 0;
}
}
}
/*
** 作用:添加自定义属性
** @param {array} el 获取元素
** @param {element} name 属性的名称
** @param {element} value 属性的值
** 实例
123
var box = U.selectEl("#box")[0];
box.onclick = function(){
U.UF.EL.addAttributes(box,{"pname":"pvalue","pname1":"pvalue1","pname2":"pvalue1"});//添加自定义属性
U.UF.EL.delAttributes(box,"pname");//删除自定义属性
*/
U.UF.EL.addAttributes = function (el, name, value) {
// 如果传入的参数为name, value
el.setAttribute(name, value) // 设置元素的自定义属性
}
/*
** 作用:删除自定义属性
** @param {array} el 获取元素
** @param {element} name 属性的名称
*/
U.UF.EL.delAttributes = function (el, name) {
// 判断属性是否具有传入的属性名
if (el.hasAttribute(name)) {
el.removeAttribute(name)// 删除该属性
}
}
/*
** 作用:获取元素所需要的样式
** @param {element} el 需要获取样式的元素
** @param {string} str 获取样式的属性值,如position:absolute,则传positon或者absolute
*/
U.UF.EL.getStyle = function (el, str) {
//判断是否拥有需要获取样式的元素,并且,该元素有style样式
if (el && el.style) {//如果满足两个两件,则进行下一步程序执行
var _str = U.UF.EL.styleConversion(str); //style样式转换 如 text-align => textAlign 或者相反的换
//判断元素是否需要的样式,并且获取的样式组为cssText
if (el.style[_str] || _str == "cssText") {//如果同时满足两个条件
return el.style[_str]; //返回获取需要的元素
} else {
//判断是否有需要的样式
if (el.currentStyle) {//如果有
return el.currentStyle[_str]; //返回样式值
} else {//如果没有
return ""; //获取js对应的的style值
}
}
return ""; //获取js对应的的style值
}
}
/*
**作用:用于指定的元素进行删除指定的class,如果class存在,那么class就删除,如果class不存则不处理
**参数一:el进行操作的对象
**参数二:str获取className的字符
*/
U.UF.EL.addClass = function (el, str) {
var _Reg = el.className.match(new RegExp("(\\s|^)" + str + "(\\s|$)")); // ( \\s|^ ) 判断前面是否有空格 (\\s | $ )判断后面是否有空格
var _b = !!(_Reg); //两个感叹号为转换为布尔值 以方便做判断
if (!_b) {//判断元素存在指定的class
el.className += " " + str; //给指定的元素添加指定的class
}
}
/*
**作用:用于指定的元素进行删除指定的class,如果class存在,那么class就删除,如果class不存则不处理
**参数一:el1进行操作的对象
**参数二:el2获取className的字符
*/
U.UF.EL.removeClass = function (el, str) {
var _Reg = el.className.match(new RegExp("(\\s|^)" + str + "(\\s|$)")); // ( \\s|^ ) 判断前面是否有空格 (\\s | $ )判断后面是否有空格
var _b = !!(_Reg); //两个感叹号为转换为布尔值 以方便做判断
if (_b) {//判断元素存在指定的class
el.className = el.className.replace(new RegExp("(\\s|^)" + str + "(\\s|$)"), " ").trim(); // replace方法是替换
}
}
/*
** 作用:用于判断是否有存在的class,如果有,则返回true,如果没有,则返回false
** @param {element} el
** @param {string} str
*/
U.UF.EL.isHasClass = function (el, str) {
//判断是否存在指定的classname,如果指定的classname没有出现,则该方法返回 -1。
if ((el.className).indexOf(str) > -1) {//如果出现了classname,则会出现比-1大的值
return true; //则返回true
}
return false;
}
/*
** 作用:style样式转换 如 text-align => textAlign 或者相反的换
** @param {element} el 进行操作的对象
** @param {string} str 确定循环的范围
*/
U.UF.EL.styleConversion = function (el, str) {
if (str) {//判断是否有确定循环的范围
str = [/[A-Z]/g, "-", 0, "toLowerCase"]; //转换的样式或者属性,如textAlign => text-align
}
else {//否则的话就进行下面的语句
str = [/-[a-z ]/g, "", 1, "toUpperCase"]; //转换的样式或者属性,如 text-align => textAlign
}
return el.replace(str[0], function (el2) {//利用正则表达式进行转换
return str[1] + el2.charAt(str[2])[str[3]](); //利用charAt方法返回指定位置的字符
});
}
/*
**作用:在指定的元素区域通过鼠标进行点击或者是鼠标的其他事件,这个时候我们就需要获取这个鼠标的位置在指定元素的相对位置。
**参数一:el 需要相对位置的元素
*/
U.UF.EL.getMousePosition = function (el) {
var _eltop = 0, _elleft = 0,
_mouseevent = event || window.event; //获取事件源
//如果是手机点击则获取touches[0]对象
if (_mouseevent.touches && _mouseevent.touches[0]) {
_mouseevent = _mouseevent.touches[0]; //如果是手机则获取touches[0]对象
}
//如果是pc则获取事件源
else {
_mouseevent = _mouseevent; //如果是pc则获取事件源
}
//获取鼠标的坐标对象
var _mousex = _mouseevent.clientX || 0, //获取鼠标的X坐标或者是手机点击的X坐标
_mousey = _mouseevent.clientY || 0; //获取鼠标的Y坐标或者是手机点击的Y坐标
//循环的找位置
while (el) {
_elleft += el.offsetLeft;
_eltop += el.offsetTop;
el = el.offsetParent;
}
//计算点击的相对位置
_elx = _mousex - _elleft, //获取鼠标点击的相对位置X坐标
_ely = _mousey - _eltop; //获取鼠标点击的相对位置的Y坐标
return { x: _elx, y: _ely }//返回鼠标的相对位置X和Y坐标
}
/*
** 右键菜单处理
** @param {array} 菜单数组 {"name":"","onclick":function(){}}
** @param {string} 定位到哪个元素
*/
U.UF.EL.rightMenu = function (arr, el, e) {
var i, _menu;
if ($("#U_UF_EL_rightmenu")[0]) {
U.selectEl("#U_UF_EL_rightmenu")[0].remove();
}
_menu = $$("div", { "style": { "position": "fixed", "width": "150px", "border": "1px solid #e4e4e4", "backgroundColor": "White", "left": "100px", "display": "none", "z-index": "999" }, "id": "U_UF_EL_rightmenu" }, U.selectEl(el)[0]);
for (i = 0; i < arr.length; i++) {
var _div = $$('div', { "style": { "height": "25px", "lineHeight": "25px", "textAlign": "center", "width": "100%", "cursor": "pointer", "padding": "5px 0", "border-bottom": "1px solid rgb(228,228,228)" }, "className": "rightlist" }, _menu);
U.selectEl(_div).addAttrArray(arr[i]);
}
U.selectEl(_menu)[0].style.display = "block";
U.UF.C.rightClickMenuLocation($(_menu)[0]);
e = e || window.event;
var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; //分别兼容ie和chrome
var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
var x = e.pageX || (e.clientX + scrollX); //兼容火狐和其他浏览器
var y = e.pageY || (e.clientY + scrollY);
var _top = _menu.offsetHeight;
var _left = _menu.offsetWidth;
if (_top > y) {
_menu.style.top = y + "px";
}
if (_left > x) {
_menu.style.left = x + "px";
}
U.selectEl(_menu).bind('contextmenu', function (e) {
U.UF.EV.stopBubble(e); //阻止冒泡
});
}
;
;
///
//处理事件:
Namespace.register("U.UF.EV");
/**
* 统一绑定系统处理函数
* @param fun {function} 执行函数
* 绑定的所有函数可通过 U.UF.EV.systemEventBind,Array 查看
*/
U.UF.EV.systemEventBind = function (fun) {
U.selectEl('body').bind(fun);
U.UF.EV.systemEventBind, Array.push(fun);
}
/*
*var a = document.body.aaaa ;
*document.body.aaaa = "aaa"
* U.UF.EV.boundProperties(HTMLElement.prototype,"aaaa",
* function(){
* return this.innerHTML;
* },
* function(value){
* this.innerHTML = value;
* })
*
** 作用:属性添加处理 这里处理例如chrome取消innerText等。
当修改html元素的属性时,可以让他触发一个函数.可以用于双向绑定。当某个变量的值变了,触发回调函数,修改其中的样式。
** @param {object} obj 需要添加属性的对象
** @param {string} str 类型的名字
** @param {function} fun1 get函数处理
** @param {function} fun2 set函数处理
*/
U.UF.EV.boundProperties = function (obj, str, fun1, fun2) {
//判断obj是否已经定义了新的属性
if (obj.__defineGetter__) {//兼容处理
obj.__defineGetter__ = (obj, fun1); //__definGetter__用于Getter方法追加定义,函数第一个是getter的名称,第二个参数为getter的函数
obj.__defineSetter__ = (obj, fun2); //__definSetter__用于Setter方法追加定义,函数第一个是setter的名称,第二个参数为setter的函数
} else if (Object.defineProperty) {//ie8以上的兼容处理
//obj.defineProperty是直接在某一个对象上定义一个属性,这个属性可以用来添加或修改现有的属性,obj修改对象,key属性名,
//{//descriptor}对象用来声明新属性的特性
//configurable:默认false,表示此属性是否可用delete删除。
//enumerable: 默认为false,表示此属性是否可被for...in、Object.keys遍历到
//value:默认undefined,此属性的值,可以是任何JavaScript类型
//writable:默认为false,此属性是否可被改写
//get:默认undefined,指定一个函数,当属性被调用时,此函数也被调用,默认为返回属性值
//set:默认undefined,指定一个函数,当属性被赋值时,此函数也被调用,仅接受一个参数,参数为属性被赋的值
Object.defineProperty(obj, str, { configurable: true, get: fun1, set: fun2 });
} else {//ie6-1e7
obj[str] = fun1; //如果自动获取了属性的对象和类型的名字,则自动调用get函数处理
obj[str].toString = fun1; //获取的属性对象的类型名进行字符串转换
//attachEvent事件监听处理,第一个参数是事件类型,第二个参数是处理函数
obj.attachEvent("onpropertychange", function () {
if (event.propertyName == obj) {//判断事件对象的属性名是否为需要添加的属性的对象
//argument用于提供调用当前正在执行的函数,caller返回调用这个函数体的函数,则返回U.UF.EV.boundProperties()
//再添加一个caller,则返回调用了U.UF.EV.boundProperties()这个函数体的函数
var _str = arguments.caller.caller;
obj.detachEvent("onpropertychange", _str); //detachEvent事件监听处理,删除事件,与attachEvent相配对。第一个参数是事件参数,第二个是处理函数
fun2(obj[str]); //调用set方法去设置新的属性
obj[str] = fun1; //如果自动获取了属性的对象和类型的名字,则自动调用get函数处理
obj[str].toString = fun2; //获取的属性对象的类型名进行字符串的转换,并且调用set函数处理
obj.attachEvent("onpropertychange", _str); //重新建立事件监听处理,重新设置新的属性
}
});
}
}
/*
** 作用:对象添加原型方法,添加新的数据类型,或者在已有数据类型上扩充功能,例如:String,Number,Array,Object,Guid等
** @param {object} obj 数据类型 例如string、number等
** @param {string、object} str 当这个参数为string的时候下述函数有效
** @param {function} fun 原型对应的函数
*/
U.UF.EV.addPrototype = function (obj, str, fun) {
//判断传值的参数类型是否是string
if (typeof str == "string") {//如果传值的数据类型是string,则执行以下函数
obj.prototype[str] = fun; //prototype是添加属性和方法,向obj对象中添加一个属性
} else {
var i; //用于循环
for (i in str) {//循环所有包含了str的个数
obj.prototype[i] = str[i]; //单个添加包含了str这个类型的属性
}
}
}
/**
*当页面滚动到底端的时候执行
*
* @param {function} fun 滚动到底端需要加载的函数
* @param {objcet} obj 需要滚动的元素
*/
U.UF.EV.scrollLoad = function (obj, fun) {
obj.onscroll = function () {//滚动滚轮触发
clearTimeout(U.UF.EV.scrollLoad.time);
if (U.UF.EV.scrollLoad.scrollTop(obj) + U.UF.EV.scrollLoad.windowHeight(obj) >= (U.UF.EV.scrollLoad.documentHeight(obj))) {
U.UF.EV.scrollLoad.time = setTimeout(fun, 100);
}
}
}
/**
* 获取页面顶部被卷起来的高度
*/
U.UF.EV.scrollLoad.scrollTop = function (obj) {
return Math.max(//取最大值
//chrome
U.selectEl(obj)[0].scrollTop,
//firefox/IE
document.documentElement.scrollTop
);
}
/**
* 获取页面文档的总高度
*/
U.UF.EV.scrollLoad.documentHeight = function (obj) {
//现代浏览器(IE9+和其他浏览器)和IE8的document.body.scrollHeight和document.documentElement.scrollHeight都可以
return Math.max($(obj)[0].scrollHeight, document.documentElement.scrollHeight); //取最大值
}
/**
* 获取页面浏览器视口的高度
*/
U.UF.EV.scrollLoad.windowHeight = function (obj) {
return U.selectEl(obj)[0].clientHeight;
}
/**
* 页面活动监视,当用户离开页面休息时,停止页面活动(计时器)
*
* @param {function} 页面聚焦回调函数
* @param {function} 页面离开的回调
* @return {string} 获取key对应的值
*/
U.UF.EV.IsActivity = function (fun1, fun2) {
var _timer;
//页面聚焦的处理
if (fun1) {
//判断鼠标是否在body页面上
U.selectEl(document.body).mouseenter(function () {
//由于函数会多次触发,所以做一个计时器进行处理,让函数只触发一次
if (_timer) {
window.clearTimeout(_timer);
}
_timer = window.setTimeout(fun1);
});
//页面聚焦同时为活动页面
U.UF.EV.addElementEvent("focusin", document, function () {
//由于函数会多次触发,所以做一个计时器进行处理,让函数只触发一次
if (_timer) {
window.clearTimeout(_timer);
}
_timer = window.setTimeout(fun1);
});
}
//页面失焦的处理
if (fun2) {
//页面不活动的时候处理
U.UF.EV.addElementEvent("focusout", document, function () {
var _clientx = event.clientX; //页面x坐标
var _clienty = event.clientY; //获取event对象的y坐标
//判断用户的鼠标是否在制定的范围内,如果在说明活动了当前页面
if ((!(U.UF.CI.getBrowser().browser == "msie") ||
(_clientx < 0 || _clientx > US.width || _clienty < 0 || _clienty > US.height))) { //判断鼠标不在页面中
fun2();
}
});
}
}
/**
* 滚动条滚动到制定的位置
*
* @param {string} 指定scrollTop的数值
* @param {function} 需要调整滚动条位置的对象
* @param {function} 加载成功回调
* @return {element} 图片元素
*/
U.UF.EV.scrollToPosition = function (str, fun1, fun2) {
var _isnumber = U.UF.C.isNumber(str); //判断str是否是数字true 或者 false
//动画移动具体的位置
if (_isnumber && fun2) {
U.selectEl(fun1).animate({ "scrollTop": str }, fun2);
}
else {
//设置fun1的内容垂直滚动的像素数
if (typeof str == "number") {
fun1.scrollTop = str;
}
else {
str.scrollIntoView(); //sty.scrollIntoView 让当前的元素滚动到浏览器窗口的可视区域内
}
} //直接移动过
}
/**
* 自动触发HTMLElement事件 Mouse事件,模拟鼠标点击事件
*
* @param {element} 触发的元素
* @param {string} 事件类型
* @return {object} resize对象
*/
U.UF.EV.simulateMouseClicks = function (el, str) {
//ie直接执行事件的处理
if (el.fireEvent) {
return el.fireEvent("on" + str, window.event);
}
//ie以外的浏览器处理事件执行
else if (document.createEvent) {
var _mousevent = document.createEvent("MouseEvents"), //创建事件事件
_event = window.event; //事件处理
//初始化事件
if (_event) { //原本已经具有事件event来源的情况下处理
//执行mouse事件处理
_mousevent.initMouseEvent(
str,
true,
true,
window,
_event.detail,
_event.screenX,
_event.screenY,
_event.clientX,
_event.clientY,
_event.ctrlKey,
_event.altKey,
_event.shiftKey,
_event.metaKey,
_event.button,
_event.relatedTarget
);
}
else {
//没有事件来源event的处理
_mousevent.initMouseEvent(
str,
true,
true,
document.defaultView,
0,
0,
0,
0,
0,
false,
false,
false,
false,
0,
el
)
}
//分发事件
return el.dispatchEvent(_mousevent);
}
}
/**
* 自动触发HTMLElement Touch事件
*
* @param {element} 触发的元素
* @param {string} 事件类型
* @param {object} resize对象
*/
U.UF.EV.simulatePhoneTouch = function (el, str, obj) {
if (el.fireEvent) { //ie事件触发处理
el.fireEvent("on" + TF);
}
else if (document.createEvent) { //h5事件处理
var i,
_arr,
_event = obj || window.event;
//创建一个touch时间的处理
if (TouchEvent) { //有TouchEvent的创建方式
var _touchevent = new TouchEvent(str, _event);
}
//其他的创建方式
else {
var _touchevent = document.createEvent("TouchEvent");
}
//执行事件的方法
if (_touchevent.initTouchEvent) { //有initTouchEvent执行方法的处理
var _str = "initTouchEvent";
}
else { //initEvent执行方法的处理
var _str = "initEvent";
}
//chrome
_arr = [
//chrome
[
event.touches, //当前屏幕上所有触摸点的列表
event.targetTouches, //当前对象上所有触摸点的列表
event.changedTouches, //涉及当前(引发)事件的触摸点的列表
str,
event.view,
event.screenX,
event.screenY,
event.clientX,
event.clientY,
event.ctrlKey,
event.alrKey,
event.shiftKey,
event.metaKey
],
//safari
[
str,
true,
event.cancelable,
event.view,
event.detail,
event.screenX,
event.screenY,
event.clientX,
event.clientY,
event.ctrlKey,
event.altKey,
event.shiftKey,
event.metaKey,
event.touches,
event.targetTouches,
event.changedTouches,
event.scale,
event.rotation
],
//firefox
[
str,
true,
event.cancelable,
event.view,
event.detail,
event.ctrlKey,
event.altKey,
event.shiftKey,
event.metaKey,
event.touches,
event.targetTouches,
event.changedTouches
],
];
//由于浏览器对直接执行事件的兼容有三种方案,这里是对三种方案的循环添加
for (i = 0; i < _arr.length; i++) {
//直接执行
try {
_touchevent[_str].apply(_touchevent, _arr[i]);
}
catch (e) {
}
if (_touchevent.type == str) {
break;
}
}
}
return el.dispatchEvent(_touchevent); //分发事件
}
/**
* 注册函数事件 Internet Explorer 8 及更早IE版本不支持 addEventListener() 方法,,Opera 7.0 及 Opera 更早版本也不支持。 但是,对于这些不支持该函数的浏览器,你可以使用 attachEvent() 方法来添加事件句柄
*
* @param {string} 事件名称
* @param {element} 添加事件的元素
* @param {function} 事件触发后调用的函数
* @param {string} 指定事件是否在捕获或冒泡阶段执行
*/
U.UF.EV.addElementEvent = function (str, el, fun, isbubble) {
if (el.addEventListener) { //非IE使用
el.addEventListener(str, fun, isbubble || false);
}
else if (el.attachEvent) { //IE
el.attachEvent("on" + str, fun);
}
else {//html5处理
el["on" + str] = function () {
el["on" + str]();
fun();
}
}
}
/**
* 取消函数事件
*
* @param {string} 事件名称
* @param {element} 添加事件的元素
* @param {function} 事件触发后调用的函数
* @param {string} 指定事件是否在捕获或冒泡阶段执行
*/
U.UF.EV.delElementEvent = function (str, el, fun, isbubble) {
if (el.removeEventListener) { //非IE使用
el.removeEventListener(str, fun, isbubble || false);
}
else if (el.detachEvent) {//IE使用
el.detachEvent("on" + str, fun);
}
else { el["on" + str] = null; } //非元素
}
/**
* 获取事件源 跨iframe搜索,由于我们在点击iframe的时候,不知道事件是从哪个iframe或者来的,所以这里循环iframe找事件的来源
*
*/
U.UF.EV.getEventSource = function () {
var i, //循环初始化
_data, //用于储存数据
_frames = window.frames; //获取window.frames
var _event = window.event; //获取window.event
if (!_event) {
for (i = 0; i < _frames.length; i++) { //循环所有的iframe 获取事件源
_data = _frames[i]; //得到iframe处理
//由于非自己站点的iframe会存在跨域处理
try {
_event = _data.event; //获取事件
//如果找到了事件那么就直接break
if (_event) {
break;
}
}
catch (e) { continue; };
}
}
//返回事件源
return _event;
}
/**
* 阻止冒泡
*/
U.UF.EV.stopBubble = function () {
var _event = U.UF.EV.getEventSource(); //获取Event
//调用的时候判断是否有时间的来源
if (_event) {
//非ie系列浏览器支持处理事件冒泡的方案
if (_event.stopPropagation) {
_event.stopPropagation();
}
//ie系列浏览器支持去小事件冒泡处理
else {
_event.cancelBubble = true;
}
}
}
/**
* 执行mouseout mouseover不冒泡情况,以前是多次触发,现在做到移动进去触发一次,移动出来触发一次
* mouseout||mouseover 冒泡解决
*
* @param {element} 需要执行的元素
* @return {function} 回调函数
*/
U.UF.EV.stopBubbleMouseOutOrOver = function (el, cb) {
if (event && "mouseover,mouseout".indexOf(event.type) > -1) { //判断事件源
var _target = (event.type == "mouseover" ? event.fromElement : event.toElement) || event.relatedTarget, //事件对象
_bool = U.UF.EL.isChild(el, _target); //判断_target是否是el的子孙节点
if (!_bool && U.UF.C.isFunction(cb)) { //判断是否在该元素下
cb();
}
return _bool;
}
}
/**
* 阻止浏览器的默认行为,例如右键菜单,左键选择
*
*/
U.UF.EV.stopDefault = function (e) {
var _event = e || window.event; //获取window.event对象
if (_event) {
//IE中阻止函数器默认动作的方式
if (document.all) {
_event.returnValue = false;
}
//阻止默认浏览器动作(W3C)
else {
_event.preventDefault();
}
return false;
}
}
/**
事件委托,本地程序调用客户端程序时会用到。
* 随机产生一个函数 调用后销毁 类似委托
解决跨域问题,以及ajax多个请求,多份实例的问题。
*
* @param {function} 回调函数
* @param {array} 回调参数 params1
* @param {boolean} 执行成功后是否移除委托
* @param {string} id
* @return {object} 委托对象
*/
U.UF.EV.eventDelegation = function (cb, params, isremove, id) {
if (isremove == null) {
isremove = true;
}
var _id = id || "a" + Guid.newGuid(); //唯一识别id
window[_id] = function () {
try {
//判断是否有回调函数
if (U.UF.C.isFunction(cb)) {
cb.apply(null, arguments);
}
//是否移除事件委托对象
if (this.isremove) {
window[_id] = null; //设置对象移除
delete window[_id]; //清理对象
}
}
catch (e) { }
}
return _id;
}
/**
* 页面消息传递,解决跨域问题。
* @param {function} 跨域iframe传参的回调函数
* @param {boolean} 是否是发送者,在iframe里面的是接收者,iframe外的是发送者
* @param {string} 与iframe通讯的唯一识别id,如果是接收多个不同回调的消息,那么需要传参
* @param {string} 需要跨域的iframe的id
*
*/
U.UF.EV.message = function (fun, issender, id, iframeid) {
this.fun = fun; //监视消息的函数
this.id = id || Guid.guidNoDash(); //消息通讯的唯一id
this.sender = issender; //是否是发送者
this.iframeid = iframeid; //消息发送到哪个iframe里 接受者没有
this.iframe = null; //发送给那个iframe的元素
this.url = ""; //iframe的链接
U.UF.EV.message.callbacks[this.id] = this; //所有消息记录
//设置onmessage事件获取浏览器之间的传参
if ("onmessage" in window) {
U.UF.EV.addElementEvent("message", window, U.UF.EV.message.getDataAndCallBack);
}
//如果是iframe内的发送的处理方式
if (this.sender) {
this.iframe = U.selectEl("#" + this.iframeid)[0]; //获取iframe
this.url = $$("a", { "src": this.iframe.src }).host; //iframe的链接,用于ie跨域传参的时候使用
}
//如果是接收者也就是iframe里面的对象的处理方法
else if (!("onmessage" in window)) {
U.UF.EV.message.getDataAndCallBack();
}
}
//这里包含了所有的需要回调的回调函数
U.UF.EV.message.callbacks = [];
/**
* 得到数据的方法
* @message {object} 发送者发送的信息
*/
U.UF.EV.message.getDataAndCallBack = function (message) {
var _data;
//高版本的浏览器是通过onmessage获取的
if ("onmessage" in window) {
_data = message.data; //获取数据
}
//低版本的浏览器获取值得处理
else {
_data = window.name; //获取数据
}
_data = _data.parseJSON(); //传入的数据转化成json处理
var _fun = U.UF.EV.message.callbacks[_data[1]]; //得到回调函数的类
//如果类存在,那么调用类的message数据回调方法
if (_fun) {
_fun.message(_data[0], _data[1], _data[2]);
}
}
//message类的原型方法
U.UF.EV.message.prototype = {
/**
* 接收消息
* @data {object} 接收的信息
* @cookie {object} 接受者 cookie
*/
message: function (data, id, cookie) {
//如果页面监视的是回调函数的处理
if (U.UF.C.isFunction(this.fun)) {
this.fun(data, id, cookie);
}
//如果是接收者,同时又是在低版本的浏览器下使用的iframe,那么清空iframe的使用
if (this.sender && !("onmessage" in window)) {
var _doc = this.obj.contentWindow.document; //重新创建一个document
_doc.open(); //打开
_doc.write(""); //整个页面写入空
_doc.close(); //关闭
}
},
/**
* 提交消息
* @data {object} 发送者发送的信息
* @id {object} 发送者的id
* @cookie {object} 发送者 cookie
*/
post: function (data, id, cookie) {
var _win,
_message = U.UF.C.jsonToStr([data, id || this.id, cookie]); //拼接传参的参数,由于发送者和接受者都公用这个 所以当接受者给发送者发回消息的时候第二个参数是发送者的id。
//高版本的iframe发送消息
if ("onmessage" in window) {
if (this.sender) {
//得到iframe传参的域
try {
_win = this.iframe.contentWindow || this.iframe; //如果是发送者,那么获取contentWindow
}
catch (e) {
_win = this.iframe; //如果是接收者发送回给发送者,那么iframe是parent就不需要获取contentWindow了
}
}
else {
_win = parent;
}
_win.postMessage(_message, "*"); //发送消息
}
//低版本的浏览器发送iframe消息
else {
//如果是发送者发消息的处理
if (this.sender) {
//等待iframe重新加载后处理跨域
U.UF.DL.iframeLoad(this.iframe, U.UF.C.apply(this, function () {
this.iframe.contentWindow.name = _message; //设置window.name传参值
this.iframe.contentWindow.location.href = this.url; //刷新到跨域的页面
//重新设置onlaod事件处理等待页面响应
U.UF.DL.iframeLoad(this.iframe, U.UF.C.apply(this, function () {
U.UF.EV.message.getDataAndCallBack(); //调用iframe返回数据后重新load "about:blank"链接后的回调
}));
}));
this.iframe.src = "about:blank"; //重新加载iframe
}
//接受者的处理
else {
window.name = _message; //设置window.name传参值
window.src = "about:blank"; //
}
}
}
}
/**
* 打印处理函数
*
*/
U.UF.EV.print = function (el) {
// var AllContent = window.document.body.innerHTML; //首先获得元素的html内容,保存当前页面的HTML
// var newstr = el.innerHTML; //得到需要打印的元素HTML
// document.body.innerHTML = newstr; //把当前页面替换为打印内容HTML
// window.print(); //执行打印操作
// document.body.innerHTML = AllContent; //还原当前页面
var iframe = document.createElement('iframe');
var doc = null;
iframe.setAttribute('style', 'position:absolute;width:0px;height:0px;left:-500px;top:-500px;');
document.body.appendChild(iframe);
doc = iframe.contentWindow.document;
doc.write('
' + el.innerHTML + '
');
doc.close();
iframe.contentWindow.focus();
iframe.contentWindow.print();
if (navigator.userAgent.indexOf("MSIE") > 0) {
document.body.removeChild(iframe);
}
}
;
///
Namespace.register("U.UF.IMG");
/**
* 图片预加载方法
*
* @param {string} 需要加载的图片地址
* @param {function} 预加载回调函数
* @param {function} 加载成功回调
* @param {function} 错误处理回调
* @return {element} 图片元素
*/
U.UF.IMG.imgReady = function (url, URD, ULD, UE) {
var _UW,
_UH,
_UNW, //image对象的width属性
_UNH, //image对象的height属性
_UIMG = new Image(); //image对象
_UOR = function () { //预加载
_UIMG = _UIMG || this;
_UNW = _UIMG.width;
_UNH = _UIMG.height; //获取加载图片的长宽
if ((_UNW !== _UW || _UNH !== _UH) || _UNH !== 0) {
if (URD) { URD.call(_UIMG) };
_UOR.end = true;
}
};
U.selectEl(_UIMG).addAttrArray({
"src": url,
"onload": function () { //成功加载回调
setTimeout(function () {
if (!_UOR.end) { _UOR() };
if (_UIMG) { _UIMG.onload = _UIMG.onerror = null };
if (_UIMG && ULD) { ULD.call(_UIMG) };
_UIMG = null;
}, 0);
},
"onerror": function () { //错误图片处理
if (U.UF.C.IsNetwork()) {
if (UE) { UE.call(_UIMG) };
}
}
});
if (_UIMG) { //说明图片还在加载中
_UOR(); //执行预加载处理
if (_UIMG.complete == true) { //判断是否已经成功加载过了 缓存图片处理
_UIMG.onload(); return;
}
}
if (!_UOR.end) { //添加进入图片大小加载事件
U.UF.IMG.imgReady._UL.push(_UOR);
if (U.UF.IMG.imgReady._UIT == null) {
U.UF.IMG.imgReady._UIT = setInterval(U.UF.IMG.imgReady._URT, 40); //每40毫秒进入
}
}
return _UIMG;
}
U.UF.IMG.imgReady._UIT; //计时器初始化
U.UF.IMG.imgReady._UL = []; //需要预加载的图片集
//去除预加载计时
U.UF.IMG.imgReady._US = function () {
clearInterval(U.UF.IMG.imgReady._UIT);
U.UF.IMG.imgReady._UIT = null;
};
//计时加载逐个加载处理
U.UF.IMG.imgReady._URT = function () {
for (var i = 0; i < U.UF.IMG.imgReady._UL.length; i++) {
U.UF.IMG.imgReady._UL[i].end ? U.UF.IMG.imgReady._UL.splice(i--, 1) : U.UF.IMG.imgReady._UL[i]();
}
if (!U.UF.IMG.imgReady._UL.length) { U.UF.IMG.imgReady._US() };
}
;
///
//json综述。此类主要处理以下两种情况的数据。
//1、后台返回的数据形如:{"id":"1","name":"zhangsan"} 称为json数据,在js中称为对象。
// 元素Elements,包括div,a,input等在前端的表现形式是:{"tagname":"input","className":""}
// {"tagname":"div","className":""}
//2、[
// {"id":"1","name":"zhangsan"}
// {"id":"2","name":"lisi"}
// ]
//
//综上所述,前端元素,数据基本都是{}.所以本数据处理类是针对前端所有对象。
//#region 这里是json操作区域
Namespace.register("U.Json");
//兼容JSON
U.Json.init = function () {
if (!window.JSON) {
window.JSON = {
stringify: U.Json.stringify,
parse: U.Json.parse
};
}
}
//JSON类操作,如果不存在json类,则自己创建一个window.JSON。只有一个地方使用了此函数的parse方法
U.Json.stringify = function (json) {//转化成字符串
return U.UF.C.jsonToStr(json);
}
U.Json.parse = function (str) {//转化成实体
return str.parseJSON();
}
/**
* 判断数据是否符合条件
*
* @param {object || array} 被添加的json对象或者数组
*
* @param {object} 比较的对象
*
* @return {object} 比较的对象
*/
U.Json.ifExists = function (key1, key2) {
if (key2 === key1) {
return true;
}
for (var i in key1) {
if (key1[i] != key2[i]) {
return false;
}
}
return true;
}
//#region json对象处理类,处理类似下面的json数据
/*{
"_id" : ObjectId("532eab25aa01ee01e2297676"),
"UserID" : "83ddf636-7266-4d15-be11-a7ef89bcac55",
"TNode" : [{
"Name" : "根目录",
"CreateDate" : ISODate("2014-03-23T09:36:37.376Z"),
"Type" : "folder",
"ID" : "e6f3963e-6087-b772-8e54-561353832f7b",
"Deep" : 1.0,
"IsDelete" : false,
"TNode" : [{
"Name" : "Test",
"CreateDate" : ISODate("2014-03-23T09:36:43.526Z"),
"Type" : "folder",
"ID" : "0fb91d00-7c5b-dd79-4f3e-1c2d405611e2",
"IsDelete" : false,
"Deep" : 2.0,
"TNode" : [{
"Name" : "index.htm",
"CreateDate" : ISODate("2014-03-23T09:36:43.548Z"),
"Type" : "file",
"ID" : "929bb945-ca3b-dedd-7077-88d1ce0492e3",
"IsDelete" : false,
"Deep" : 3.0,
"Content" : ""
}],
"IsPublic" : true
}]
}]
}*/
/**
* 添加json对象
*
* @param {object || array} 被添加的json对象或者数组
*
* @param {object} 需要添加的对象值
*
* @return {object} 返回添加后新的对象值
实例一
var a = [{username:"a"},{username:"b"},{username:"c"}];
var b = {test:'1'}
U.Json.add(a,b);
实例二
var a = {username:"cxs"}
var b = {id:'1'}
U.Json.add(a,b);
*/
U.Json.add = function (obj1, obj2) {
var i; //循环初始值
//判断参数obj1是否为对象或者数组,如果是对象,循环添加。
if (!Array.isArray(obj1)) {//判断是否为数组
for (i in obj2) {//循环参数obj2对象
obj1[i] = obj2[i]; //对参数obj1赋值
}
}
//如果参数obj1是数组,为数组中的每一个对象都添加赋值
else {
for (i = 0; i < obj1.length; i++) {//循环obj1数组
U.UF.C.AddObj(obj1[i], obj2); //为数组中的每一个对象元素都添加对象obj2的值。
}
}
//返回添加后新的对象值
return obj1;
}
//少一个跨层搜索的方法。
//obj json格式 为类似mongodb中的数据,
//key 字符串 是关键字
//value 字符串 是值
U.Json.find = function (obj, key, value) {
}
//#endregion
//#region 处理jsonArray的数据,实质是数组
/**
* 根据条件,删除json数组中指定的json
*
* @param {array} 被删除的json数组。
*
* @param {object} 删除json的数据。
*
* @return {object} 返回的删除数据。
实例一
var a = [{parentid:1, username:"a"},{parentid:1,username:"b"},{parentid:2,username:"c"}]
var b = {parentid:2,username:"c"}
U.Json.delete(a,b);
*/
U.Json.del = function (obj, key, data) { //删除 允许递归
data = data || obj; //传递进来的json数据
var i,
_deldata,
_delarray = []; //返回的删除数据。
//数组删除指定obj条件的元素
if (Array.isArray(data)) {//数组使用
for (i = 0; i < data.length; i++) {
//循环删除 获取移除的元素
_deldata = U.Json.del(obj, key, data[i]);
if (_deldata.length) { //判断是否移除了元素,length大于0相当于移除超过一个元素。
data.splice(i, 1); //数组的系统移除方法
_delarray = _delarray.concat(_deldata); //把移除的元素添加到变量中
i--; //由于上面用了循环i++ 移除元素后 数组的下标减一了,所以这里用i--让i回到前面一个循环,这样即使数组删除了一个元素也不会直接跳过下一个元素的循环
}
}
}
else if (typeof data == "object") { //对象删除
if (U.Json.ifExists(key, data)) {
delete data;
_delarray.push(data);
}
else if (key === true) { //递归删除
for (i in data) {
_deldata = U.Json.del(obj, key, data[i]); //递归删除该数据
_delarray = _delarray.concat(_deldata); //把删除的数据追加到变量中
}
}
else if (key && data[key]) { //根据指定的key进行递归删除
_deldata = U.Json.del(obj, key, data[key]); //根据指定的key递归删除该数据
_delarray = data.concat(_deldata);
}
}
return _delarray;
}
/**
* 根据条件,查找json数组中指定的json
*
* @param {array} 需要进行选择的json数组。
*
* @param {object} 选择的条件
*
* @param {number} 选择的个数
*
* @return {array} 选择后的结果
实例一
var a = [{ parentid: 1, username: "a" }, { parentid: 1, username: "b" }, { parentid: 2, username: "c" }]
var b = { parentid: 1 }
U.Json.select(a,b,2);
*/
U.Json.select = function (arr, obj, num) {//条件获取
var i, //判断初始化
_bool, //用于参数判断
_res = []; //用于存放选择后的结果
//判断需要选择的对象是否为数组
if (Array.isArray(arr)) {
//循环json数组
for (i = 0; i < arr.length; i++) {
//设置判断默认值
_bool = true;
//循环条件
for (var j in obj) {
//如果是其中有一个条件不符合要求,修改判断值。
if (arr[i][j] != obj[j]) {
_bool = false;
}
}
//如果所有的条件都成立,则记录数组
if (_bool) {
_res.push(arr[i]);
}
//判断程序选择的个数是否大于用户的选择个数,如果大于选择个数,跳出循环
if (_res.length == num) {
break;
};
}
}
//返回结果集
return _res;
}
/**
* 根据条件,查找json数组中指定的json,只获取一个结果集
*
* @param {array} 需要进行选择的json数组。
*
* @param {object} 选择的条件
*
* @return {array} 选择后的结果
实例一
var a = [{ parentid: 1, username: "a" }, { parentid: 1, username: "b" }, { parentid: 2, username: "c" }]
var b = { parentid: 1 }
U.Json.selectOne(a,b);
*/
U.Json.selectOne = function (arr, obj) {
return (U.Json.select(arr, obj, 1))[0];
}
/**
* 根据条件,对json数组进行排序,此函数需要移动到数组中。
*
* @param {array} 需要进行选择的json数组。
* @param {number} 排序方式 1正序 -1倒序
* @return {string} 排序的条件,json数组中的键名
实例一
var a = [{id:3},{id:1},{id:2}];
U.Json.sort(a,"id");
*/
U.Json.sort = function (arr, key, isreverse) { //排序
isreverse = isreverse || 1;
//采用数组本身的排序sort方法,此方法比较奇特。
arr = arr.sort(function (obj1, obj2) {
var _value,
_type, //比较大小的类型
_value1 = obj1[key],
_value2 = obj2[key],
_isobj = U.UF.C.isObject(obj1); //判断比较的大小是否为对象
//对象的大小匹配
if (_isobj) {
_type = (typeof (obj1[key] || obj2[key])).capitalizeFirstLetter(); //由于类型的值有可能是null或者是undefined,判断两种比较安全
}
//非对象的处理方式 U.UF.Ut.compare+type 是一些列的对象比较大小的方法
else {
_type = (typeof obj1).capitalizeFirstLetter();
}
//数字大小比较
if (_type == "Number") {
_value = _value1 > _value2;
}
//时间大小比较
else if (_type == "Date") {
_value = U.UF.D.SizeComparison(_value1, _value2);
}
//字符串大小比较
else if (_type == "String") {
_value = _value1.localeCompare(_value2) == 1;
}
//服务器的值可能是null,没有类型比较默认第一个比第二个大
else {
_value = true;
}
//isreverse 用于判断倒序还是正序,如果是-1就是倒序,如果是1就是正序,需要返回这个值给数组的sort函数,比较奇特
_value = isreverse * (_value ? 1 : -1);
return _value;
});
return arr;
}
/**
* 根据条件,对json数组进行排序,此函数注释有问题
*
* @param {array} obj数组
* @param {string} 关键字
*/
U.Json.toKeyArray = function (arr, key) {
var i,
_returnarr = []; //数组存储数据
//循环写入数据
for (i = 0; i < arr.length; i++) {
_returnarr.push(arr[i][key]);
}
//返回数组
return _returnarr;
}
/**
* 根据条件,对json数组进行排序,此函数注释有问题
*
* @param {array} obj数组
* @param {object} key value的条件
* @param {number} 关键字
*/
U.Json.like = function (arr, obj, num) {
var i, //判断初始化
_bool, //用于参数判断
_res = []; //用于存放选择后的结果
//判断需要选择的对象是否为数组
if (Array.isArray(arr)) {
//循环json数组
for (i = 0; i < arr.length; i++) {
//设置判断默认值
_bool = false;
//循环条件
for (var j in obj) {
//如果是其中有一个条件不符合要求,修改判断值。
if (arr[i][j] && (arr[i][j].indexOf(obj[j]) > -1 || obj[j].indexOf(arr[i][j]) > -1)) {
_bool = true;
}
}
//如果所有的条件都成立,则记录数组
if (_bool) {
_res.push(arr[i]);
}
//判断程序选择的个数是否大于用户的选择个数,如果大于选择个数,跳出循环
if (_res.length == num) {
break;
};
}
//返回结果集
return _res;
}
}
//#endregion
;
///
//#region 函数区域
Namespace.register("U.UF.Math");
/**
* 获取一个随机数
*
* @param {number} 随机数的长度
* @return {number} 随机数
*/
U.UF.Math.getRandom = function (n) {
return Math.floor(Math.random() * n + 1);
}
/**
* 获取两个数字间的随机数
*
* @param {number} 位置的开始
* @param {number} 位置的结束
* @return {number} 随机数
*/
U.UF.Math.randomRange = function (m, n) {
return Math.floor(Math.random() * Math.abs(n - m)) + (m > n ? n : m);
}
/**
* 冒泡排序法的封装
*
* @param {array} 排序数组
* @param {string} 排序类型
* @param {function} 判断执行函数
* @param {number} 是否是升序降序
----------[-1] 升序
----------[1] 降序
*/
U.UF.Math.sequence = function (arr, str, fun, num) {
if (arr) {//是否存在数组
var _num;
arr = arr.sort(function (obj1, obj2) {//arr.sort()根据条件,对json数组进行排序
if (fun(obj1[str], obj2[str])) {//是否是升序降序
_num = (-1) * (num || 1); //num=-1升序
} else {
_num = 1 * (num || 1); //num=1 降序
}
return _num;
});
return arr;
};
}
/**
*浮点数运算函数
JavaScript浮点运算的一个bug。 比如:7*0.8 JavaScript算出来就是:5.6000000000000005
* 数字计算 解决浮点的bug
*
* @param {number} 数字1
* @param {number} 数字2
* @param {string} 连系符号 + - * /
*/
U.UF.Math.floatOperate = function (number1, number2, operator) {
var i, //循环初始化
_pow, ////用于存放数据的变量
_strarr = [String(number1), String(number2)]; //用于存放数据的数组
//获取变成整数差几位
for (i = 0; i < 2; i++) {
_strarr[i + 2] = _strarr[i].length - _strarr[i].indexOf(".") - 1;
}
//变成整数的幂
_pow = Math.pow(10, Math.max(_strarr[2], _strarr[3]));
//运算得出结果
return (eval("0," + _strarr[0] * _pow + operator + _strarr[1] * _pow)) / _pow;
}
;
///
/*
前进后退处理区域
用于场景
1、导航前进后退处理
2、记录用户步骤处理
3、url前进后退处理
*/
Namespace.register("U.UF.N");
//#region 前进后退使用处理区域
U.UF.N.goList = {}; //前进后退处理
U.UF.N.route = null //url处理
/**
* 前进后退公开调用区域
*
* @param {string} 前进后退在指定的域
* @param {boolean} 是否重新加载
*/
U.UF.N.createNav = function (str, bool) {
var _obj = U.UF.N.goList;
//根据类类型 获取前进后退类
if (_obj[str] && bool !== true) { //已经存在域的前进后退
return _obj[str].context;
}
else { //创建一个新的前进后退处理
return new U.UF.N.initNav(str);
}
}
/**
* 注册前进后退
*
* @param {string} 前进后退在指定的域 如 disk 那就在disk导航
*/
U.UF.N.initNav = function (str) {
/*
描述
-----OF: 当前前进后退集合
-----OL: 前进后退所在的位置
-----UT: 当前的域
*/
this.cb = [];
this.length = 0;
this.context = this;
U.UF.N.goList[str] = this; //添加到集合里面
}
/**
* 添加前进后退
*
* @param {function} 前进后退函数添加
* @param {string} 前进后退在指定的域
*/
U.UF.N.addEvent = function (callback, str) {
var _goList = U.UF.N.createNav(str); // 获取前进后退类
_goList.addHandleEvent(callback); // 注册前进后退事件
callback(); //添加执行前进后退
}
/**
* 添加前进后退事件
*
* @param {function} 前进后退函数添加
*/
U.UF.N.addHandleEvent = function (callback) {
this.cb.splice(this.length, this.cb.length - this.length, callback); //添加一个回调函数
// this.cb.length - this.length 始终为0
this.length++; //位置加一
}
/**
* 前进后退统一处理区
* 该函数必须得先后退才能前进
*
* @param {number} 前进后退处理参数
----------1 后退处理
----------0 前进处理
*/
U.UF.N.handle = function (num) {
var _callback = this.cb[this.length - num * 2]; //获取前进后退事件
// 若 num 为1 则 this.cb[this.length - num * 2] 为 this.cb[this.length - 1]
// 若 num 为0 则 this.cb[this.length - num * 2] 为 this.cb[this.length]
if (_callback) {
_callback();
this.length += ((-num * 2) + 1); //前进后退执行
// 若 num 为1 则 将 this.length - 1
// 若 num 为0 则 将 this.length + 1
}
}
/**
* 后退执行
*
* @param {string} 前进后退在指定的域
*/
U.UF.N.backOff = function (str) {
U.UF.N.goList[str]["context"].handle(1);
}
/**
*
* 前进执行
*
* @param {string} 前进后退在指定的域
*/
U.UF.N.goAhead = function (str) {
U.UF.N.goList[str]["context"].handle(0);
}
/**
*
* 获取当前位置
*
* @param {string} 前进后退在指定的域
* @return {object} 返回位置信息
* 数据结构如下: {
* count: 总计层级,
* now: 当前层级(1为根级导航 当当前层级等于总计层级时为最后一级导航)
* }
*/
U.UF.N.getLocation = function (str) {
return {
count: U.UF.N.goList[str].cb.length,
now: U.UF.N.goList[str].length
}
}
//设置原型 运行实例化使用
U.UF.N.initNav.prototype = {
addEvent: U.UF.N.addEvent,
addHandleEvent: U.UF.N.addHandleEvent,
handle: U.UF.N.handle,
backOff: U.UF.N.backOff,
goAhead: U.UF.N.goAhead
}
//#endregion
//#region 网页路由使用
//
U.UF.N.isActive = false;
/*
* 作用:初始化函数,每次修改hash值的时候都会触发这个函数,调用onhashchange事件
* @param {callback} fun 回调函数,进行数据的操作
*/
U.UF.N.route = function (fun) {
//当浏览器前进后退修改hash值时,触发onhashchange事件
if (document.all && !document.documentMode) { //辨别IE,IE8才有documentMode
/* 低于IE8的IE系列采用定时器监听 */
setInterval(function () { U.UF.N.changeHashCallBack(fun) }, 100); //每隔0.1秒监听一次hash值,发生变化时,触发U.UF.N.changeHashCallBack()这个函数
}
else {
window.onhashchange = function () { U.UF.N.changeHashCallBack(fun) }; //当hash值改变时,触发函数U.UF.N.changeHashCallBack()
}
}
/*
* 作用:给需要添加hash的元素添加hash值
* @param {string} hashname 添加hash的name
*/
U.UF.N.addHash = function (hashname) {
U.UF.N.setHash(hashname); //给需要添加hash值的元素设置hash值,参数为添加hash的name
}
/*
* 作用:给需要添加hash值的元素设置hash值
* @param {element} id 添加hash的值
*/
U.UF.N.setHash = function (id) {
U.UF.N.isActive = true; //设置成程序主动模式
location.hash = id; //给当前的hash值设值为用户自定义的hash的name
//计时器处理
setTimeout(function () {
//计时器处理,等浏览器响应hash后设置为非主动模式
U.UF.N.isActive = false;
}, 10)
}
/*
* 作用:获取当前的hash值
*/
U.UF.N.getHash = function () {
var _nowhash = location.hash; //获取当前的hash值
if (!_nowhash) {//判断是否有这个hash值
return ''; //如果没有返回空
}
else {//如果有
return location.hash; //返回当前的hash值
}
}
/*
* 作用:当hash改变之后,会触发这个函数
*/
U.UF.N.changeHashCallBack = function (fun) {
//如果不是通过程序添加的处理,而是用户自己输入到地址栏的处理
if (!U.UF.N.isActive) {
var _newhash = U.UF.N.getHash(); //获取当前的hash值
var _hash = _newhash.substr('1'); //获取hash值的#符号后面的内容
if (_hash != "") { //判断U.UF.N.Data的json数据中是否存在这个hash值
fun(_hash);
}
else if (_hash == "") {
window.history.forward(1); //如果是,禁止后退
}
}
}
//#endregion
;
///
Namespace.register("U.UF.QR"); //二维码命名空间
/**
* 生成二维码
*
* @param {number} 二维码元素宽度
* @param {number} 二维码元素高度
* @param {string} 二维码背景色
* @param {string} 二维码前景色
* @param {string || object} 二维码内容
* @param {object} 二维码追加元素
*/
U.UF.QR.generate = function (w, h, d, l, v, g) {
//清空生成地
g.innerHTML = "";
//创建一个对象
var qrcode = new QRCode(g, {
width: w,
height: h,
colorDark: d,
colorLight: l,
correctLevel: QRCode.CorrectLevel.H //容错率
});
U.UF.QR.makeCode = function (v) {
//绘制
qrcode.makeCode(v);
}
U.UF.QR.makeCode(v);
}
/**
* @fileoverview
* - Using the 'QRCode for Javascript library'
* - Fixed dataset of 'QRCode for Javascript library' for support full-spec.
* - this library has no dependencies.
*
* @author davidshimjs
* @see
http://www.d-project.com/
* @see
http://jeromeetienne.github.com/jquery-qrcode/
*/
var QRCode;
(function () {
//---------------------------------------------------------------------
// QRCode for JavaScript
//
// Copyright (c) 2009 Kazuhiko Arase
//
// URL: http://www.d-project.com/
//
// Licensed under the MIT license:
// http://www.opensource.org/licenses/mit-license.php
//
// The word "QR Code" is registered trademark of
// DENSO WAVE INCORPORATED
// http://www.denso-wave.com/qrcode/faqpatent-e.html
//
//---------------------------------------------------------------------
function QR8bitByte(data) {
this.mode = QRMode.MODE_8BIT_BYTE;
this.data = data;
this.parsedData = [];
// Added to support UTF-8 Characters
for (var i = 0, l = this.data.length; i < l; i++) {
var byteArray = [];
var code = this.data.charCodeAt(i);
if (code > 0x10000) {
byteArray[0] = 0xF0 | ((code & 0x1C0000) >>> 18);
byteArray[1] = 0x80 | ((code & 0x3F000) >>> 12);
byteArray[2] = 0x80 | ((code & 0xFC0) >>> 6);
byteArray[3] = 0x80 | (code & 0x3F);
} else if (code > 0x800) {
byteArray[0] = 0xE0 | ((code & 0xF000) >>> 12);
byteArray[1] = 0x80 | ((code & 0xFC0) >>> 6);
byteArray[2] = 0x80 | (code & 0x3F);
} else if (code > 0x80) {
byteArray[0] = 0xC0 | ((code & 0x7C0) >>> 6);
byteArray[1] = 0x80 | (code & 0x3F);
} else {
byteArray[0] = code;
}
this.parsedData.push(byteArray);
}
this.parsedData = Array.prototype.concat.apply([], this.parsedData);
if (this.parsedData.length != this.data.length) {
this.parsedData.unshift(191);
this.parsedData.unshift(187);
this.parsedData.unshift(239);
}
}
QR8bitByte.prototype = {
getLength: function (buffer) {
return this.parsedData.length;
},
write: function (buffer) {
for (var i = 0, l = this.parsedData.length; i < l; i++) {
buffer.put(this.parsedData[i], 8);
}
}
};
function QRCodeModel(typeNumber, errorCorrectLevel) {
this.typeNumber = typeNumber;
this.errorCorrectLevel = errorCorrectLevel;
this.modules = null;
this.moduleCount = 0;
this.dataCache = null;
this.dataList = [];
}
QRCodeModel.prototype = {
addData: function (data) { var newData = new QR8bitByte(data); this.dataList.push(newData); this.dataCache = null; }, isDark: function (row, col) {
if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) { throw new Error(row + "," + col); }
return this.modules[row][col];
}, getModuleCount: function () { return this.moduleCount; }, make: function () { this.makeImpl(false, this.getBestMaskPattern()); }, makeImpl: function (test, maskPattern) {
this.moduleCount = this.typeNumber * 4 + 17; this.modules = new Array(this.moduleCount); for (var row = 0; row < this.moduleCount; row++) { this.modules[row] = new Array(this.moduleCount); for (var col = 0; col < this.moduleCount; col++) { this.modules[row][col] = null; } }
this.setupPositionProbePattern(0, 0); this.setupPositionProbePattern(this.moduleCount - 7, 0); this.setupPositionProbePattern(0, this.moduleCount - 7); this.setupPositionAdjustPattern(); this.setupTimingPattern(); this.setupTypeInfo(test, maskPattern); if (this.typeNumber >= 7) { this.setupTypeNumber(test); }
if (this.dataCache == null) { this.dataCache = QRCodeModel.createData(this.typeNumber, this.errorCorrectLevel, this.dataList); }
this.mapData(this.dataCache, maskPattern);
}, setupPositionProbePattern: function (row, col) { for (var r = -1; r <= 7; r++) { if (row + r <= -1 || this.moduleCount <= row + r) continue; for (var c = -1; c <= 7; c++) { if (col + c <= -1 || this.moduleCount <= col + c) continue; if ((0 <= r && r <= 6 && (c == 0 || c == 6)) || (0 <= c && c <= 6 && (r == 0 || r == 6)) || (2 <= r && r <= 4 && 2 <= c && c <= 4)) { this.modules[row + r][col + c] = true; } else { this.modules[row + r][col + c] = false; } } } }, getBestMaskPattern: function () {
var minLostPoint = 0; var pattern = 0; for (var i = 0; i < 8; i++) { this.makeImpl(true, i); var lostPoint = QRUtil.getLostPoint(this); if (i == 0 || minLostPoint > lostPoint) { minLostPoint = lostPoint; pattern = i; } }
return pattern;
}, createMovieClip: function (target_mc, instance_name, depth) {
var qr_mc = target_mc.createEmptyMovieClip(instance_name, depth); var cs = 1; this.make(); for (var row = 0; row < this.modules.length; row++) { var y = row * cs; for (var col = 0; col < this.modules[row].length; col++) { var x = col * cs; var dark = this.modules[row][col]; if (dark) { qr_mc.beginFill(0, 100); qr_mc.moveTo(x, y); qr_mc.lineTo(x + cs, y); qr_mc.lineTo(x + cs, y + cs); qr_mc.lineTo(x, y + cs); qr_mc.endFill(); } } }
return qr_mc;
}, setupTimingPattern: function () {
for (var r = 8; r < this.moduleCount - 8; r++) {
if (this.modules[r][6] != null) { continue; }
this.modules[r][6] = (r % 2 == 0);
}
for (var c = 8; c < this.moduleCount - 8; c++) {
if (this.modules[6][c] != null) { continue; }
this.modules[6][c] = (c % 2 == 0);
}
}, setupPositionAdjustPattern: function () {
var pos = QRUtil.getPatternPosition(this.typeNumber); for (var i = 0; i < pos.length; i++) {
for (var j = 0; j < pos.length; j++) {
var row = pos[i]; var col = pos[j]; if (this.modules[row][col] != null) { continue; }
for (var r = -2; r <= 2; r++) { for (var c = -2; c <= 2; c++) { if (r == -2 || r == 2 || c == -2 || c == 2 || (r == 0 && c == 0)) { this.modules[row + r][col + c] = true; } else { this.modules[row + r][col + c] = false; } } }
}
}
}, setupTypeNumber: function (test) {
var bits = QRUtil.getBCHTypeNumber(this.typeNumber); for (var i = 0; i < 18; i++) { var mod = (!test && ((bits >> i) & 1) == 1); this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod; }
for (var i = 0; i < 18; i++) { var mod = (!test && ((bits >> i) & 1) == 1); this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod; }
}, setupTypeInfo: function (test, maskPattern) {
var data = (this.errorCorrectLevel << 3) | maskPattern; var bits = QRUtil.getBCHTypeInfo(data); for (var i = 0; i < 15; i++) { var mod = (!test && ((bits >> i) & 1) == 1); if (i < 6) { this.modules[i][8] = mod; } else if (i < 8) { this.modules[i + 1][8] = mod; } else { this.modules[this.moduleCount - 15 + i][8] = mod; } }
for (var i = 0; i < 15; i++) { var mod = (!test && ((bits >> i) & 1) == 1); if (i < 8) { this.modules[8][this.moduleCount - i - 1] = mod; } else if (i < 9) { this.modules[8][15 - i - 1 + 1] = mod; } else { this.modules[8][15 - i - 1] = mod; } }
this.modules[this.moduleCount - 8][8] = (!test);
}, mapData: function (data, maskPattern) {
var inc = -1; var row = this.moduleCount - 1; var bitIndex = 7; var byteIndex = 0; for (var col = this.moduleCount - 1; col > 0; col -= 2) {
if (col == 6) col--; while (true) {
for (var c = 0; c < 2; c++) {
if (this.modules[row][col - c] == null) {
var dark = false; if (byteIndex < data.length) { dark = (((data[byteIndex] >>> bitIndex) & 1) == 1); }
var mask = QRUtil.getMask(maskPattern, row, col - c); if (mask) { dark = !dark; }
this.modules[row][col - c] = dark; bitIndex--; if (bitIndex == -1) { byteIndex++; bitIndex = 7; }
}
}
row += inc; if (row < 0 || this.moduleCount <= row) { row -= inc; inc = -inc; break; }
}
}
}
}; QRCodeModel.PAD0 = 0xEC; QRCodeModel.PAD1 = 0x11; QRCodeModel.createData = function (typeNumber, errorCorrectLevel, dataList) {
var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel); var buffer = new QRBitBuffer(); for (var i = 0; i < dataList.length; i++) { var data = dataList[i]; buffer.put(data.mode, 4); buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber)); data.write(buffer); }
var totalDataCount = 0; for (var i = 0; i < rsBlocks.length; i++) { totalDataCount += rsBlocks[i].dataCount; }
if (buffer.getLengthInBits() > totalDataCount * 8) {
throw new Error("code length overflow. ("
+ buffer.getLengthInBits()
+ ">"
+ totalDataCount * 8
+ ")");
}
if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) { buffer.put(0, 4); }
while (buffer.getLengthInBits() % 8 != 0) { buffer.putBit(false); }
while (true) {
if (buffer.getLengthInBits() >= totalDataCount * 8) { break; }
buffer.put(QRCodeModel.PAD0, 8); if (buffer.getLengthInBits() >= totalDataCount * 8) { break; }
buffer.put(QRCodeModel.PAD1, 8);
}
return QRCodeModel.createBytes(buffer, rsBlocks);
}; QRCodeModel.createBytes = function (buffer, rsBlocks) {
var offset = 0; var maxDcCount = 0; var maxEcCount = 0; var dcdata = new Array(rsBlocks.length); var ecdata = new Array(rsBlocks.length); for (var r = 0; r < rsBlocks.length; r++) {
var dcCount = rsBlocks[r].dataCount; var ecCount = rsBlocks[r].totalCount - dcCount; maxDcCount = Math.max(maxDcCount, dcCount); maxEcCount = Math.max(maxEcCount, ecCount); dcdata[r] = new Array(dcCount); for (var i = 0; i < dcdata[r].length; i++) { dcdata[r][i] = 0xff & buffer.buffer[i + offset]; }
offset += dcCount; var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount); var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1); var modPoly = rawPoly.mod(rsPoly); ecdata[r] = new Array(rsPoly.getLength() - 1); for (var i = 0; i < ecdata[r].length; i++) { var modIndex = i + modPoly.getLength() - ecdata[r].length; ecdata[r][i] = (modIndex >= 0) ? modPoly.get(modIndex) : 0; }
}
var totalCodeCount = 0; for (var i = 0; i < rsBlocks.length; i++) { totalCodeCount += rsBlocks[i].totalCount; }
var data = new Array(totalCodeCount); var index = 0; for (var i = 0; i < maxDcCount; i++) { for (var r = 0; r < rsBlocks.length; r++) { if (i < dcdata[r].length) { data[index++] = dcdata[r][i]; } } }
for (var i = 0; i < maxEcCount; i++) { for (var r = 0; r < rsBlocks.length; r++) { if (i < ecdata[r].length) { data[index++] = ecdata[r][i]; } } }
return data;
}; var QRMode = { MODE_NUMBER: 1 << 0, MODE_ALPHA_NUM: 1 << 1, MODE_8BIT_BYTE: 1 << 2, MODE_KANJI: 1 << 3 }; var QRErrorCorrectLevel = { L: 1, M: 0, Q: 3, H: 2 }; var QRMaskPattern = { PATTERN000: 0, PATTERN001: 1, PATTERN010: 2, PATTERN011: 3, PATTERN100: 4, PATTERN101: 5, PATTERN110: 6, PATTERN111: 7 }; var QRUtil = {
PATTERN_POSITION_TABLE: [[], [6, 18], [6, 22], [6, 26], [6, 30], [6, 34], [6, 22, 38], [6, 24, 42], [6, 26, 46], [6, 28, 50], [6, 30, 54], [6, 32, 58], [6, 34, 62], [6, 26, 46, 66], [6, 26, 48, 70], [6, 26, 50, 74], [6, 30, 54, 78], [6, 30, 56, 82], [6, 30, 58, 86], [6, 34, 62, 90], [6, 28, 50, 72, 94], [6, 26, 50, 74, 98], [6, 30, 54, 78, 102], [6, 28, 54, 80, 106], [6, 32, 58, 84, 110], [6, 30, 58, 86, 114], [6, 34, 62, 90, 118], [6, 26, 50, 74, 98, 122], [6, 30, 54, 78, 102, 126], [6, 26, 52, 78, 104, 130], [6, 30, 56, 82, 108, 134], [6, 34, 60, 86, 112, 138], [6, 30, 58, 86, 114, 142], [6, 34, 62, 90, 118, 146], [6, 30, 54, 78, 102, 126, 150], [6, 24, 50, 76, 102, 128, 154], [6, 28, 54, 80, 106, 132, 158], [6, 32, 58, 84, 110, 136, 162], [6, 26, 54, 82, 110, 138, 166], [6, 30, 58, 86, 114, 142, 170]], G15: (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0), G18: (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0), G15_MASK: (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1), getBCHTypeInfo: function (data) {
var d = data << 10; while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) { d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15))); }
return ((data << 10) | d) ^ QRUtil.G15_MASK;
}, getBCHTypeNumber: function (data) {
var d = data << 12; while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) { d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18))); }
return (data << 12) | d;
}, getBCHDigit: function (data) {
var digit = 0; while (data != 0) { digit++; data >>>= 1; }
return digit;
}, getPatternPosition: function (typeNumber) { return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1]; }, getMask: function (maskPattern, i, j) { switch (maskPattern) { case QRMaskPattern.PATTERN000: return (i + j) % 2 == 0; case QRMaskPattern.PATTERN001: return i % 2 == 0; case QRMaskPattern.PATTERN010: return j % 3 == 0; case QRMaskPattern.PATTERN011: return (i + j) % 3 == 0; case QRMaskPattern.PATTERN100: return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0; case QRMaskPattern.PATTERN101: return (i * j) % 2 + (i * j) % 3 == 0; case QRMaskPattern.PATTERN110: return ((i * j) % 2 + (i * j) % 3) % 2 == 0; case QRMaskPattern.PATTERN111: return ((i * j) % 3 + (i + j) % 2) % 2 == 0; default: throw new Error("bad maskPattern:" + maskPattern); } }, getErrorCorrectPolynomial: function (errorCorrectLength) {
var a = new QRPolynomial([1], 0); for (var i = 0; i < errorCorrectLength; i++) { a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0)); }
return a;
}, getLengthInBits: function (mode, type) { if (1 <= type && type < 10) { switch (mode) { case QRMode.MODE_NUMBER: return 10; case QRMode.MODE_ALPHA_NUM: return 9; case QRMode.MODE_8BIT_BYTE: return 8; case QRMode.MODE_KANJI: return 8; default: throw new Error("mode:" + mode); } } else if (type < 27) { switch (mode) { case QRMode.MODE_NUMBER: return 12; case QRMode.MODE_ALPHA_NUM: return 11; case QRMode.MODE_8BIT_BYTE: return 16; case QRMode.MODE_KANJI: return 10; default: throw new Error("mode:" + mode); } } else if (type < 41) { switch (mode) { case QRMode.MODE_NUMBER: return 14; case QRMode.MODE_ALPHA_NUM: return 13; case QRMode.MODE_8BIT_BYTE: return 16; case QRMode.MODE_KANJI: return 12; default: throw new Error("mode:" + mode); } } else { throw new Error("type:" + type); } }, getLostPoint: function (qrCode) {
var moduleCount = qrCode.getModuleCount(); var lostPoint = 0; for (var row = 0; row < moduleCount; row++) {
for (var col = 0; col < moduleCount; col++) {
var sameCount = 0; var dark = qrCode.isDark(row, col); for (var r = -1; r <= 1; r++) {
if (row + r < 0 || moduleCount <= row + r) { continue; }
for (var c = -1; c <= 1; c++) {
if (col + c < 0 || moduleCount <= col + c) { continue; }
if (r == 0 && c == 0) { continue; }
if (dark == qrCode.isDark(row + r, col + c)) { sameCount++; }
}
}
if (sameCount > 5) { lostPoint += (3 + sameCount - 5); }
}
}
for (var row = 0; row < moduleCount - 1; row++) { for (var col = 0; col < moduleCount - 1; col++) { var count = 0; if (qrCode.isDark(row, col)) count++; if (qrCode.isDark(row + 1, col)) count++; if (qrCode.isDark(row, col + 1)) count++; if (qrCode.isDark(row + 1, col + 1)) count++; if (count == 0 || count == 4) { lostPoint += 3; } } }
for (var row = 0; row < moduleCount; row++) { for (var col = 0; col < moduleCount - 6; col++) { if (qrCode.isDark(row, col) && !qrCode.isDark(row, col + 1) && qrCode.isDark(row, col + 2) && qrCode.isDark(row, col + 3) && qrCode.isDark(row, col + 4) && !qrCode.isDark(row, col + 5) && qrCode.isDark(row, col + 6)) { lostPoint += 40; } } }
for (var col = 0; col < moduleCount; col++) { for (var row = 0; row < moduleCount - 6; row++) { if (qrCode.isDark(row, col) && !qrCode.isDark(row + 1, col) && qrCode.isDark(row + 2, col) && qrCode.isDark(row + 3, col) && qrCode.isDark(row + 4, col) && !qrCode.isDark(row + 5, col) && qrCode.isDark(row + 6, col)) { lostPoint += 40; } } }
var darkCount = 0; for (var col = 0; col < moduleCount; col++) { for (var row = 0; row < moduleCount; row++) { if (qrCode.isDark(row, col)) { darkCount++; } } }
var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5; lostPoint += ratio * 10; return lostPoint;
}
}; var QRMath = {
glog: function (n) {
if (n < 1) { throw new Error("glog(" + n + ")"); }
return QRMath.LOG_TABLE[n];
}, gexp: function (n) {
while (n < 0) { n += 255; }
while (n >= 256) { n -= 255; }
return QRMath.EXP_TABLE[n];
}, EXP_TABLE: new Array(256), LOG_TABLE: new Array(256)
}; for (var i = 0; i < 8; i++) { QRMath.EXP_TABLE[i] = 1 << i; }
for (var i = 8; i < 256; i++) { QRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4] ^ QRMath.EXP_TABLE[i - 5] ^ QRMath.EXP_TABLE[i - 6] ^ QRMath.EXP_TABLE[i - 8]; }
for (var i = 0; i < 255; i++) { QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i; }
function QRPolynomial(num, shift) {
if (num.length == undefined) { throw new Error(num.length + "/" + shift); }
var offset = 0; while (offset < num.length && num[offset] == 0) { offset++; }
this.num = new Array(num.length - offset + shift); for (var i = 0; i < num.length - offset; i++) { this.num[i] = num[i + offset]; }
}
QRPolynomial.prototype = {
get: function (index) { return this.num[index]; }, getLength: function () { return this.num.length; }, multiply: function (e) {
var num = new Array(this.getLength() + e.getLength() - 1); for (var i = 0; i < this.getLength(); i++) { for (var j = 0; j < e.getLength(); j++) { num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i)) + QRMath.glog(e.get(j))); } }
return new QRPolynomial(num, 0);
}, mod: function (e) {
if (this.getLength() - e.getLength() < 0) { return this; }
var ratio = QRMath.glog(this.get(0)) - QRMath.glog(e.get(0)); var num = new Array(this.getLength()); for (var i = 0; i < this.getLength(); i++) { num[i] = this.get(i); }
for (var i = 0; i < e.getLength(); i++) { num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio); }
return new QRPolynomial(num, 0).mod(e);
}
}; function QRRSBlock(totalCount, dataCount) { this.totalCount = totalCount; this.dataCount = dataCount; }
QRRSBlock.RS_BLOCK_TABLE = [[1, 26, 19], [1, 26, 16], [1, 26, 13], [1, 26, 9], [1, 44, 34], [1, 44, 28], [1, 44, 22], [1, 44, 16], [1, 70, 55], [1, 70, 44], [2, 35, 17], [2, 35, 13], [1, 100, 80], [2, 50, 32], [2, 50, 24], [4, 25, 9], [1, 134, 108], [2, 67, 43], [2, 33, 15, 2, 34, 16], [2, 33, 11, 2, 34, 12], [2, 86, 68], [4, 43, 27], [4, 43, 19], [4, 43, 15], [2, 98, 78], [4, 49, 31], [2, 32, 14, 4, 33, 15], [4, 39, 13, 1, 40, 14], [2, 121, 97], [2, 60, 38, 2, 61, 39], [4, 40, 18, 2, 41, 19], [4, 40, 14, 2, 41, 15], [2, 146, 116], [3, 58, 36, 2, 59, 37], [4, 36, 16, 4, 37, 17], [4, 36, 12, 4, 37, 13], [2, 86, 68, 2, 87, 69], [4, 69, 43, 1, 70, 44], [6, 43, 19, 2, 44, 20], [6, 43, 15, 2, 44, 16], [4, 101, 81], [1, 80, 50, 4, 81, 51], [4, 50, 22, 4, 51, 23], [3, 36, 12, 8, 37, 13], [2, 116, 92, 2, 117, 93], [6, 58, 36, 2, 59, 37], [4, 46, 20, 6, 47, 21], [7, 42, 14, 4, 43, 15], [4, 133, 107], [8, 59, 37, 1, 60, 38], [8, 44, 20, 4, 45, 21], [12, 33, 11, 4, 34, 12], [3, 145, 115, 1, 146, 116], [4, 64, 40, 5, 65, 41], [11, 36, 16, 5, 37, 17], [11, 36, 12, 5, 37, 13], [5, 109, 87, 1, 110, 88], [5, 65, 41, 5, 66, 42], [5, 54, 24, 7, 55, 25], [11, 36, 12], [5, 122, 98, 1, 123, 99], [7, 73, 45, 3, 74, 46], [15, 43, 19, 2, 44, 20], [3, 45, 15, 13, 46, 16], [1, 135, 107, 5, 136, 108], [10, 74, 46, 1, 75, 47], [1, 50, 22, 15, 51, 23], [2, 42, 14, 17, 43, 15], [5, 150, 120, 1, 151, 121], [9, 69, 43, 4, 70, 44], [17, 50, 22, 1, 51, 23], [2, 42, 14, 19, 43, 15], [3, 141, 113, 4, 142, 114], [3, 70, 44, 11, 71, 45], [17, 47, 21, 4, 48, 22], [9, 39, 13, 16, 40, 14], [3, 135, 107, 5, 136, 108], [3, 67, 41, 13, 68, 42], [15, 54, 24, 5, 55, 25], [15, 43, 15, 10, 44, 16], [4, 144, 116, 4, 145, 117], [17, 68, 42], [17, 50, 22, 6, 51, 23], [19, 46, 16, 6, 47, 17], [2, 139, 111, 7, 140, 112], [17, 74, 46], [7, 54, 24, 16, 55, 25], [34, 37, 13], [4, 151, 121, 5, 152, 122], [4, 75, 47, 14, 76, 48], [11, 54, 24, 14, 55, 25], [16, 45, 15, 14, 46, 16], [6, 147, 117, 4, 148, 118], [6, 73, 45, 14, 74, 46], [11, 54, 24, 16, 55, 25], [30, 46, 16, 2, 47, 17], [8, 132, 106, 4, 133, 107], [8, 75, 47, 13, 76, 48], [7, 54, 24, 22, 55, 25], [22, 45, 15, 13, 46, 16], [10, 142, 114, 2, 143, 115], [19, 74, 46, 4, 75, 47], [28, 50, 22, 6, 51, 23], [33, 46, 16, 4, 47, 17], [8, 152, 122, 4, 153, 123], [22, 73, 45, 3, 74, 46], [8, 53, 23, 26, 54, 24], [12, 45, 15, 28, 46, 16], [3, 147, 117, 10, 148, 118], [3, 73, 45, 23, 74, 46], [4, 54, 24, 31, 55, 25], [11, 45, 15, 31, 46, 16], [7, 146, 116, 7, 147, 117], [21, 73, 45, 7, 74, 46], [1, 53, 23, 37, 54, 24], [19, 45, 15, 26, 46, 16], [5, 145, 115, 10, 146, 116], [19, 75, 47, 10, 76, 48], [15, 54, 24, 25, 55, 25], [23, 45, 15, 25, 46, 16], [13, 145, 115, 3, 146, 116], [2, 74, 46, 29, 75, 47], [42, 54, 24, 1, 55, 25], [23, 45, 15, 28, 46, 16], [17, 145, 115], [10, 74, 46, 23, 75, 47], [10, 54, 24, 35, 55, 25], [19, 45, 15, 35, 46, 16], [17, 145, 115, 1, 146, 116], [14, 74, 46, 21, 75, 47], [29, 54, 24, 19, 55, 25], [11, 45, 15, 46, 46, 16], [13, 145, 115, 6, 146, 116], [14, 74, 46, 23, 75, 47], [44, 54, 24, 7, 55, 25], [59, 46, 16, 1, 47, 17], [12, 151, 121, 7, 152, 122], [12, 75, 47, 26, 76, 48], [39, 54, 24, 14, 55, 25], [22, 45, 15, 41, 46, 16], [6, 151, 121, 14, 152, 122], [6, 75, 47, 34, 76, 48], [46, 54, 24, 10, 55, 25], [2, 45, 15, 64, 46, 16], [17, 152, 122, 4, 153, 123], [29, 74, 46, 14, 75, 47], [49, 54, 24, 10, 55, 25], [24, 45, 15, 46, 46, 16], [4, 152, 122, 18, 153, 123], [13, 74, 46, 32, 75, 47], [48, 54, 24, 14, 55, 25], [42, 45, 15, 32, 46, 16], [20, 147, 117, 4, 148, 118], [40, 75, 47, 7, 76, 48], [43, 54, 24, 22, 55, 25], [10, 45, 15, 67, 46, 16], [19, 148, 118, 6, 149, 119], [18, 75, 47, 31, 76, 48], [34, 54, 24, 34, 55, 25], [20, 45, 15, 61, 46, 16]]; QRRSBlock.getRSBlocks = function (typeNumber, errorCorrectLevel) {
var rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel); if (rsBlock == undefined) { throw new Error("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + errorCorrectLevel); }
var length = rsBlock.length / 3; var list = []; for (var i = 0; i < length; i++) { var count = rsBlock[i * 3 + 0]; var totalCount = rsBlock[i * 3 + 1]; var dataCount = rsBlock[i * 3 + 2]; for (var j = 0; j < count; j++) { list.push(new QRRSBlock(totalCount, dataCount)); } }
return list;
}; QRRSBlock.getRsBlockTable = function (typeNumber, errorCorrectLevel) { switch (errorCorrectLevel) { case QRErrorCorrectLevel.L: return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0]; case QRErrorCorrectLevel.M: return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1]; case QRErrorCorrectLevel.Q: return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2]; case QRErrorCorrectLevel.H: return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3]; default: return undefined; } }; function QRBitBuffer() { this.buffer = []; this.length = 0; }
QRBitBuffer.prototype = {
get: function (index) { var bufIndex = Math.floor(index / 8); return ((this.buffer[bufIndex] >>> (7 - index % 8)) & 1) == 1; }, put: function (num, length) { for (var i = 0; i < length; i++) { this.putBit(((num >>> (length - i - 1)) & 1) == 1); } }, getLengthInBits: function () { return this.length; }, putBit: function (bit) {
var bufIndex = Math.floor(this.length / 8); if (this.buffer.length <= bufIndex) { this.buffer.push(0); }
if (bit) { this.buffer[bufIndex] |= (0x80 >>> (this.length % 8)); }
this.length++;
}
}; var QRCodeLimitLength = [[17, 14, 11, 7], [32, 26, 20, 14], [53, 42, 32, 24], [78, 62, 46, 34], [106, 84, 60, 44], [134, 106, 74, 58], [154, 122, 86, 64], [192, 152, 108, 84], [230, 180, 130, 98], [271, 213, 151, 119], [321, 251, 177, 137], [367, 287, 203, 155], [425, 331, 241, 177], [458, 362, 258, 194], [520, 412, 292, 220], [586, 450, 322, 250], [644, 504, 364, 280], [718, 560, 394, 310], [792, 624, 442, 338], [858, 666, 482, 382], [929, 711, 509, 403], [1003, 779, 565, 439], [1091, 857, 611, 461], [1171, 911, 661, 511], [1273, 997, 715, 535], [1367, 1059, 751, 593], [1465, 1125, 805, 625], [1528, 1190, 868, 658], [1628, 1264, 908, 698], [1732, 1370, 982, 742], [1840, 1452, 1030, 790], [1952, 1538, 1112, 842], [2068, 1628, 1168, 898], [2188, 1722, 1228, 958], [2303, 1809, 1283, 983], [2431, 1911, 1351, 1051], [2563, 1989, 1423, 1093], [2699, 2099, 1499, 1139], [2809, 2213, 1579, 1219], [2953, 2331, 1663, 1273]];
function _isSupportCanvas() {
return typeof CanvasRenderingContext2D != "undefined";
}
// android 2.x doesn't support Data-URI spec
function _getAndroid() {
var android = false;
var sAgent = navigator.userAgent;
if (/android/i.test(sAgent)) { // android
android = true;
var aMat = sAgent.toString().match(/android ([0-9]\.[0-9])/i);
if (aMat && aMat[1]) {
android = parseFloat(aMat[1]);
}
}
return android;
}
var svgDrawer = (function () {
var Drawing = function (el, htOption) {
this._el = el;
this._htOption = htOption;
};
Drawing.prototype.draw = function (oQRCode) {
var _htOption = this._htOption;
var _el = this._el;
var nCount = oQRCode.getModuleCount();
var nWidth = Math.floor(_htOption.width / nCount);
var nHeight = Math.floor(_htOption.height / nCount);
this.clear();
function makeSVG(tag, attrs) {
var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
for (var k in attrs)
if (attrs.hasOwnProperty(k)) el.setAttribute(k, attrs[k]);
return el;
}
var svg = makeSVG("svg", { 'viewBox': '0 0 ' + String(nCount) + " " + String(nCount), 'width': '100%', 'height': '100%', 'fill': _htOption.colorLight });
svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
_el.appendChild(svg);
svg.appendChild(makeSVG("rect", { "fill": _htOption.colorLight, "width": "100%", "height": "100%" }));
svg.appendChild(makeSVG("rect", { "fill": _htOption.colorDark, "width": "1", "height": "1", "id": "template" }));
for (var row = 0; row < nCount; row++) {
for (var col = 0; col < nCount; col++) {
if (oQRCode.isDark(row, col)) {
var child = makeSVG("use", { "x": String(col), "y": String(row) });
child.setAttributeNS("http://www.w3.org/1999/xlink", "href", "#template")
svg.appendChild(child);
}
}
}
};
Drawing.prototype.clear = function () {
while (this._el.hasChildNodes())
this._el.removeChild(this._el.lastChild);
};
return Drawing;
})();
var useSVG = document.documentElement.tagName.toLowerCase() === "svg";
// Drawing in DOM by using Table tag
var Drawing = useSVG ? svgDrawer : !_isSupportCanvas() ? (function () {
var Drawing = function (el, htOption) {
this._el = el;
this._htOption = htOption;
};
/**
* Draw the QRCode
*
* @param {QRCode} oQRCode
*/
Drawing.prototype.draw = function (oQRCode) {
var _htOption = this._htOption;
var _el = this._el;
var nCount = oQRCode.getModuleCount();
var nWidth = Math.floor(_htOption.width / nCount);
var nHeight = Math.floor(_htOption.height / nCount);
var aHTML = ['
'];
for (var row = 0; row < nCount; row++) {
aHTML.push('');
for (var col = 0; col < nCount; col++) {
aHTML.push(' | ');
}
aHTML.push('
');
}
aHTML.push('
');
_el.innerHTML = aHTML.join('');
// Fix the margin values as real size.
var elTable = _el.childNodes[0];
var nLeftMarginTable = (_htOption.width - elTable.offsetWidth) / 2;
var nTopMarginTable = (_htOption.height - elTable.offsetHeight) / 2;
if (nLeftMarginTable > 0 && nTopMarginTable > 0) {
elTable.style.margin = nTopMarginTable + "px " + nLeftMarginTable + "px";
}
};
/**
* Clear the QRCode
*/
Drawing.prototype.clear = function () {
this._el.innerHTML = '';
};
return Drawing;
})() : (function () { // Drawing in Canvas
function _onMakeImage() {
this._elImage.src = this._elCanvas.toDataURL("image/png");
this._elImage.style.display = "block";
this._elCanvas.style.display = "none";
}
// Android 2.1 bug workaround
// http://code.google.com/p/android/issues/detail?id=5141
if (this._android && this._android <= 2.1) {
var factor = 1 / window.devicePixelRatio;
var drawImage = CanvasRenderingContext2D.prototype.drawImage;
CanvasRenderingContext2D.prototype.drawImage = function (image, sx, sy, sw, sh, dx, dy, dw, dh) {
if (("nodeName" in image) && /img/i.test(image.nodeName)) {
for (var i = arguments.length - 1; i >= 1; i--) {
arguments[i] = arguments[i] * factor;
}
} else if (typeof dw == "undefined") {
arguments[1] *= factor;
arguments[2] *= factor;
arguments[3] *= factor;
arguments[4] *= factor;
}
drawImage.apply(this, arguments);
};
}
/**
* Check whether the user's browser supports Data URI or not
*
* @private
* @param {Function} fSuccess Occurs if it supports Data URI
* @param {Function} fFail Occurs if it doesn't support Data URI
*/
function _safeSetDataURI(fSuccess, fFail) {
var self = this;
self._fFail = fFail;
self._fSuccess = fSuccess;
// Check it just once
if (self._bSupportDataURI === null) {
var el = document.createElement("img");
var fOnError = function () {
self._bSupportDataURI = false;
if (self._fFail) {
self._fFail.call(self);
}
};
var fOnSuccess = function () {
self._bSupportDataURI = true;
if (self._fSuccess) {
self._fSuccess.call(self);
}
};
el.onabort = fOnError;
el.onerror = fOnError;
el.onload = fOnSuccess;
el.src = "data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="; // the Image contains 1px data.
return;
} else if (self._bSupportDataURI === true && self._fSuccess) {
self._fSuccess.call(self);
} else if (self._bSupportDataURI === false && self._fFail) {
self._fFail.call(self);
}
};
/**
* Drawing QRCode by using canvas
*
* @constructor
* @param {HTMLElement} el
* @param {Object} htOption QRCode Options
*/
var Drawing = function (el, htOption) {
this._bIsPainted = false;
this._android = _getAndroid();
this._htOption = htOption;
this._elCanvas = document.createElement("canvas");
this._elCanvas.width = htOption.width;
this._elCanvas.height = htOption.height;
el.appendChild(this._elCanvas);
this._el = el;
this._oContext = this._elCanvas.getContext("2d");
this._bIsPainted = false;
this._elImage = document.createElement("img");
this._elImage.alt = "Scan me!";
this._elImage.style.display = "none";
this._el.appendChild(this._elImage);
this._bSupportDataURI = null;
};
/**
* Draw the QRCode
*
* @param {QRCode} oQRCode
*/
Drawing.prototype.draw = function (oQRCode) {
var _elImage = this._elImage;
var _oContext = this._oContext;
var _htOption = this._htOption;
var nCount = oQRCode.getModuleCount();
var nWidth = _htOption.width / nCount;
var nHeight = _htOption.height / nCount;
var nRoundedWidth = Math.round(nWidth);
var nRoundedHeight = Math.round(nHeight);
_elImage.style.display = "none";
this.clear();
for (var row = 0; row < nCount; row++) {
for (var col = 0; col < nCount; col++) {
var bIsDark = oQRCode.isDark(row, col);
var nLeft = col * nWidth;
var nTop = row * nHeight;
_oContext.strokeStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight;
_oContext.lineWidth = 1;
_oContext.fillStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight;
_oContext.fillRect(nLeft, nTop, nWidth, nHeight);
// 안티 앨리어싱 방지 처리
_oContext.strokeRect(
Math.floor(nLeft) + 0.5,
Math.floor(nTop) + 0.5,
nRoundedWidth,
nRoundedHeight
);
_oContext.strokeRect(
Math.ceil(nLeft) - 0.5,
Math.ceil(nTop) - 0.5,
nRoundedWidth,
nRoundedHeight
);
}
}
this._bIsPainted = true;
};
/**
* Make the image from Canvas if the browser supports Data URI.
*/
Drawing.prototype.makeImage = function () {
if (this._bIsPainted) {
_safeSetDataURI.call(this, _onMakeImage);
}
};
/**
* Return whether the QRCode is painted or not
*
* @return {Boolean}
*/
Drawing.prototype.isPainted = function () {
return this._bIsPainted;
};
/**
* Clear the QRCode
*/
Drawing.prototype.clear = function () {
this._oContext.clearRect(0, 0, this._elCanvas.width, this._elCanvas.height);
this._bIsPainted = false;
};
/**
* @private
* @param {Number} nNumber
*/
Drawing.prototype.round = function (nNumber) {
if (!nNumber) {
return nNumber;
}
return Math.floor(nNumber * 1000) / 1000;
};
return Drawing;
})();
/**
* Get the type by string length
*
* @private
* @param {String} sText
* @param {Number} nCorrectLevel
* @return {Number} type
*/
function _getTypeNumber(sText, nCorrectLevel) {
var nType = 1;
var length = _getUTF8Length(sText);
for (var i = 0, len = QRCodeLimitLength.length; i <= len; i++) {
var nLimit = 0;
switch (nCorrectLevel) {
case QRErrorCorrectLevel.L:
nLimit = QRCodeLimitLength[i][0];
break;
case QRErrorCorrectLevel.M:
nLimit = QRCodeLimitLength[i][1];
break;
case QRErrorCorrectLevel.Q:
nLimit = QRCodeLimitLength[i][2];
break;
case QRErrorCorrectLevel.H:
nLimit = QRCodeLimitLength[i][3];
break;
}
if (length <= nLimit) {
break;
} else {
nType++;
}
}
if (nType > QRCodeLimitLength.length) {
throw new Error("Too long data");
}
return nType;
}
function _getUTF8Length(sText) {
var replacedText = encodeURI(sText).toString().replace(/\%[0-9a-fA-F]{2}/g, 'a');
return replacedText.length + (replacedText.length != sText ? 3 : 0);
}
/**
* @class QRCode
* @constructor
* @example
* new QRCode(document.getElementById("test"), "http://jindo.dev.naver.com/collie");
*
* @example
* var oQRCode = new QRCode("test", {
* text : "http://naver.com",
* width : 128,
* height : 128
* });
*
* oQRCode.clear(); // Clear the QRCode.
* oQRCode.makeCode("http://map.naver.com"); // Re-create the QRCode.
*
* @param {HTMLElement|String} el target element or 'id' attribute of element.
* @param {Object|String} vOption
* @param {String} vOption.text QRCode link data
* @param {Number} [vOption.width=256]
* @param {Number} [vOption.height=256]
* @param {String} [vOption.colorDark="#000000"]
* @param {String} [vOption.colorLight="#ffffff"]
* @param {QRCode.CorrectLevel} [vOption.correctLevel=QRCode.CorrectLevel.H] [L|M|Q|H]
*/
QRCode = function (el, vOption) {
this._htOption = {
width: 256,
height: 256,
typeNumber: 4,
colorDark: "#000000",
colorLight: "#ffffff",
correctLevel: QRErrorCorrectLevel.H
};
if (typeof vOption === 'string') {
vOption = {
text: vOption
};
}
// Overwrites options
if (vOption) {
for (var i in vOption) {
this._htOption[i] = vOption[i];
}
}
if (typeof el == "string") {
el = document.getElementById(el);
}
if (this._htOption.useSVG) {
Drawing = svgDrawer;
}
this._android = _getAndroid();
this._el = el;
this._oQRCode = null;
this._oDrawing = new Drawing(this._el, this._htOption);
if (this._htOption.text) {
this.makeCode(this._htOption.text);
}
};
/**
* Make the QRCode
*
* @param {String} sText link data
*/
QRCode.prototype.makeCode = function (sText) {
this._oQRCode = new QRCodeModel(_getTypeNumber(sText, this._htOption.correctLevel), this._htOption.correctLevel);
this._oQRCode.addData(sText);
this._oQRCode.make();
this._el.title = sText;
this._oDrawing.draw(this._oQRCode);
this.makeImage();
};
/**
* Make the Image from Canvas element
* - It occurs automatically
* - Android below 3 doesn't support Data-URI spec.
*
* @private
*/
QRCode.prototype.makeImage = function () {
if (typeof this._oDrawing.makeImage == "function" && (!this._android || this._android >= 3)) {
this._oDrawing.makeImage();
}
};
/**
* Clear the QRCode
*/
QRCode.prototype.clear = function () {
this._oDrawing.clear();
};
/**
* @name QRCode.CorrectLevel
*/
QRCode.CorrectLevel = QRErrorCorrectLevel;
})();;
///
//#region 选择器区域
//var win = window;// doc = document;
//window.U.Json_ = window.$; //记录命名控件 //全局使用 解决jquery覆盖我们的选择器的问题。
/*下面的写法会导致程序在window.onload之前执行,为什么要在window.onload之前执行,如果非要执行,能否把所有要做window.onload之前执行的整合在一个文件?并列明必须先执行的理由?*/
/*
选择器前言
好处:
1、简化项目的代码
2、当我对系统的ocument.getElementById document.getElementsByTagName document.getElementsByClassName有奇异 觉得里面需要修改添加一些新的方法处理 可以统一处理
*/
//#region 创建元素
/*
*使用$$操作符简化编码长度。
*例:$$("div", { "style": { "cssText": "font-size:16px;float:left;line-height:33px;width:40%;margin:0px 0px 0px 15px;" }, "innerHTML": "文件名" }, Inner_J)
* @param {string} 元素的类型tagName 例如:"div"
* @param {object} 集合,类似 { "style": { "cssText": "font-size:16px;float:left;line-height:33px;width:40%;margin:0px 0px 0px 15px;" }, "innerHTML": "文件名" }
* @param {element} 所要追加的父亲元素,把第二个参数作为孩子节点追加到第三个参数。par代表父亲元素
* @param {element} 追加的位置,如果有此参数,则把创建的元素追加到此元素的前面。此元素必须为第三个参数的孩子节点。
*/
U.quickCreate = window.$$ = function (str, obj, parentel, child) { //创建基本元素元素
var i, _element;
//由于createDocumentFragment和createTextNode太长,可以通过简单的方式去创建
var _obj = {
"frag": "createDocumentFragment" //碎片元素
// "text": "createTextNode" //文本元素
};
//判断是否创建上面的元素方式
if (_obj[str]) {
_element = document[_obj[str]]();
}
//创建制定标签的元素
else {
_element = document.createElement(str);
}
//给元素添加属性
if (obj) {
U.selectEl(_element).addAttrArray(obj);
}
//如果存在父亲,则追加孩子节点。
if (parentel) {
//如果存在第四个参数,则追加到第四个参数的前面。否则,追加在最后面。
if (child) {
parentel.insertBefore(_element, child);
}
//追加到父亲元素的最后面
else {
parentel.appendChild(_element);
}
}
//返回创建的元素
return _element;
}
//#endregion
//#region 1473用的快速选择器 去除没有必要的功能 只保留简单的选择功能
/**
* 初始化编辑区域
*
* @param {string} 选择 首先我们会定义3个获取元素的方法代替系统的 document.getElementById document.getElementsByTagName document.getElementsByClassName
* @param {元素} 在元素下面搜索符合参数一的所有孩子节点
例一、$("#U_MD_D_H");找名为U_MD_D_H唯一id。
例二、$("div", UDKF):在元素UDKF下面搜索所有div元素。
例三:$(".className", UDKF) 在元素UDKF下面找classname等于classname的元素。不建议用,性能太低。
*/
$ = U.selectEl = function (name, el) {
//调用选择器的方法
return new U.select(name, el);
}
/**
* 初始化编辑区域
*
* @param {string} 选择的元素,例如"div"
* @param {document} 搜索的层次
* 返回值:数组 [elment,elment,element]
* var a=U.select("div.classname",body);
* var b=U.select("input,a)
*/
U.select = function (selector, el) { //定义类
//设置值
this.length = 0; //选择元素的总长度
this.context = el || document; //选择器的域(在哪个元素下面选,默认是document)
//获取元素选择
this.select(selector, el); //选择元素
}
U.select.EVENTS = []; //元素绑定事件存储的地方
/**
* 这里是选择器的方法集合
*
*/
U.select.prototype = {//原型对象使用
/**
* 定义选择器构造器
*
* @param {string} 选择特殊字符串 包含# & []
* @param {document} 搜索的层次
*/
select: function (name, el) { //选择器选择
var _selectel;
//如果是字符串说明用户要通过选择器找到字符串
if (U.UF.C.isString(name)) {
var _r = name.substring(0, 1), //获取特殊字符 . # 或者 ""
_n = name.substring(1, name.length), //获取标签名
_doc = el || document; //去除特殊字符后
//这里是判断获取
try { //这里利用基础的选择器选取数据
switch (_r) {
case "#": //根据id获取 因为id获取只能通过全局搜索 但是由于项目中有存在克隆的情况 会出现id不唯一的情况
if (_doc == document && U.UF.S.EN.test(_n)) {
_selectel = document.getElementById(_n);
}
break;
case ".": //根据className获取
if (U.UF.S.EN.test(_n)) {
_selectel = _doc.getElementsByClassName(_n);
}
break;
case "*":
//如果后面有输入id,那么找所有的媒体文件
if (U.UF.S.EN.test(_n)) {
_selectel = document[_n]; //获取媒体文件
if (!_selectel) { //如果没有找到说明不兼容
if (U.UF.CI.getBrowser().browser == "msie") { //ie得到媒体文件的方法
_selectel = document.getElementById(_n);
}
//非ie系列
else {
_selectel = document.embeds[_n];
}
}
}
//否则就是直接找指定元素下面的所有元素
else {
_selectel = _doc.getElementsByTagName("*");
}
break;
default: //标签的获取 //获取指定的元素
if (U.UF.S.EN.test(name)) {
_selectel = _doc.getElementsByTagName(name); //除去特殊字符的处理
}
break;
}
}
catch (e) {
}
//判断是否获取元素成功,如果上面简单的选择去不成功,那么就通过其他的选择器方案去获取
if (_selectel == null) {
_selectel = U.UF.CP.selectorElement(name, _doc); //其他选择的方式获取
}
}
//如果用户第一个参数传的是元素,那么就直接设置
else if (name) {
_selectel = name;
}
//添加元素到this里面
if (_selectel) {
this.addElement(_selectel);
}
return this;
},
/**
* 添加查找到的元素到this里
*
* @param {elements} 选择的元素数组
*/
addElement: function (els) {
//把所有获取出来的元素转化成数组,以便下面循环添加 U.UF.C.isElement(els) || els.length == null
if ((U.UF.C.isElement(els) || els.length == null) || els.toString() == "[object Window]") {
els = [els];
}
//循环所有的元素,把元素设置到this里面,这样用户获取到的元素集就能通过this[0]或者this[id]去获取了
for (var i = 0; i < els.length; i++) {
//如果元素存在的处理
this[i] = els[i];
//如果元素有id,那么给返回值添加一个id的处理,以便返回值中有以id作为key的返回值
if (els[i].id) {
this[els[i].id] = els[i];
}
this.length++; //没添加一个那么选择的元素的长度多一个
}
},
/**
* 在选择好的元素下面继续搜索子元素
*
* @param {string} 选择特殊字符串 包含# & []
* @param {number} 搜索的层次
*/
find: function (name, item) { //获取元素的后代
var i = item || 0, //由于选择选择出来的元素是数组,所以需要筛选出第几个需要获取子节点
_length = item + 1 || this.length, //选择元素的长度
_elements = new U.select(); //由于新选择了元素,那么实例化选择器
for (; i < _length; i++) {
_elements.select(name, this[i]); //重新选择添加处理
}
return _elements; //返回最后选择的结果
},
/**
* 当前元素前一个兄弟节点
*
* @param {string} 选择特殊字符串 包含# & []
* @param {number} 搜索的层次
*/
prev: function (item) {
var _selectel, //获取选择的元素
_selects = [], //所有选择的元素
i = item || 0, //由于选择选择出来的元素是数组,所以需要筛选出第几个需要获取子节点
_length = item + 1 || this.length, //选择元素的长度
_elements = new U.select(); //由于新选择了元素,那么实例化选择器
//循环的去获取每个元素的上级元素
for (; i < _length; i++) {
_selectel = this[i];
if (_selectel) {
//用do while去过滤文本节点,只找元素节点
do {
_selectel = _selectel.previousSibling;
}
while (_selectel && _selectel.nodeType !== 1)
}
//找到节点追加到数组里
if (_selectel) {
_selects.push(_selectel);
}
}
//把元素添加到_elements里,并返回到前台
_elements.addElement(_selects);
return _elements;
},
/**
* 当前元素之后第一个兄弟节点
*
* @param {string} 选择特殊字符串 包含# & []
* @param {number} 搜索的层次
*/
next: function (item) {
var _selectel, //获取选择的元素
_selects = [], //所有选择的元素
i = item || 0, //由于选择选择出来的元素是数组,所以需要筛选出第几个需要获取子节点
_length = item + 1 || this.length, //选择元素的长度
_elements = new U.select(); //由于新选择了元素,那么实例化选择器
//循环的去获取每个元素的上级元素
for (; i < _length; i++) {
_selectel = this[i];
if (_selectel) {
//用do while去过滤文本节点,只找元素节点
do {
_selectel = _selectel.nextSibling;
}
while (_selectel && _selectel.nodeType !== 1)
}
//找到节点追加到数组里
if (_selectel) {
_selects.push(_selectel);
}
}
//把元素添加到_elements里,并返回到前台
_elements.addElement(_selects);
return _elements;
},
/**
* 获取所有的子元素
*
* @param {number} 选择器结果里面的第几个
*/
Nodes: function (item) {
item = item || 0; //由于选择选择出来的元素是数组,所以需要筛选出第几个需要获取子节点
//直接返回所有的子节点
if (this[item]) {
this[item].childNodes;
}
;
},
/**
* 获取所有的子元素
*
* @param {number} 选择器结果里面的第几个
*/
Child: function (item) {//获取有效元素孩子节点
item = item || 0; //由于选择选择出来的元素是数组,所以需要筛选出第几个需要获取子节点
//如果选择的元素存在则获取子节点 通过U.UF.EL.getChildrenNoText 可以把 #text节点过滤
if (this[item]) {
return U.UF.EL.getChildrenNoText(this[item].childNodes)
}
},
/**
* 如果没有参数,则是查找自己的父亲,如果有参数,则查找符合条件的祖先元素。
* 如果UTF是数字n,则向上查找n层祖先。
* 如果UTF是属性,则查找符合条件的属性。
*
* @param {number} 选择器结果里面的第几个
*/
Parent: function (obj) {//获取上级父亲层
var _while,
_istrue,
_el = this[0];
obj = obj || 1; //如果没有条件,那么就是默认选取上一层的父亲
if (U.UF.C.isNumber(obj)) {
for (i = 0; i < obj; i++) {
if (_el) { //判断是否有选取
_el = _el.parentNode;
}
}
}
else {
//循环的向上寻找制定条件的元素,最大不超过document层
_while: while (_el && _el != document) {
_istrue = true;
//循环判断条件是否匹配
for (i in obj) {
//如果条件匹配
if (obj[i] != _el[i] && (!_el.getAttribute || _el.getAttribute(i) != obj[i])) {
_istrue = false;
break;
}
}
//如果全部条件符合,那么直接跳出
if (_istrue) {
break _while;
}
//继续向上找
else {
_el = _el.parentNode;
}
}
}
//返回找到的祖先层
return _el;
},
/**
* 获取所有的子元素
*
* @param {number} 选择器结果里面的第几个
*/
childs: function (item) {//获取孩子节点
return new U.select(this.Child(item));
},
/**
* 如果没有参数,则是查找自己的父亲,如果有参数,则查找符合条件的祖先元素。
* 如果UTF是数字n,则向上查找n层祖先。
* 如果UTF是属性,则查找符合条件的属性。
*
* @param {number} 选择器结果里面的第几个
*/
parentElement: function (obj, item) {//获取父亲节点
return new U.select(this.Parent(obj, item));
},
/**
* 克隆元素
*
* @param {boolean} 设置为 true,如果您需要克隆节点及其属性,以及后代, 设置为 false,如果您只需要克隆节点及其后代
* @param {number} 选择器结果里面的第几个
*/
clone: function (deep, item) { //克隆元素 UDOD, UDID, USE
var i = item || 0, //item 基本没有用
_returnarr = [], //返回的数据
_length = i + 1 || this.length; //克隆元素的长度
//循环克隆放入_returnarr里
for (; i < _length; i++) {
_returnarr.push(this[i].cloneNode(deep));
}
//返回选择器
return new U.select(_returnarr);
},
/**
* 把元素添加到制定的父亲层
*
* @param {element} 添加到哪个父亲层
* @param {number} 选择器结果里面的第几个
* @param {element} 添加到哪个元素的上面
*/
appendTo: function (parentel, item, childel) {//添加元素到制定的位置
var i = item || 0, //选择器结果里面的第几个
_length = item + 1 || this.length; //插入元素的长度
//循环条件元素
for (; i < _length; i++) {
//如果有子元素,就添加到这个子元素的前面
if (childel) {
parentel.insertBefore(this[i], childel);
}
//添加到最后面
else {
parentel.appendChild(this[i]);
}
}
return this;
},
/**
* 添加子元素
*
* @param {element} 需要追加的元素
* @param {number} 选择器结果里面的第几个
* @param {element} 添加到哪个元素的上面
*/
append: function (el, item, childel) {//插入元素
item = item || 0; //选择器结果里面的第几个
//如果有子元素,就添加到这个子元素的前面
if (childel) {
this[item].insertBefore(el, childel);
}
//添加到最后面
else {
this[item].appendChild(el);
}
return this;
},
/**
* 移除元素
*
* @param {boolean} 设置为 true,如果您需要克隆节点及其属性,以及后代, 设置为 false,如果您只需要克隆节点及其后代
* @param {number} 选择器结果里面的第几个
*/
remove: function (item) {
var i = item || 0, //选择器结果里面的第几个
_length = item != null ? item + 1 : this.length; //移除的数量
//循环移除
for (; i < _length; i++) {
//判断是否有上一级
if (this[i] && this[i].parentNode) {
this[i].parentNode.removeChild(this[i]); //移除
}
}
return this;
},
/**
* 元素居中
*
* @param {number} 选择器结果里面的第几个
*/
Center: function (item) { //元素居中
var i = item || 0, //选择器结果里面的第几个
_length = item + 1 || this.length; //居中弹出的数量
//循环弹出处理
for (; i < _length; i++) {
U.UF.F.windowTopCenter(this[i]); //居中弹出
}
return this;
},
/**
* 返回元素的大小和位置
*
* @param {number} 选择器结果里面的第几个
*/
getElementInfo: function (item) {
return U.UF.EL.getElementInfo(this[item || 0]);
},
/**
* 返回元素的大小和位置
*
* 设置单个Css属性传参说明
* @obj {string} 必填 css属性名
* @value {string} 必填 css属性对应的值
* @item {number} 选填 选择器结果里面的第几个
*
* 设置多个Css属性传参说明
* @obj {string} 必填 需设置的cssjson
* 形如:{width : '100px', height: '100px', 'backgroud-color': 'red'}
* @value {null} 占位传参 null
* @item {number} 选填 选择器结果里面的第几个
*/
css: function (obj, value, item) {//获取指定的css值
var i = item || 0, //选择第几个
_length = item + 1 || this.length, //长度
_isobject = U.UF.C.isObject(obj);
//如果是object,那么第二个参数就是item 所以这里的 value = item
if (_isobject) {
this.addAttrArray({ "style": obj }, value);
}
//如果第一个参数是strig类型那么value需要有值,如果有值那么就是设置,否则是获取css
else if (value != null) {
//循环的设置值
for (i; i < _length; i++) {
obj = U.UF.EL.styleConversion(obj); //由于用户这边会穿 text-align 这样的值 但是在css里面 该值为 textAlign改成了大写
try {
this[i].style[obj] = value;
} catch (e) { }
}
}
//获取css
else {
return U.UF.EL.getStyle(this[i], obj);
}
return this;
},
/**
* 添加classname
*
* @param {string} 移除的classname
*/
addClass: function (classname, item) { //添加Class
var i = item || 0, //选择第几个
_length = item + 1 || this.length; //长度
//循环给元素添加class值
for (; i < _length; i++) {
U.UF.EL.addClass(this[i], classname);
}
return this;
},
/**
* 移除classname
*
* @param {string} 移除的classname
*/
removeClass: function (classname, item) {//移除制定的class
var i = item || 0, //选择第几个
_length = item + 1 || this.length; //长度
//循环给元素移除classname
for (; i < _length; i++) {
U.UF.EL.removeClass(this[i], classname);
}
return this;
},
/**
* 判断元素是否有制定的class
*
* @param {string} classname
*/
hasClass: function (classname, item) {
item = item || 0;
return U.UF.EL.isHasClass(this[item], classname);
},
/**
* 判断元素是否有制定的class
*
* @param {string} classname
*/
attr: function (obj, value, item) { //添加属性
var j,
i, //选择第几个
_length, //长度
_isobject = U.UF.C.isObject(obj); //判断元素是否为对象
//如果是object,那么第二个参数就是item 所以这里的 value = item
if (_isobject) {
i = value || 0; //选择第几个
_length = value + 1 || this.length; //长度
//循环所有的元素添加至
for (; i < _length; i++) {
for (j in obj) {
U.UF.EL.addAttributes(this[i], j, obj[j]); //给元素添加属性
}
}
}
//如果第一个参数是strig类型那么value需要有值,如果有值那么就是设置,否则是获取css
else if (value != null) {
i = item || 0; //选择第几个
_length = item + 1 || this.length; //长度
//循环的设置值
for (i; i < _length; i++) {
U.UF.EL.addAttributes(this[i], obj, value); //给元素添加属性
}
}
//获取属性,
else {
return this[item || 0].getAttribute(obj);
}
return this;
},
/**
* 移除属性
*
* @param {string} classname
*/
rmAttr: function (name, item) { //移除属性
U.UF.EL.delAttributes(this[item || 0], name); //移除元素
return this;
},
/**
* 添加属性
*
* @param {string} classname
*/
addAttrArray: function (obj, item) {//赋值区域
var j, k,
_newcsstext,
_csstype,
_csstext = "", //csstext
i = item || 0, //选择第几个
_length = item + 1 || this.length; //长度
//循环的处理每个元素赋值
for (; i < _length; i++) {
//循环所有的属性
for (j in obj) {
//css的添加方式
if (j == "style") {
_csstext = "";
_newcsstext = obj[j]["cssText"];
for (k in obj[j]) {
_csstype = U.UF.EL.styleConversion(k, true); //把所有的cssText转成css-text,因为css在拼接的时候是以这种形式
//cssText的设置方式,添加一份新的csstext
if (_csstype == "css-text") {
continue;
}
//如果是其他普通样式的添加,那么就拼接
else if (k in this[i][j]) {
_csstext += _csstype + ":" + obj[j][k] + ";";
}
//自定义属性的设置,情况比较少,但是在做兼容方案的时候可能会用到
else {
this[i][j][k] = obj[j][k];
}
}
//如果需要设置cssText的处理
if (_newcsstext) {
_csstext = this[i][j]["cssText"] + ";" + _newcsstext + ";" + _csstext;
}
//如果是undefined或者是null这样不设置值的处理
else if (_newcsstext !== "") {
_csstext = this[i][j]["cssText"] + ";" + _csstext;
}
this[i][j]["cssText"] = _csstext;
}
//出css以外的添加方式 如 onclick事件赋值 classname赋值
else {
//如果是事件类型的,又是字符串类型,那么这里把它转化成函数
if (j.indexOf("on") == 0 && U.UF.C.isString(obj[j])) {
this[i][j] = new Function(obj[j]); //字符串转化成function
continue;
}
//&& "string".indexOf(U.UF.C.getType((_UVE = UDE[j]))) > -1
//如果是字符串,同时又是系统属性,那么通过setAttribute的方式设置属性,该方式设置属性可以让属性在网页调试模式下看到如
kk为自定义属性
else if (U.UF.C.isString(obj[j]) && U.UF.EL.isCustomAttributes(this[i], j)) {
//由于低版本的浏览器会报错,这里用try catch
try {
this[i].setAttribute(j, obj[j]);
}
catch (e) {
}
}
try {
this[i][j] = obj[j];
}
catch (e) { }
}
}
}
return this;
},
/**
* 隐藏元素
*
* @param {string} classname
*/
hide: function (item) {
this.css({ "display": "none" }, item);
},
/**
* 显示元素
*
* @param {string} classname
*/
show: function (item) { //显示元素
this.css({ "display": "block" }, item);
},
/**
* 获取长度
*
*/
width: function () {
return U.UF.EL.getElementRealWidth(this[0]);
},
/**
* 获取长度
*
*/
height: function () {
return U.UF.EL.getElementRealHeight(this[0]);
},
/**
* 鼠标移入的时候触发,由于onmouseover会出发多次 这里做兼容
*
* @param {string} classname
*/
mouseenter: function (cb, item) { //enter事件
//设置移入函数
this.addAttrArray({
"onmouseover": function () {
U.UF.EV.stopBubbleMouseOutOrOver(this, cb); //判断用户移入的时候出发元素,进行判断元素是否移入
}
}, item);
return this;
},
/**
* 鼠标移出的时候触发,由于onmouseout会出发多次 这里做兼容
*
* @param {string} classname
*/
mouseleave: function (cb, item) { //leave事件
//设置移入函数
this.addAttrArray({
"onmouseout": function () {
U.UF.EV.stopBubbleMouseOutOrOver(this, cb); //判断用户移入的时候出发元素,进行判断元素是否移入
}
}, item);
return this;
},
/**
* 鼠标移出的时候触发,由于onmouseout会出发多次 这里做兼容
*
* @param {string} classname
*/
gt: function (item) { //索引大于的元素
var i = item, //item 基本没有用
_returnarr = [], //返回的数据
_elements = new U.select(); //由于重新筛选数据,那么需要新建一个选择器
//循环筛选元素
for (; i < this.length; i++) {
_returnarr.push(this[i]);
}
//循环添加到this里面
_elements.addElement(_returnarr);
return _elements;
},
/**
* 鼠标移出的时候触发,由于onmouseout会出发多次 这里做兼容
*
* @param {string} classname
*/
lt: function (item) {
var i = 0, //item 基本没有用
_returnarr = []; //返回的数据
//循环筛选元素
for (; i < item; i++) {
_returnarr.push(this[i]);
}
//循环添加到this里面
return new U.select(_returnarr); //由于重新筛选数据,那么需要新建一个选择器
},
/**
* 元素事件绑定
*
* @param {string} classname
*/
bind: function (obj, value, item) {
var j,
i, //选择第几个
_length, //长度
_isobject = U.UF.C.isObject(obj); //判断元素是否为对象
//如果是object,那么第二个参数就是item 所以这里的 value = item
if (_isobject) {
i = value || 0; //选择第几个
_length = value + 1 || this.length; //长度
//循环所有的元素添加至
for (; i < _length; i++) {
for (j in obj) {
U.UF.EV.addElementEvent(j, this[i], obj[j]); //添加事件绑定
//添加事件
U.select.EVENTS.push({
element: this[i], //绑定事件
event: j, //事件
fun: obj[j] //函数
});
}
}
}
//如果第一个参数是strig类型那么value需要有值,如果有值那么就是设置,否则是获取css
else if (value != null) {
i = item || 0; //选择第几个
_length = item + 1 || this.length; //长度
//循环的设置值
for (i; i < _length; i++) {
U.UF.EV.addElementEvent(obj, this[i], value); //添加事件绑定
//添加事件
U.select.EVENTS.push({
element: this[i], //绑定事件
event: obj, //事件
fun: value //函数
});
}
}
return this;
},
/**
* 元素解除事件绑定
*
* @param {string} classname
*/
unbind: function (obj, value, item) { //事件绑定取消
var j,
i, //选择第几个
k,
_length, //长度
_isobject = U.UF.C.isObject(obj); //判断元素是否为对象
//如果是object,那么第二个参数就是item 所以这里的 value = item
if (_isobject) {
i = value || 0; //选择第几个
_length = value + 1 || this.length; //长度
//循环所有的元素添加至
for (; i < _length; i++) {
for (j in obj) {
U.UF.EV.delElementEvent(j, this[i], obj[j]); //删除事件绑定
for (k = 0; k < U.select.EVENTS.length; k++) {
if (U.select.EVENTS[k].element == this[i] && U.select.EVENTS[k].event == j && U.select.EVENTS[k].fun == obj[j]) {
U.select.EVENTS.splice(k, 1);
k--;
}
}
}
}
}
//如果第一个参数是strig类型那么value需要有值,如果有值那么就是设置,否则是获取css
else if (obj != null) {
i = item || 0; //选择第几个
_length = item + 1 || this.length; //长度
//循环的设置值
for (i; i < _length; i++) {
for (k = 0; k < U.select.EVENTS.length; k++) {
if (U.select.EVENTS[k].element == this[i] &&
U.select.EVENTS[k].event == obj &&
(value == null || U.select.EVENTS[k].fun == value)) {
U.UF.EV.delElementEvent(obj, this[i], U.select.EVENTS[k].fun); //添加事件绑定
U.select.EVENTS.splice(k, 1);
k--;
}
}
}
}
//如果没有传key和value去移除,那么就移除元素所有绑定的事件
else {
i = item || 0; //选择第几个
_length = item + 1 || this.length; //长度
for (i; i < _length; i++) {
for (k = 0; k < U.select.EVENTS.length; k++) {
if (U.select.EVENTS[k].element == this[i]) {
U.UF.EV.delElementEvent(U.select.EVENTS[k].event, this[i], U.select.EVENTS[k].fun); //添加事件绑定
U.select.EVENTS.splice(k, 1);
k--;
}
}
}
}
return this;
}
}
//#endregion
;
///
/*
一、此js主要扩展了String,Number,Array,Object,Guid,json,Date等七种数据类型,还有一些html5的数据类型,但暂未使用,此js需要立即执行的区域比较多。
没有对以下数据类型进行扩展 function Boolean null undefined。
二、此js包含了正则处理
*/
Namespace.register("U.UF.S");
//#region 正则方法区域
U.UF.S.browser = /(msie|firefox|chrome|ipad|iphone|safari|opera|version|rv).*?([\d.]+)/; //区分浏览器正则
U.UF.S.Event = /\[object (Keyboard|Mouse|Focus|Wheel|Composition|Storage|MS|)Event(Obj|)\]/; //判断是否为event
U.UF.S.Guid = /^[a-fA-F0-9]{8}(-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}$/; //判断是否为Guid
U.UF.S.English = /^[A-Za-z]+$/; //是否为英文
U.UF.S.RNum = /\d+/g; //数字浮点等
U.UF.S.Number = /^\d+$/; //整数
U.UF.S.Num = /^(-?\d+)(\.\d+)?$/; //浮点
U.UF.S.EN = /^([a-zA-Z0-9_\-]+)$/; //css样式名规则
U.UF.S.Url = /^\w+\:\/\/([\w+]).*/; //是否是有效链接
U.UF.S.FileName = /^([a-zA-Z0-9\u4e00-\u9fa5\s\._-]+)$/; //文件名判断
U.UF.S.ZWFileName = /^[0-9a-zA-Z\u4e00-\u9fa5\._-]{1,40}\\*$/; //文件名判断
U.UF.S.PBrief = /^.{0,100}$/; //判断是否为有效的签名
U.UF.S.FFZF = /^(\w|-|[\u4E00-\u9FA5])*$/; //中文字符下划线
U.UF.S.ChineseIdCard = /\d{17}[\d|X]|\d{15}/; //身份证
U.UF.S.TelephoneNumber = /^1[0-9]{10}$/; //电话号码
U.UF.S.Email = /^\w+([_+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/; //邮箱
U.UF.S.TrueName = /^[\u4e00-\u9fa5]{1,20}$|^[a-zA-Z]{1,20}$/; //真实姓名
U.UF.S.UserName = /^\S{1,25}$/; //用户名
U.UF.S.NickName = /^[0-9a-zA-Z\u4e00-\u9fa5_-]{1,40}\\*$/; //昵称
U.UF.S.PassWord = /^[^\u4E00-\u9FA5\uF900-\uFA2D]{6,20}$/; //密码
U.UF.S.Visa = /^[45]\d{15}$/; //银行卡号
U.UF.S.rgb = /^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/ //rgb颜色判断
//#endregion
//#region 字符串处理
//---------------------------------- 字符串处理-------------------------------------
U.UF.C.String = {
//场景:制作编辑器word,excel,txt时,把符号"'"转义成"\'",把符号"""转义成"\"".
//作用,把符号"'"转义成"\'",把'张三'存入数据库,会报错,符号'''会在存储过程执行时报错,此时需要把"'"转成"\'",转换后的结果是"\'张三\'"
//例:exec 存储过程 ''param'',转义为exec 存储过程 '\'param\''
//把符号"""转义成"\"",把"张三"存入数据库,会报错,符号'"'会在存储过程执行时报错,此时需要把"""转成"\"",转换后的结果是"\"张三\""
//例:exec 存储过程 ""param"",转义为exec 存储过程 "\"param\""
escapeQuotes: function () {
return this.replace(/'/ig, "''").replace(/"/ig, "\\\""); //字符串的形式输出
},
unEscapeQuotes: function () {
return this.replace(/\\'/ig, '\'').replace(/\\"/ig, "\""); //字符串的形式输出
},
count: function () { //获取字符串长度
return this.substrU(); //调用SubstrU() 获取字符串长度
},
//截取字符串在制定的长度内
substrU: function (start, end) {
var i, _UTF, _num = 0, _UMS = "";
if (end == null && start != null) { end = start, start = 0 }; //参数只有一个的情况 start=0起点设置0 end=start把start当做截取字符串的终点
_UTF = (start == null && end == null); //没有参数情况 _UTF=true
for (i = 0; i < this.length; i++) {
_num += this.charCodeAt(i) < 255 ? 1 : 2; //非常规字符判断长度为2 常规则1
if (_num < start) { continue; } //当前长度小于起点则 continue
if (_num <= end || _UTF) {//当前长度小于 终点
_UMS += this.charAt(i); //获取字符串的第i个
continue;
}
break; //不符合if时 break
}
return (_UTF ? _num : _UMS); //判断参数是否为空 为空返回长度 否则返回截取的字符串
},
//jsstring: function () { //json string
// return this.replace(/\r\n/g, "\\r\\n").replace(/\n/g, "\\n").replace(/\"/g, "\\\""); //把 \r\n转成 \\r\\n \n转成\\n \"转成\\\"
//},
//SubstrN: function (UN) { //判断是否在指定的长度内,
// return this.substrU(0, UN) == this; //用SubstrU截取0-UN的字符串 判断是否等于原字符串
//},
isStrNull: function () { //判断是否为空字符串
return this.trim() == ""; //用trim 去除所有空白字符再判断是否等于 ""
},
//文本换行替换成页面换行,把\r\n 换成
replaceRnToBr: function () {
return this.replace(/\r\n/g, "
"); //把\r\n 换成
},
//成页面换行替换成文本换行,把
换成\r\n
replaceBrToRn: function () {
return this.replace(/<(BR)[^<>]*>/ig, "\r\n"); // 把
换成\r\n
},
removeP: function () { //去除P标签
return this.replace(/<(p)[^<>]*>/ig, ""); //把
去掉
},
removeBr: function () { //去除BR标签
return this.replace(/<(BR)[^<>]*>/ig, ""); //把
去掉
},
removeRn: function () { //去除\r\n标签
return this.replace(/\r\n/g, ""); //把\r\n 去掉
},
replaceBrAndBlank: function () { //把
转换为 \r\n并把空格" "转换为"",应用场景在哪里?
return this.replaceBrToRn().replace(/ /g, '');
},
//判断用户是否在div可编辑区域里面输入了内容。
isHtmlNull: function () { //移除
标签,移除P标签,去除所有空格。当用户发帖时需要判断用户是否输入了文字图片,可以用此函数判断用户是否输入了内容。在div可编辑时需要用此函数。
return this.removeBr().removeP().trim() != ""; //
},
//把字符串中的< > 分别转换成 < >
replaceLtAndGt: function () {
return this.replace(/</g, "<").replace(/>/g, ">"); //所有< > 分别转换成 < >
},
//把字符串中的 < >分别转换成< >
replaceAngleBrackets: function () { //把字符串中的 < >分别转换成< >
return this.replace(//g, ">"); //所有< > 分别转换成 < >
},
//应用:从数据库取出的html代码会直接显示在页面中,为了让js,css等文字以文字的形式显示,而不是植入到页面中不显示,所以需要转义。
//HTML字符转化为ASCLL码.把字符串中的 < >分别转换成< > ,把"'"转换为"'",把"""转换为""",把
//注释:/&(?!#?[a-zA-Z0-9]+;)/g, "&"暂时不知道什么意思。
replaceHtmlSign: function () {
return this.replace(/&(?!#?[a-zA-Z0-9]+;)/g, "&").replace(//g, ">").replace(/'/g, "'").replace(/"/g, """);
},
replaceDoubleToAngleBrackets: function () { //html字符可输出
return this.replace(/\《/g, "<").replace(/\》/g, ">"); //所有《》转换为<>
},
replaceAngleToDoubleBrackets: function () {//中文括号
return this.replace(/\/g, "》"); // 所有<>转换为《》
},
trim: String.prototype.trim || function (str) {//去除所有空格,用于发帖时标题内容是否为空的判断,创建文件夹时输入文件夹名时的判断。
return this.replace(/\ |\ |\s+|\n|\r|\t/g, str || ""); //去除空白符号、\t、\s、\r、\n
},
lTrim: function () { //去除左边空格
return this.replace(/(^\s*)/g, "");
},
rTrim: function () { //去除右边边空格
return this.replace(/(\s*$)/g, '');
},
addPreSpace: function (n) { //字符串前面追加n个空格,用于IDE编辑器环境前面空四格
var i, k = "";
for (i = 0; i < n; i++)
k += " ";
return k + this;
},
insertString: function (str, n) { //指定位置插入字符串
//调用substr截取字符串 加上插入的字符 再加上 把原字符串删除前UN个字符的字符串
var _pre = this.substr(0, n);
var _back = this.substr(n, this.length);
return _pre + str + _back;
},
//指定位置插入省略号, 常见于文章标题过长、文件夹名称过长,在显示时后面的字符以省略号代替
addEllipsis: function (n) { //省略号
var _str = this.substrU(0, n); //调用SubstrU 截取字符串
if (_str != this) {
_str = _str + "...";
}
//当修改String的原型时,会把字符串string替换为object的str,所以需要用valueOf()方法转换为字符串的string. Object对象的格式类似 String {"asdasd"}
return _str.valueOf(); //判断_str是否为原字符串 不是的话返回_str加上...
},
//字符串转化成number
toInt: function () {
var _UTV = this.valueOf(), _UMS = _UTV.match(/^(-|\+)?\d+/g);
return _UMS && _UMS.length == 1 ? Number(_UMS[0]) : _UTV;
},
//把原字符串source换成目标字符串target
replaceStr: function (source, target) {
return this.replace(new RegExp(source, "gm"), target); //把原字符串source换成目标字符串target
},
parseJSON: function () { //string 转 json对象
var _obj = null, _str = this;
try {
_obj = eval("0,(" + _str + ")");
} catch (e) { }
return _obj == null ? _str.valueOf() : _obj;
},
capitalizeFirstLetter: function () { //首字母大写
return this.replace(/\b(\w)|\s(\w)/g, function (UAE) { return UAE.toUpperCase(); });
},
//回车换行替换成换行 并返回按照\n拆分出的数组
SplitRN: function () {
return this.replace(/\r\n/g, "\n").split("\n"); //把\r\n替换成\n 并且根据\n把字符串分成数组
},
//根据符号"<",">"把html字符串拆分成数组,适合于IDE编辑器
////增加一个拆分html编码为字符串数组的操作,用于编辑器的换行,定义到主项目中
//拆分HTML编码,适合于编辑器,不止是拆分html编码,同时还需要把中间的文字提出出来,例如javascript代码,div中间的文字等。
// SplitAngleBrackets: function () {
// var i, s, a = [];
// for (i = 0; i < this.length; i++) {
// if (this[i] == "<") {
// s = i;
// }
// if (this[i] == ">") {
// a.push(this.substring(s, i + 1));
// }
// };
// return a;
// },
//根据符号"<",">"把html字符串拆分成数组,适合于IDE编辑器
////增加一个拆分html编码为字符串数组的操作,用于编辑器的换行,定义到主项目中
//拆分HTML编码,适合于编辑器,不止是拆分html编码,同时还需要把中间的文字提出出来,例如javascript代码,div中间的文字等。
SplitAngleBrackets: function () {
return this.match(/(<(.[^>]*)>)|((|>)[^\<]*[^\<^\s])/g);
},
//过滤html标签留下纯文本,不保留任何格式
htmlToText: function () { //过滤HTML标签留下纯文本
return String(this).replace(/(<(.[^>]*)>)/g, "");
},
//过滤html标签留下纯文本,但保留换行符号
htmlToTextRn: function () {
return this.replace(/(<(.[^>]*)>)/g, function (str) {
return (/(<\/(div|DIV|p|P)([|^>]*)>)|<(BR)[^<>]*>/ig.test(str)) ? "\r\n" : "";
});
},
//获取body里面的html
getBodyHtml: function () {
try {
return /]*>([\s\S]*)<\/body>/.exec(String(this))[1].unEscapeQuotes();
}
catch (e) {
return "";
}
}
};
//#endregion
//#region 数字Number
U.UF.C.Number = {
//数字转换成货币的格式 100000 = 10,000
formatMoney: function () {
var _split; //
var _arr = [];
var _str = this.toString();
while (_str) { //循环拆分
_split = _str.length - 3;
//unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度。
_arr.unshift(_str.substr(_split < 0 ? 0 : _split));
_str = _str.substr(0, _split);
}
return _arr.join(",");
},
//数字前面补零
prefixInteger: function (n) {
return (this < 10 ? "0" + this : this).valueOf(); //小于10 补零
//Array(n)创建n位数组,join(0)以0作为分隔符,
return (Array(n).join(0) + this).slice(-n);
},
//把角度转换成弧度,
toRadians: function () { //返回圆弧率
return this * Math.PI / 180; //PI即圆周率,Math.PI/180*t是将t把角度转换成弧度.缺少应用场景
}
};
//#endregion
//#region 数组处理
/**
* 判断是否为数组,//ie10以下浏览器不支持Array.isArray。使用return Object.prototype.toString.call(arr) === "[object Array]";做兼容。U.UF.C.Array是为了添加Array的原型方法,而Array.isArray不是原型方法,所以没有放到U.UF.C.Array中。
*
* @param {array} 需要判断的类型
* @returns {bool} 返回真假
*/
//判断是否为数组
Array.isArray = Array.isArray || function (arr) {
return Object.prototype.toString.call(arr) === "[object Array]";
}
//数组初始化类
U.UF.C.Array = {
/**
* 判断有否有内容包含在该数组中的位置
*
* @param {string、number} 需要查找的值indexOf
* @returns {int} -1 >-1 -1 就是数组不存在 >-1就是位置
*/
indexOf: Array.prototype.indexOf || function (val, startpoint) {
var i = startpoint || 0,
j;
//循环数组,获取数组的值
for (; i < this.length; i++) {
//在数组中查找制定的值,如果值匹配数组中的其中一个,那么返回该数组所在的位置
if (this[i] == val) {
return i;
}
}
//如果没有找到制定的位置,那么就直接返回-1
return -1;
},
//对象object在数组中的位置
//参数:object 形如{"name":"张三"}
objIndexOf: function (obj) {
var i,
j,
_isfind;
for (i = 0; i < this.length; i++) {
_isfind = false; //默认没有找到位置。
//循环所有的obj里面的key和value,匹配所有的key和value都正确的,找到第一个匹配成功的位置
for (j in obj) {
//根据key匹配了指定的值,那么设置为true
if (this[i][j] == obj[j]) {
_isfind = true;
}
//如果根据key匹配指定的值错误,那么解决forin循环直接设置为false
else {
_isfind = false;
break;
}
}
//如果上面的obj判断全部正确,那么返回所在的位置,否则返回-1;
if (_isfind) {
return i;
}
}
//如果没有找到制定的位置,那么就直接返回-1
return -1;
},
/**
* 移除数组里相同的值, 类似[element,elment,elment,element],或者[1,2,3,4,3,2],或者["张三","李四","张三","","王五"]
*
* @param {string} 判断字段
* @param {string} 原数组
* @returns 删除的原元素本身
*/
unique: function () { //移除数组里相同的值
//将数组的值作为对象的属性,通过对象的属性值来判断数组是否重复,若该项不重复则给对象对应属性值赋为true,便于之后的判断,并将数据项加入结果集中
var result = [];
var obj = {};
for (var i = 0; i < this.length; i++) {
if (!obj[this[i]]) {
result.push(this[i]);
obj[this[i]] = true;
}
}
return result;
},
//以下几个函数是做浏览器兼容的,系统本身支持这些函数,但有些浏览器不支持,为了使所有浏览器都支持,则定义以下几个兼容函数。
//方法对数组的每个元素执行一次提供的函数。
//参数一:callback 为数组中每个元素执行的函数,该函数接收三个参数:currentValue(当前值) 数组中正在处理的当前元素。index(索引)数组中正在处理的当前元素的索引。arrayforEach()方法正在操作的数组。
//参数二:可选参数。当执行回调 函数时用作this的值(参考对象)。
forEach: Array.prototype.forEach || function (cb, thisArg) {//允许object和array使用
var i = 0;
var _length = this.length;
while (i < _length) {
cb.call(thisArg, this[i], i, this);
i++;
}
},
/**
* 测试数组的所有元素是否都通过了指定函数的测试。
*
* @param {function} 用来测试每个元素的函数。
* @param {Array} 执行 callback 时使用的 this 值。
* @returns {boolean}
*/
every: Array.prototype.every || function (cb, thisArg) {
// return this.forEach(cb, UTI, "every");
var i = 0, b;
var _length = this.length;
while (i < _length) {
b = cb.call(thisArg, this[i], i, this);
if (b == false) {
return b;
}
i++;
}
return true;
},
/**
* 方法测试数组中的某些元素是否通过由提供的函数实现的测试。
*
* @param {function} 用来测试每个元素的回调函数
* @param {Array} 执行 callback 函数时 使用的this 值。
* @returns {boolean}
*/
some: Array.prototype.some || function (cb, thisArg) {
var t = Object(this);
var _len = t.length;
for (var i = 0; i < _len; i++) {
if (i in t && cb.call(thisArg, t[i], i, t))
//为数组中的每一个元素执行一次 callback 函数,如果回调函数返回true的话,则some函数返回true。
return true;
}
return false;
},
/**
* 方法测试数组中的某些元素是否通过由提供的函数实现的测试。
*
* @param {function} 生成新数组元素的函数,使用三个参数:
currentValue callback 的第一个参数,数组中正在处理的当前元素。
@param {int} callback 的第二个参数,数组中正在处理的当前元素的索引。
@param {Array} callback 的第三个参数,map 方法被调用的数组。
* @param {Array} 执行 callback 函数时 使用的this 值。
* @returns {Array} 返回整合过后的新数组
*/
map: Array.prototype.map || function (cb, thisArg) {
/*var T, A, k;
// 将O赋值为调用map方法的数组.
var O = Object(this);
//将len赋值为数组O的长度.
var len = O.length;
//如果参数thisArg有值,则将T赋值为thisArg;否则T为undefined.
if (thisArg) {
T = thisArg;
}
//创建新数组A,长度为原数组O长度len
A = new Array(len);
//将k赋值为0
k = 0;
//当 k < len 时,执行循环.
while (k < len) {
var kValue, mappedValue;
//遍历O,k为原数组索引
if (k in O) {
//kValue为索引k对应的值.
kValue = O[k];
// 执行callback,this指向T,参数有三个.分别是kValue:值,k:索引,O:原数组.
mappedValue = callback.call(T, kValue, k, O);
// 返回值添加到新数组A中.
A[k] = mappedValue;
}
// k自增1
k++;
}
//返回新数组A
return A;*/
//定义自增量
var i = 0;
//定义数组长度
var _length = this.length;
//定义新的数组
var _arr = [];
//判断传入的cb必须是个'function',若不是返回类型错误提示
if (typeof cb != "function")
throw new TypeError();
//当i<_length时循环
while (i < _length) {
//判断索引是否为原数组的索引
if (i in this) {
// 执行callback,this指向thisArg,参数有三个.分别是this[i]:值,i:索引,this:原数组.
_arr.push(cb.call(thisArg, this[i], i, this));
}
//i+1
i++;
}
//返回出新的数组
return _arr;
},
/**
* 创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。
*
* @param {function} 用来测试数组的每个元素的函数。返回true表示保留该元素(通过测试),false则不保留。
* @param {Array} 可选。执行 callback 时的用于 this 的值。
* @returns {Array} 一个新的通过测试的元素的集合的数组
*/
filter: Array.prototype.filter || function (cb, thisArg) {
/*var t = Object(this);
var len = t.length;
var res = [];
for (var i = 0; i < len; i++) {
if (i in t) {
var val = t[i];
if (cb.call(thisArg, val, i, t))
//判断是否符合回调函数中的条件,如果符合则添加到新数组中
res.push(val);
}
}
return res;*/
//定义自增量
var i = 0;
//定义数组长度
var _length = this.length;
//定义新的数组
var _arr = [];
//判断传入的cb必须是个'function',若不是返回类型错误提示
if (typeof cb != "function")
throw new TypeError();
while (i < _length) {
//如果i是原数组的索引,执行call.参数有三个.分别是this[i]:值,i:索引,this:原数组.
if (i in this && cb.call(thisArg, this[i], i, this))
_arr.push(this[i]);
i++;
}
return _arr;
},
/* mdn中没有的Array方法
reject: function (cb, UTI) { //过滤真元素
return this.forEach(cb, UTI, "reject");
},
*/
/**
* 返回数组中满足提供的测试函数的第一个元素的索引。否则返回-1。
*
* @param {function} 针对数组中的每个元素, 都会执行该回调函数, 执行时会自动传入下面三个参数:
element 当前元素。
index 当前元素的索引。
array 调用findIndex的数组。
* @param {Array} 可选。执行 callback 时的用于 this 的值。
* @returns {int} 用来判断是否满足测试函数中的第一个元素的值 没有返回-1
*/
findIndex: Array.prototype.findIndex || function (predicate) {
/*var o = Object(this);
var len = o.length;
var thisArg = arguments[1];
var k = 0;
while (k < len) {
var kValue = o[k];
if (predicate.call(thisArg, kValue, k, o)) {
//如果找到这个元素的话则返回k
return k;
}
k++;
}
//没有找到该元素则返回-1
return -1;*/
//定义自增量
var i = 0;
//定义数组长度
var _length = this.length;
//判断传入的cb必须是个'function',若不是返回类型错误提示
if (typeof predicate != "function")
throw new TypeError();
while (i < _length) {
//参数有三个.分别是this[i]:值,i:索引,this:原数组.
if (predicate(this[i], i, this))
//如果找到这个元素的话则返回i
return i;
i++;
}
return -1;
},
/**
* 方法返回指定元素(也即有效的 JavaScript 值或变量)在数组中的最后一个的索引,如果不存在则返回 -1。从数组的后面向前查找,从 fromIndex 处开始。
*
* @param {element} 被查找的元素。
* @param {int} 从此位置开始逆向查找。默认为数组的长度减 1,即整个数组都被查找。如果该值大于或等于数组的长度,则整个数组会被查找。如果为负值,将其视为从数组末尾向前的偏移。即使该值为负,数组仍然会被从后向前查找。如果该值为负时,其绝对值大于数组长度,则方法返回 -1,即数组不会被查找。
* @returns {int} 数组中最后一个元素的索引,如未找到返回-1
*/
lastIndexOf: Array.prototype.lastIndexOf || function (searchElement, fromIndex) {
var n, k,
t = Object(this),
len = t.length;
if (len === 0) {
//如果数组的长度为零的话直接返回-1
return -1;
}
n = len - 1;
if (arguments.length > 1) {
n = Number(arguments[1]);
if (n != n) {
n = 0;
}
else if (n != 0 && n != (1 / 0) && n != -(1 / 0)) {
n = (n > 0 || -1) * Math.floor(Math.abs(n));
}
}
for (k = n >= 0
? Math.min(n, len - 1)
: len - Math.abs(n); k >= 0; k--) {
if (k in t && t[k] === searchElement) {
// 如果有等于参数1 的元素,返回该元素
return k;
}
}
//如果上述查找没有符合条件的元素,返回-1
return -1;
//定义结束位置
/* var endLength = !isNaN(parseFloat(UTI)) && isFinite(UTI) ? UTI : 0;
//定义自减量
var i = this.length - 1;
while (i >= endLength) {
if (USE == this[i])//如果等于就返回i索引
return i;
i--;
}
//没符合条件,返回-1
return -1;*/
},
/* mdn Array方法中无此方法 */
/*
sample: function (UIE, UDE) { //获取一组随机数
UDE = UDE || this; var _USE = [], _UL = UDE.length; UIE = UIE || 1;
for (i = 0; (i < _UL && i < UDE.length); i++) { _USE.push(UDE[U.UF.Math.getRandom(_UL)]); }
},*/
/**
* 用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。
*
* @param {int} 用来填充数组元素的值。
* @param {int} 起始索引,默认值为0。
* @param {int} 终止索引,默认值为 this.length。
* @returns {Array} 修改后的数组。
*/
fill: Array.prototype.fill || function (value) {
var O = Object(this);
//转换成无符号的整数
var _len = O.length;
var _start = arguments[1];
var _relativeStart = _start;
//判断start是否小于零,并将相应的值赋予变量
var k = _relativeStart < 0 ?
Math.max(_len + _relativeStart, 0) :
Math.min(_relativeStart, _len);
var _end = arguments[2];
var _relativeEnd = _end === undefined ?
_len : _end;
//判断end是否小于零,并将相应的值赋予变量
var _final = _relativeEnd < 0 ?
Math.max(_len + _relativeEnd, 0) :
Math.min(_relativeEnd, _len);
//对数组进行填充
while (k < _final) {
O[k] = value;
k++;
}
return O;
},
/**
* 浅复制数组的一部分到同一数组中的另一个位置,并返回它,而不修改其大小。
*
* @param {int} 0 为基底的索引,复制序列到该位置。如果是负数,target 将从末尾开始计算。
* @param {int} 0 为基底的索引,开始复制元素的起始位置。如果是负数,start 将从末尾开始计算。
* @param {int}0 为基底的索引,开始复制元素的结束位置。copyWithin 将会拷贝到该位置,但不包括 end 这个位置的元素。如果是负数, end 将从末尾开始计算。
* @returns {Array} 改变了的数组。
*/
copyWithin: Array.prototype.copyWithin || function (target, start, end) { //拷贝对象
var O = Object(this);
var _len = O.length;
//转换成无符号整数
var _relativeTarget = target;
//判断target是否小于0,并将判断之后的值赋予变量
var _to = _relativeTarget < 0 ?
Math.max(_len + _relativeTarget, 0) :
Math.min(_relativeTarget, _len);
//start转换成无符号整数
var _relativeStart = start;
//判断start是否小于0,并将判断之后的值赋予变量
var _from = _relativeStart < 0 ?
Math.max(_len + _relativeStart, 0) :
Math.min(_relativeStart, _len);
var end = arguments[2];
var _relativeEnd = end === undefined ? _len : end >> 0;
//判断end是否小于0,并将判断之后的值赋予变量
var _final = _relativeEnd < 0 ?
Math.max(_len + _relativeEnd, 0) :
Math.min(_relativeEnd, _len);
var _count = Math.min(_final - _from, _len - _to);
var _direction = 1;
if (_from < _to && _to < (_from + _count)) {
_direction = -1;
_from += _count - 1;
_to += _count - 1;
}
//循环进行数组操作
while (_count > 0) {
if (_from in O) {
O[_to] = O[_from];
} else {
delete O[_to];
}
_from += _direction;
_to += _direction;
_count--;
}
//返回复制过后的数组
return O;
},
/*该特性是非标准的,请尽量不要在生产环境中使用它!*/
//toSource: function () { return JSON.stringify(this); },
/* mdn Array方法中无此方法 */
//ArrayToString: function () { return JSON.stringify(this); }, //数组转换为字符串,在写api时获取后台返回的值时经常用到。
/* IE无法兼容此方法 */
/*keys: Array.prototype.keys || function () {
var _UME = function (UDE) { this.i = 0; this.e = UDE; }
_UME.prototype = {
next: function () { //迭代
return { value: this.i++, done: this.i >= this.e.length }
}
}
return new _UME(this);
},*/
/**
* 返回一个新的Array Iterator对象,该对象包含数组中每个索引的键/值对。
*
* @returns {object} 一个新的 Array 迭代器对象。
*/
/* IE无法兼容此方法 */
//entries: Array.prototype.entries || function () { }
//一维数组深拷贝是用concat()函数。
//多维数组深度拷贝函数
//重玩本关是一个难点,难度在于三维数组的拷贝,只复制地址,不复制值,这意味着通关后的数组再也回不到初始化时的数组,也就实现不了重玩本关的功能。
//javascrit数组数据类型提供了slice(0)和concat()函数实现数组的深拷贝,但只局限于一维数组,在二维,三维,四维中不起作用。
//为了解决此问题,特提供深度拷贝函数解决此问题。
//递归的适合于二维数组以上的所有维度的深拷贝。
deepCopy: function () {
var i,
_newarr = [];
for (i = 0; i < this.length; i++) {
if (Array.isArray(this[i])) {
//深拷贝
_newarr[i] = this[i].deepCopy(this[i]);
}
else {
_newarr[i] = this[i];
}
}
return _newarr;
}
};
//ArrayBuffer兼容处理,只有在h5文件上传用到
U.UF.S.ArrayBuffer = function () {
/**
* ArrayBuffer slice polyfill.
*
* @see https://github.com/ttaubert/node-arraybuffer-slice
*/
if (typeof ArrayBuffer !== 'undefined' && !ArrayBuffer.prototype.slice) {
(function () {
function clamp(val, length) {
val = (val | 0) || 0;
if (val < 0) {
return Math.max(val + length, 0);
}
return Math.min(val, length);
}
ArrayBuffer.prototype.slice = function (from, to) {
var length = this.byteLength,
begin = clamp(from, length),
end = length,
num,
target,
targetArray,
sourceArray;
if (to !== undefined) {
end = clamp(to, length);
}
if (begin > end) {
return new ArrayBuffer(0);
}
num = end - begin;
target = new ArrayBuffer(num);
targetArray = new Uint8Array(target);
sourceArray = new Uint8Array(this, begin, num);
targetArray.set(sourceArray);
return target;
};
})();
}
}
//#endregion
//#region Guid
/**
* 自定义Guid 类型
默认情况下我们给guid返回 空Guid
*/
window.Guid = U.UF.C.Guid = {
//生成Guid
newGuid: function () {
var _num, i, _guid = "";
for (i = 0; i < 32; i++) {
_guid += Math.floor(Math.random() * 16).toString(16); //随机0 - 16 的数字 转变为16进制的字符串
_num = Math.floor((i - 7) / 4); //计算 (i-7)除4
if (_num > -1 && _num < 4 && (i == (7 + 4 * _num))) { //会使guid中间加 "-" 形式为xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
_guid += "-";
}
}
return _guid;
},
//空Guid
emptyGuid: US.EMPTYGUID,
// 返回一串无 "-" 的Guid Dash翻译为破折号
guidNoDash: function () {
return Guid.newGuid().replace(/-/g, "");
},
//测试是不是正确的Guid 返回结果为 true 或 false
IsGuid: function (guid) {
return U.UF.S.Guid.test(guid);
}
}
//#endregion
;
///
/*
上传下载处理类
*/
Namespace.register("U.UF.UP");
//上传总函数
/*
* @param {array} 所有需要上传的input
* @param {function} 上传成功回调函数
* @param {array} 回调参数
* @param {string} 上传后响应的处理文件地址 http://disk.1473.cn/upload.ashx
* 上下文(上一个函数与下一个函数的联系):
r.context 回调函数的参数。上下文之间的传参,同第四个参数。
返回值说明:
由开发者定义:例如:可以定义为数组,格式如下:
array [文件在服务器的路径, 缩略图的路径, 文件id, 文件大小, 文件对应群, 文件目录id]
*/
U.UF.UP.upload = function (inputarr, url, cb, params) {
//如果是html5,走html5
//如果有flash,则走flash。此处难做,暂时不做。
//如果html,走html..不能断点续传,不能解析md5.
}
//#region input上传
/**
* html input上传
*
* @param {array} 所有需要上传的input
* @param {string} 上传后响应的处理文件地址 http://disk.1473.cn/upload.ashx
* @param {function} 上传成功回调函数
* @param {array} 回调参数
*/
U.UF.UP.inputUpload = function (inputarr, url, cb, params) { //生成传输的iframe
U.UF.UP.uploading(inputarr, cb, params, url);
}
/**
* html input上传
*
* @param {array} 所有需要上传的input
* @param {function} 上传成功回调函数
* @param {array} 回调参数
* @param {string} 上传后响应的处理文件地址 http://disk.1473.cn/upload.ashx
*/
U.UF.UP.uploading = function (inputarr, cb, params, url) { //生成传输的iframe
var _iframe, //iframe变量
_body = document.body, //body
_name = Guid.guidNoDash() //用于刷新的iframe的id
;
//创建一个接收上传回值的iframe,创建这个iframe主要的作用是做无刷上传,让上传的input不在页面上刷新而是在iframe里面刷新(为什么要创建iframe,因为form上传页面是会刷的,需要通过)
_iframe = $$("iframe", { "id": _name, "name": _name, "width": 0, "height": 0, "style": { "display": "none" }, "frameBorder": 0 }, _body);
//创建一个iframe用于做无刷上传 因为form上传的时候会刷新页面但是如果form的action属性指向的是一个iframe就不会刷新页面,这里为什么要创建跨域的iframe的因为我们项目通常不是一个域名是多个域名,等input上传结束后需要通过iframe去取值,那么下面的创建就显得非常重要
U.UF.C.iframeSameDomain(_iframe, "", function () {
//提交input上传
U.UF.UP.inputUpload.submit(_iframe, inputarr, cb, params, url, _name);
});
}
/**
* html input上传提交区域
*
* @param {element} 用于刷新页面的iframe数组
* @param {array} 所有需要上传的input
* @param {function} 上传成功回调函数
* @param {array} 回调参数
* @param {string} 回调调用地址 允许带参数
* @param {string} 刷新iframe的name
*/
U.UF.UP.inputUpload.submit = function (iframe, inputarr, cb, params, url, name) {
//input上传处理,首先创建一个form表单,然后把需要上传的input循环的放入form中,上传到服务器中
var i, _form, _cloneinput, _changefun, _isfile;
//跨域页面必须设置name,由于在ie8-的系列在创建元素的过程中无法设置name会出现问题,所以在这里加成成功后才能设置
iframe.contentWindow.name = name;
//创建一个form表单进行上传
_form = $$("form", { "action": url, "target": name, "encoding": "multipart/form-data", "enctype": "multipart/form-data", "method": "post", "name": "loading", "style": { "display": "none" } }, document.body);
//循环把input放在form表单里面
for (i = 0; i < inputarr.length; i++) {
//给上传的input设置id,如果不设置的话后台就无法获取上传的文件
inputarr[i].name = inputarr[i].name || inputarr[i].id || Guid.newGuid();
//由于要把input追加到上面创建的form表单里面,所以要克隆一个input
_cloneinput = inputarr[i].cloneNode();
//由于克隆的元素的value值还存在 也说明文件还存在,那么会导致上传同一个文件onchange事件无法触发,下面就是清理value值的兼容
//清空input内容处理,在之前测试是用无数次的情况下会出现异常错误,所以加了try catch
try {
//ie清理value值的方法,比较麻烦,ie input file设置value = ""无效 所以没办法
if (document.selection) {
_cloneinput.select();
document.selection.clear();
}
else {
_cloneinput.value = "";
}
}
catch (e) { }
//把创建好的input代替现在要上传的input
if (inputarr[i].parentNode) {
inputarr[i].parentNode.replaceChild(_cloneinput, inputarr[i]); //由于要把上传的元素放在form里面进行上传处理,所以这里要克隆一个元素,否则元素就会丢失。
}
//form表单里面添加
_form.appendChild(inputarr[i]); //把input添加到form表单里
//判断上传的文件是否是file,如果不是file那么就不用multipart/form-data这种格式提交,因为只是正常的上传input里面只有文字的会产生乱码,这种乱码在java下是没有办法看的
if (inputarr[i].type == "file") {
_isfile = true;
}
}
//如果不是文件上传 只是传输input,那么改成文本上传
if (_isfile !== true) {
_form.encoding = _form.enctype = "application/x-www-form-urlencoded";
}
//上传异步处理
U.UF.DL.iframeLoad(iframe, function () {
U.selectEl(_form).remove(); //元素移除
U.UF.UP.inputUpload.asyn(iframe, inputarr, cb, params); //上传结束异步
});
//开始上传处理
_form.submit();
//拼接传参的链接,在上传的过程中添加上传用户的id,此处需要删除.因为disk.1473.cn的上传是需要做用户识别的,所以这里设置了用户id,但是这种方式是错误的,应该直接去后台获取用户id
// if (US && US.userInfo && US.userInfo.userid) {
// url = url + (url.indexOf("?") > -1 ? "&" : "?") + "UserId=" + (US.userInfo.userid || US.userInfo.userid);
// }
}
/**
* 上传结束异步
*
* @param {element} 用于刷新页面的iframe
* @param {array} 所有需要上传的input
* @param {function} 上传成功回调函数
* @param {object} 回调参数
*/
U.UF.UP.inputUpload.asyn = function (iframe, inputarr, cb, params) {
//跨域上传的时候,服务器返回值,在ie下已经可以直接获取到值,其他浏览器不行,这里给iframe修改src让src指向"about:blank"
if (!(U.UF.CI.getBrowser().browser == "msie")) {
iframe.src = "about:blank";
//由于src重新赋值
setTimeout(function () {
U.UF.UP.inputUpload.callback(iframe, inputarr, cb, params); //执行回调处理
}, 0);
}
//如果是ie浏览器的情况,那么直接回调,已经经过测试
else {
U.UF.UP.inputUpload.callback(iframe, inputarr, cb, params); //执行回调处理
}
}
/**
* 上传回调处理
*
* @param {element} 用于刷新页面的iframe
* @param {array} 所有需要上传的input
* @param {function} 上传成功回调函数
* @param {object} 回调参数
*/
U.UF.UP.inputUpload.callback = function (iframe, inputarr, cb, params) {
var _value = U.UF.UP.inputUpload.getData(iframe); //获取服务器返回的值
//上传成功后删除iframe
U.selectEl(iframe).remove();
//回调处理
if (U.UF.C.isFunction(cb)) { //判断是否为函数的处理
//调用回调的处理
cb({
"value": _value, //服务器返回的数组,类似[文件在服务器的路径, 缩略图的路径, 文件id, 文件大小, 文件对应群, 文件目录id]
"context": params, //
"inputs": inputarr
});
}
}
/**
* 获取上传成功后后台返回的值
* @param {element} 用于刷新页面的iframe
*
*/
U.UF.UP.inputUpload.getData = function (iframe) {
var _value = null; //获取返回值的变量
//通过iframe.contentWindow找到执行域到执行域里面获取innerHTML的方式获取值
try {
_value = iframe.contentWindow.document.body.innerHTML;
}
catch (e) { }
//如果上面获取值的方式没有成功,就使用下面的方法获取
if (!_value) {
try {
_value = iframe.contentWindow.name != iframe.id ? iframe.contentWindow.name : ""; //因为跨域上传后iframe的src的地址已经是跨域的地址,这个时候要通过Window.name方式获取跨域的值
}
catch (e) {
}
}
//上传失败
if (_value == null) {
U.alert("服务器处理繁忙,上传失败");
}
else {
//获取值转化成json对象
_value = U.UF.C.toJson(_value);
}
return _value;
}
//#endregion
//#region html5上传
/*
* @param {element} 所有需要上传的input
* @param {function} 上传成功回调函数
* @param {object} 失败的回调
{
* "error": "U.UF.UP.error", //错误处理
* "select": "U.UF.UP.select", //选择文件处理
* "getHashCallBack": "U.UF.UP.getHashCallBack", //上传解析文件的处理
* "progress": "U.UF.UP.progress", //解析文件md5值,和上传文件的时候的进度条处理
* "uploadComplete": "U.UF.UP.uploadComplete", //上传结束的处理,这个时候还没有返回值
* "getData": "U.UF.UP.getData", //上传结束后服务器返回的值
* "endUpload": "U.UF.UP.endUpload", //上传结束处理
}
*/
U.UF.UP.html5Upload = function (fileinfo, succallback, callback) { //生成传输的iframe
//进行文件加密 回调参数(进度,完成,文件hash)
U.UF.UP.html5Upload.fileMd5(fileinfo, function (progress, finish, filehash) {
if (finish) {//判断是否解析完成
//获取hash后的回调处理
if (U.UF.C.isFunction(callback.getHashCallBack)) {
callback.getHashCallBack(filehash, fileinfo, succallback, callback.error);
}
}
});
}
/*
* @param {element} 所有需要上传的input
* @param {function} 解析回调函数
*/
U.UF.UP.html5Upload.fileMd5 = function (file, callback) {//生成文件hash
var blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice, //分割文件的方法
chunkSize = 2097152, // Read in chunks of 2MB
chunks = Math.ceil(file.size / chunkSize), //分割的次数
currentChunk = 0,
spark = new U.UF.EC.SparkMD5.ArrayBuffer(),
fileReader = new FileReader()
;
file.fileReader = fileReader;
//解析监听
fileReader.onload = function (e) {
spark.append(e.target.result);
currentChunk++;
//判断是否解析成功
if (currentChunk < chunks) {
loadNext();
callback({ 'Loaded': currentChunk, 'Total': chunks }) // 参数:进度
}
else {
callback({ 'Loaded': 100, 'Total': 100 }, true, spark.end()) // 参数:进度、 是否完成、 文件hash
}
};
//解析失败监听
fileReader.onerror = function () {
callback(null, 'oops, something went wrong.') // 参数:进度
};
//解析下一步处理
var loadNext = function () {
var start = currentChunk * chunkSize,
end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;
fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
}
loadNext();
}
/*
* 判断上传的文件是否在服务器中
* @param {file} 所有需要上传的input
* @param {string} 上传文件的hash值
* @param {function} 解析回调函数
*/
U.UF.UP.html5Upload.select = function (file, filehash, callback) {
U.A.Request("http://upload.1473.cn/select", [file.name, filehash, file.size], function (r) {
callback(r.value.fileServerName, r.value.filesize);
});
}
/*
* 断点续传函数
* @param {file} 文件
* @param {int} 文件总大小
* @param {int} 文件每次上传
* @param {string} 文件服务器名
* @param {int} 服务器文件大小
* @param {fun} 成功回调函数
* @param {fun} 失败回调函数
* @param {int} 第几次上传次数
* @param {int} 总上传次顺
* @param {string} 文件hash
*/
U.UF.UP.html5Upload.loop = function (file, filehash, fileservername, filesize, callback) {
var _xhr, _fd, _thunkto, _islast, // 切割末端
_totalsize = file.size, // 总大小
_eachsize = 1024 * 500, // 每次上传大小 这里是500kb
_thunkfrom = filesize // 切割起始端
;
//判断是否是最后一次上传
if (_eachsize + filesize >= _totalsize) {
_thunkto = _totalsize; //设置上传结束为止的大小
_islast = true; //设置本次上传为最后一次上传
}
//非最后一次上传,这是每次上传为500kb
else {
_thunkto = _eachsize + filesize;
}
//创建form表单发送数据
_fd = new FormData();
_fd.append('theFile', file.slice(_thunkfrom, _thunkto)); // 分好段的文件
_fd.append('filehash', filehash);
_fd.append('fileChunk', 0); // 大小
_fd.append('isLastChunk', _islast); // 是否最后一次上传 count === counts - 1
_fd.append('fileServerName', fileservername); //文件名
//调用ajax请求发送form数据
_xhr = new XMLHttpRequest();
file.xhr = _xhr;
_xhr.open("post", "http://upload.1473.cn/upload", true);
_xhr.onreadystatechange = function () {
if (_xhr.readyState == 4 && _xhr.status == 200) {
var _rs = JSON.parse(_xhr.responseText); //获取后台返回的值
if (_rs.status == 200) {
callback({ 'Loaded': _thunkto, 'Total': _totalsize }); //进度条处理
//判断是否继续上传
if (!_rs.isLastChunk) {
//继续上传
U.UF.UP.html5Upload.loop(file, filehash, fileservername, _thunkto, callback)
}
else {
callback(true);
}
}
}
};
_xhr.send(_fd);
}
/**
* 删除指定上传文件
*
*/
U.UF.UP.html5Upload.deleteUploadFile = function (file) {
if (file.fileReader) {
file.fileReader.abort(); //停止解析
}
if (file.xhr) {
file.xhr.abort(); //停止上传
}
}
/**
* 删除所有的文件
*
*/
U.UF.UP.html5Upload.deleteUploadAllFile = function () {
}
//#endregion
//#region flash上传处理
/**
*flash上传按钮的数组,把所有加载的flash按钮放在这里,这样的话在多个地方加载flash按钮就可以在加载成功后触发事件后统一设置flash上传按钮的样式和回调事件
*{ flashbottom:flashobject, uploadtype:"*", style:{"width":"100", "height":"100"} callback:{
* "error": "U.UF.UP.error", //错误处理
* "select": "U.UF.UP.select", //选择文件处理
* "getHashCallBack": "U.UF.UP.getHashCallBack", //上传解析文件的处理
* "progress": "U.UF.UP.progress", //解析文件md5值,和上传文件的时候的进度条处理
* "uploadComplete": "U.UF.UP.uploadComplete", //上传结束的处理,这个时候还没有返回值
* "getData": "U.UF.UP.getData", //上传结束后服务器返回的值
* "endUpload": "U.UF.UP.endUpload", //上传结束处理
*} }
*/
U.UF.UP.flashbottom = {}; //flash上传按钮的处理
/**
* flash按钮初始化得到
*
* @param {element} flash对象要放置的地方
* @param {string} flash对象名字
* @param {object} flash按钮的样式 {"width":"100", "height":"100"}
* @param {object} flash按钮上传的回调函数的处理 {
* "error": "U.UF.UP.error", //错误处理
* "select": "U.UF.UP.select", //选择文件处理
* "getHashCallBack": "U.UF.UP.getHashCallBack", //上传解析文件的处理
* "progress": "U.UF.UP.progress", //解析文件md5值,和上传文件的时候的进度条处理
* "uploadComplete": "U.UF.UP.uploadComplete", //上传结束的处理,这个时候还没有返回值
* "getData": "U.UF.UP.getData", //上传结束后服务器返回的值
* "endUpload": "U.UF.UP.endUpload", //上传结束处理
*} }
*/
U.UF.UP.addFlashUploadBottom = function (el, name, style, callback, uploadtype) {
var _divel,
_width = style._width,
_height = style._height,
_uploadbootom = U.selectEl("object", el)[0]; //获取flash按钮
_name = name || Guid.newGuid(); //随机生成的name
//如果flash上传按钮,添加,这里做了ie低版本的兼容
if (!_uploadbootom) {
_divel = $$("div", {
"innerHTML": "
"
});
_uploadbootom = _divel.firstChild; //用上面的div去加载了object和embed标签后这里去获取
el.insertBefore(_uploadbootom, el.firstChild); //insertBefore() 在指定子节点前插入
}
//把上传文件设置到flash集合中
U.UF.UP.flashbottom[name] = {
uploadtype: uploadtype || "*", //上传的格式
flashbottom: U.selectEl("*" + name, el)[0], //flash上传按钮
style: style || {}, //flash按钮的样式
callback: callback || {} //flash按钮的回调函数,定义有注释
};
return _uploadbootom;
}
/**
* flash按钮加载成功的处理
*
*/
U.UF.UP.flashLoad = function () {
var i,
_obj = U.UF.UP.flashbottom;
//循环给flash按钮设置处理
for (i in _obj) {
//调用设置
if (_obj[i].flashbottom.setUploadStyle) {
_obj[i].flashbottom.setUploadStyle(i, _obj[i].style, {}, _obj[i].uploadtype); //加载插件初始化
}
}
}
/**
* 错误处理
*
*/
U.UF.UP.error = function (e) {
U.alert(e); //错误提醒
}
/**
* 选择文件处理
* @param {string} flash按钮的唯一识别id
* @param {array} 选择上传的文件数组
*
*/
U.UF.UP.select = function (bottomid, filesarr) {
var _obj = U.UF.UP.flashbottom[bottomid]; //获取点击弹出选择文件上传的按钮对象
_obj.callback.select(filesarr); //执行flash的回调
}
/**
* 选择文件处理
* @param {element} 选择文件上传的flash按钮
* @param {number} 获取FileReferenceList第几个需要解析的文件
* @param {number} 在FileReferenceList数组里的第几个,默认是0,前端可以不传递,这里会出现一个这样的情况,用户点击上传框选择了文件,这个时候产生了一个FileReferenceList,在未上传完成的过程中又点击选择了文件,又产生了一个FileReferenceList,那么这里会出现多个FileReferenceList同时处理
*
*/
U.UF.UP.generateFileHash = function (flashbottom, fileid, i, j) {
flashbottom.generateFileHash(fileid, 0, 0); //执行flash的回调
}
/**
* 上传解析文件的处理
* @param {string} 解析的文件md5值
* @param {string} flash上传按钮的id
*
*/
U.UF.UP.getHashCallBack = function (md5value, uploadid, fileid) {
var _obj = U.UF.UP.flashbottom[uploadid]; //获取点击弹出选择文件上传的按钮对象
_obj.callback.getHashCallBack(md5value, fileid); //执行flash的回调
}
/**
* 解析文件md5值,和上传文件的时候的进度条处理
* @param {string} 解析的文件md5值
* @param {string} flash上传按钮的id
* @param {string} 进度的提醒,包括 解析中,上传中,成功
*
*/
U.UF.UP.progress = function (speedobj, uploadid, fileid, str) {
var _obj = U.UF.UP.flashbottom[uploadid]; //获取点击弹出选择文件上传的按钮对象
_obj.callback.progress(speedobj, fileid, str); //执行flash的回调
}
/**
* 解析文件md5值,和上传文件的时候的进度条处理
* @param {element} 选择文件上传的flash按钮
* @param {string} 上传文件到哪个链接下处理
* @param {number} 获取FileReferenceList第几个需要解析的文件
* @param {number} 在FileReferenceList数组里的第几个,默认是0,前端可以不传递,这里会出现一个这样的情况,用户点击上传框选择了文件,这个时候产生了一个FileReferenceList,在未上传完成的过程中又点击选择了文件,又产生了一个FileReferenceList,那么这里会出现多个FileReferenceList同时处理
*
*/
U.UF.UP.flashUpload = function (flashbottom, fileid, url, i, j) {
flashbottom.upload(url, fileid, i, j); //flash上传调用
}
/**
* 上传结束的处理,这个时候还没有返回值
* @param {object} 上传成功后返回的提示值
* @param {string} flash上传按钮的id
*/
U.UF.UP.uploadComplete = function (e, uploadid, fileid) {
var _obj = U.UF.UP.flashbottom[uploadid]; //获取点击弹出选择文件上传的按钮对象
_obj.callback.uploadComplete(e, fileid); //执行flash的回调
}
/**
* 上传结束后服务器返回的值
* @param {object} 服务器响应等到的request结果,request中的data是返回的值
* @param {string} flash上传按钮的id
*/
U.UF.UP.getData = function (request, uploadid, fileid) {
var _obj = U.UF.UP.flashbottom[uploadid]; //获取点击弹出选择文件上传的按钮对象
_obj.callback.getData(request, fileid); //执行flash的回调
}
/**
* 上传结束处理
* @param {string} flash上传按钮的id
*/
U.UF.UP.endUpload = function (uploadid) {
var _obj = U.UF.UP.flashbottom[uploadid]; //获取点击弹出选择文件上传的按钮对象
_obj.callback.endUpload(); //执行flash的回调
}
/**
* 移除正在上传的文件,当我们在上传的过程中,取消上传,或者是文件已经上传成功了的处理
* @param {element} 选择文件上传的flash按钮
* @param {int} 获取FileReferenceList第几个需要解析的文件
* @param {int} 在FileReferenceList数组里的第几个,默认是0,前端可以不传递,这里会出现一个这样的情况,用户点击上传框选择了文件,这个时候产生了一个FileReferenceList,在未上传完成的过程中又点击选择了文件,又产生了一个FileReferenceList,那么这里会出现多个FileReferenceList同时处理
*
*/
U.UF.UP.deleteUploadFile = function (flashbottom, i, j) {
flashbottom.deleteUploadFile(i, j); //flash上传调用
}
/**
* 删除单个选择文件弹框下所有的文件
* @param {int} 在FileReferenceList数组里的第几个,默认是0,前端可以不传递,这里会出现一个这样的情况,用户点击上传框选择了文件,这个时候产生了一个FileReferenceList,在未上传完成的过程中又点击选择了文件,又产生了一个FileReferenceList,那么这里会出现多个FileReferenceList同时处理
*
*/
U.UF.UP.deleteReferenceFile = function (flashbottom, i) {
flashbottom.deleteReferenceFile(i); //flash上传调用
}
/**
* 删除所有的文件
*
*/
U.UF.UP.deleteUploadAllFile = function (flashbottom) {
flashbottom.deleteUploadAllFile(); //flash上传调用
}
//#endregion
//#region 下载
/**
* 文件下载区域
*
* @param {string} 文件下载的名字 名字.jgp
* @param {string} 下载文件的路径 fa.1473.cn/aa.jpg
* @param {string} 下载文件的处理类的地址 http://disk.1473.cn/USUpfile.ashx typename=" + (fun || "UploadFile"
*/
U.UF.UP.download = function (filename, filepath, url) {
var _filenameinput = $$("input", { "type": "text", "value": encodeURIComponent(filename), "name": "filename" }), //下载下来的文件名
_filepathinput = $$("input", { "type": "text", "value": filepath, "name": "filepath" }); //下载的文件在服务器的路径
//调用上传的接口进行下载,实际上传接口的作用是把input上传到服务器进行响应
U.UF.UP.inputUpload([_filenameinput, _filepathinput], url);
}
//#endregion
//#region 帮助处理
/**
* 获取上传的名字和类型
*
* @param {string} 文件名+类型
* @return {array}
----------[0] 文件名
----------[1] 文件类型
*/
U.UF.UP.getFileNameAndExtension = function (filename) {
filename = filename.toLocaleLowerCase(); //把文字转成消息 如 gg.JPG 转成 gg.jpg 这样下面判断容易
var _num = filename.lastIndexOf("."), //文件后缀.所在的位置
_index = filename.lastIndexOf("\\"),
_xindex = filename.lastIndexOf("/"),
_name = filename.substr((_index > _xindex ? _index : _xindex) + 1, _num), //名字
_extension = filename.substr(_num + 1) //后缀
;
return [_name, _extension]; //文件名和后缀数组
}
/**
* 判断是否为图片类型,fun为文件名,比如"aaaa.jpg"
*
* @param {string} 文件名
* @param {boolean} 是否为图片
*/
U.UF.UP.isImg = function (name) {
var _extension = U.UF.UP.getFileNameAndExtension(name.toLowerCase())[1]; //获取文件的后缀
return ["jpg", "gif", "png", "bmp", "jpeg"].indexOf(_extension) > -1; //根据后缀判断文件是否为图片
}
/**
* 文件由小转大
*
* @param {string} 文件
*/
U.UF.UP.minUnitToMaxUnit = function (filesize) {
var _unitarr = ["B", "KB", "M", "G", "TB"], //指定的文件类型
_unit = (filesize + "").replace(U.UF.S.Num, ""), //获取单位
i = _unitarr.indexOf(_unit) < 0 ? 0 : _unitarr.indexOf(_unit); //现在单位对应下标
filesize = parseFloat(filesize); //获取文件大小
//判断文件大小
while (filesize > 1024) {
filesize /= 1024; //每次除以1024,往下一个单位去变化
i++; //单位
}
return parseInt(filesize.toFixed(2)) + _unitarr[i]; //文件大小加单位
}
/**
* 获取最小单位的大小
*
* @param {string} 文件大小 如 10000B 10240KB 等等
*/
U.UF.UP.maxUnitToByte = function (filesize) {
var _unitarr = ["B", "KB", "M", "G", "TB"], //指定的文件类型
_unit = (filesize + "").replace(U.UF.S.Num, ""), //获取单位
i = _unitarr.indexOf(_unit); //看看单位对应的大小
i = i < 0 ? 0 : i; //看看转成最小单位需要*i个1024个次方
return parseFloat(filesize) * Math.pow(1024, i); //获取最大单位
}
//#endregion
;
///
Namespace.register("U.UF.F");
//#region 窗体放大缩小
//窗体的全局变量
U.UF.F.isTop = false; //置顶的全局判断
U.UF.F.hisTory = true; //判断是否保留最大化之前的窗体宽、高、top、left值
/*
* 遮罩框
* 由于在拖动拉伸等过程中可能会触发到其他iframe,这里就是全局遮罩,让拖动和拉伸的过程中,不回出发到下面的iframe
*/
U.UF.F.maskFrame = function () {
return $$("div", { "style": { "cssText": "width:100%;height:100%;position:absolute;top:0;left:0;" } }, document.body);
}
/*
** 作用:窗体的最大化和最小化功能
** @param {element} el 整个窗体的元素
*/
U.UF.F.windowZooming = function (el) {
var _csstext = el.initcsstext, //初始化的csstext
_ismax = el.ismaximize; //判断窗体是否已经最大化了
//如果最大化了,那么就把他缩小
if (_ismax) {
el.style.cssText = _csstext;
el.ismaximize = false;
}
//最大化处理
else {
el.initcsstext = el.style.cssText; //获取原本的csstext值
el.ismaximize = true;
//设置窗体最大化
U.selectEl(el).css({
"width": "100%",
"height": "100%",
"top": "0px",
"left": "0px"
});
}
U.MD.F.W.reSize();
}
/*
** 作用:窗体的最小化功能
** @param {element} el 整个窗体的元素
*/
U.UF.F.windowMinimize = function (el) {
//添加样式,实现动画效果,并且逐渐隐藏整个窗体
el.style.cssText += "display:none";
//-ms-transform:scale(0.5);-webkit-transform:translateX(100%); -o-transform:scale(0.5); transform:scale(0.5);
}
/*
** 作用:窗体的关闭功能
** @param {element} el 整个窗体的元素
** @param {string} str 操作指令
*/
U.UF.F.closeWindow = function (el, str) {
var _el = U.selectEl(el); //获取整个窗体的元素
if (_el[0].style.display != "none" && str == "remove") {//判断窗体是否被隐藏,并且操作指令为remove
_el.remove(); //移除整个窗体
_el = null; //移除整个窗体
}
else {
_el.css("display", "none");
}
}
/*
** 作用:窗体的居中功能
** @param {element} el 整个窗体的元素
*/
U.UF.F.windowTopCenter = function (el) {
//异步弹出窗体置顶,因为在我们的窗体点击的时候回切换置顶,但在在里面点击应用的时候,会导致先置顶应用(调用了该函数).然后又制定点击对应的窗体。
//setTimeout(function () {
//获取实际高度或者是当前窗口对于窗口显示区左上角的Y位置或者是整个body的实际高度
var _scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop,
//获取整个页面的宽度
_iwidth = document.documentElement.clientWidth,
//获取整个浏览器的宽度
_iheight = document.documentElement.clientHeight; //_scrollTop * 2
el.style.display = "block"; //先显示窗体
_zindex = (US || parent.US).ZINDEX++;
U.selectEl(el).css({
"zIndex": _zindex,
//获取整个窗体的left的值为浏览器窗口文档显示区域的宽度不包括滚动条减去窗体的文档显示区域在除以2再加上实际宽度
"left": (_iwidth - el.clientWidth) / 2 + "px",
//获取整个窗体的left的值为浏览器窗口文档显示区域的高度不包括滚动条减去窗体的文档显示区域在除以2再加上实际高度
"top": (_iheight - el.clientHeight) / 2 + "px"
});
//}, 0);
}
/*
** 作用:窗口的置顶功能
** @param {element} el 整个窗体的元素
** @param {string} str 是否为true
1、获取点击元素
2、给点击元素父级元素的z-index+1
*/
U.UF.F.topWindow = function (el) {
var _zindex,
_el1 = U.UF.F.getWindow(el), //通过U.UF.F.getWindow()获取需要进行置顶的窗体元素
_el3; //获取需要置顶元素的父级元素
if (_el1 && _el1.length || el && el.length) {//判断是否有需要置顶的窗体元素
for (var i = 0; i < _el1.length; i++) {//循环判断有几个窗体元素
_el3 = U.selectEl(_el1[i]).Parent();
//判断 是否有获取需要置顶的窗体元素的父级元素 并且 需要置顶的元素是否符合document.body或者id是否符合"usestudio_server"或者id是否符合"U_MD_Home"三种中的一种,并且是否需要置顶的元素"__top__"不为false,并且操作指令为true或者返回值在字符串中首次出现的位置是否为-1
if (_el3 && (_el3 == document.body || _el3.id == "usestudio_server" || _el3.id == "U_MD_Home") && ($(_el1[i]).attr("__top__") != "false" && _el1[i]["__top__"] != "false")) {
_zindex = (US || parent.US).ZINDEX++;
//如果符合全部要求,则给置顶元素添加一个style样式,z-index每一次置顶都在现有的z-index中加1,并且显示出来
U.selectEl(_el1[i]).addAttrArray({ "style": { "cssText": _el1[i].style.cssText + ";z-index:" + _zindex + ";display:block" } });
}
}
}
}
/*
** 作用:获取顶层窗体的功能
** @param {element} el 整个窗体的元素
*/
U.UF.F.getWindow = function (el) {
var _arr = [], //先定义一个用于存储需要置顶元素的元素
_el2 = el, //获取整个窗体的元素
_el3 = document.body, //获取整个文档的body部分,不包括除body外的一切
_el4 = U.selectEl("#U_MD_Home")[0] || U.selectEl("#usestudio_server")[0] || _el3; //获取满足三个条件中的一个的元素
//判断是否有满足三个条件中的一个的元素
if (_el4) {//如果有,则进行下面的语句
//循环语句,整个窗体的元素为元素的offsetParent,并且.获取的窗体元素不为整个body的部分,也不是满足获取id为U_MD_Home和id为usestudio_server的元素,并且条件满足的情况下进行循环批判断,直到结果出现
while ((_el2 = U.UF.EL.offsetParent(_el2, true)) && (_el2 && (_el2 != _el4 && _el2 != _el3))) {//因为这条语句没有循环限定次数,所以适用while循环语句
if (_el2.style.position != "relative") {
_arr.push(_el2); //如果条件满足,则向_arr这个存储元素的末尾添加一个窗体元素
}
_el2 = _el2.parentNode; //并且把窗体的父节点赋值给新的_el2元素
}
return _arr; //最后返回需要置顶的窗体元素的数组
}
}
/*
** 作用:桌面窗体自动分层次处理,点击窗口自动分层,不会叠加
** @param {callback} cb 回调函数,调用分层函数
** @param {boolean} b 操作指令,知否为true或者false
** @param {element} el 获取窗体元素
*/
U.UF.F.clickTopWindow = function (cb) {
//设置点击置顶的功能
U.selectEl(document.body).bind({
mousedown: function () {
//判断点击置顶有回调函数则回调
if (U.UF.C.isFunction(cb)) {
cb(event.srcElement, true);
}
//置顶窗体处理
top.U.UF.F.topWindow(event.srcElement, true);
}
});
}
//#endregion
//#region 拉伸
/*
* 拉伸函数处理
*
* 1 @param obj1 = {object} 需要拉伸的窗体
* 3 @param str ={string} 判断拉伸是哪个方位
实例:U.UF.F.stretching($(".窗体")[0],拉伸类型)
拉伸类型:
bottom * 向下
right * 向右
top * 向上
left * 向左
rightBottom * 右下
rightTop * 右上
leftTop * 左上
leftBottom * 左下
*/
U.UF.F.stretching = function (obj1, str) {
var e = window.event; //获取当前鼠标点击事件
//target 就是这个对象
//target = e.srcElement || e.target
//这个对象的值
//targetValue = target.value;
var _disX, _disY, _dragMinWidth = 70, _dragMinHeight = 70;
//_dragMinWidth _dragMinHeight设置窗口拉伸最小宽度和高度
// obj2.onmousedown = function (e) { //div的点击执行
//e = e || event; //获取当前event的信息赋予e
e.preventDefault(); //取消event事件的默认动作
_disX = e.clientX; //当事件被触发时鼠标指针向对于浏览器页面(或客户区)的水平坐标
_disY = e.clientY; //当事件被触发时鼠标指针向对于浏览器页面(或客户区)的垂直坐标
var _iparenttop = obj1.offsetTop; //当前窗口距离可视窗口顶部的距离
var _iparentleft = obj1.offsetLeft; //当前窗口距离可视窗口左部的距离
var _iparentwidth = obj1.offsetWidth; //当前窗口的宽度
var _iparentheight = obj1.offsetHeight; //当前窗口的高度
if (!$("#U_UF_F_drag_flag")[0]) {
var _div = $$("div", { "style": { "cssText": "width: 100%;height: 100%;z-index: 99999;position: absolute;top:0;left:0;" }, "id": "U_UF_F_drag_flag" }, document.body);
// _top = U.selectEl(U.UF.UI.form.allForm[_drag.id].header).height();
// U.selectEl(_div)[0].style.top = _top + "px";
}
var _windowfun = {
"mousemove": function (e) { //拉伸移动执行
e = e || event; //获取在鼠标移动的时候event的信息
var _iL = e.clientX - _disX - 3; //返回当事件被触发时鼠标指针向对于浏览器页面(或客户区)的水平坐标-减去-之前窗体距离左边的距离 剩下的就是改变后的宽度
//_iL 相当于 窗体要移动的距离
var _iT = e.clientY - _disY; //返回当事件被触发时鼠标指针向对于浏览器页面(或客户区)的垂直坐标-减去-之前窗体距离顶部的距离 剩下的就是改变后的高度
//_iT 相当于 窗体要移动的高度
var _maxw = document.documentElement.clientWidth - _iparentleft - 2; //获取窗体向右扩张最大宽度(网页可视宽度减去-当前窗口距离可视窗口左部的距离)剩下最大的宽度
var _maxh = document.documentElement.clientHeight - _iparenttop - 2; //获取窗体向下扩张最大高度 (网页可视高度减去-当前窗口距离可视窗口顶部的距离)剩下最大的高度
if (str == "bottom") {
var _ih = _iT + _iparentheight; //获取拉伸后窗体改变的高度
if (_ih < _dragMinHeight) { _ih = _dragMinHeight } else if (_ih > _maxh) { _ih = _maxh; };
//第一先判断改变后的高度有没有低于自己设置的最小高度如果小于就命改变后的高度变成最小高度
//第二判断改变后的高度有没有大于 之前获取的最大高度 如果大于就命 改变后的高度变成最大高度
obj1.style.height = _ih + 'px'; //执行
}
if (str == "right") {
var _iw = _iL + _iparentwidth//获取拉伸后窗体改变的宽度
if (_iw < _dragMinWidth) {
_iw = _dragMinWidth
} else if (_iw > _maxw) {
_iw = _maxw;
}; //判断改变后的宽度有没有低于自己设置的最小宽度,如果有就变成最小的宽度,
//第二判断改变后的宽度有没有大于自己设计的最大宽度如果有就命改变后的宽度变成最大的宽度
obj1.style.width = _iw + 'px'; //执行
}
if (str == "top") {
var _ih = _iparentheight - _iT //获取拉伸后窗体改变的高度 向下拉就是窗体剩余的高度
obj1.style.top = _iparenttop + _iT + 'px'; //执行窗体改变后距离可视窗口头部的距离
if (obj1.style.top < '0') {
obj1.style.top = '0px';
document.onmousemove = null;
} //判断刚刚赋予的值有没有小于0 防止窗口拉伸到外面
if (_ih < _dragMinHeight) {//之前定义了一个属性值高度防止小于窗体高度
var _bh = _ih //赋予值
_ih = _dragMinHeight; //赋予值
obj1.style.top = (_iparenttop + _iT) - (_dragMinHeight - _bh) + 'px'; //(之前距离头部的距离 + 要添加的y值) - (之前设置的最小高度值 - 获取拉伸后窗体改变的高度)
}
obj1.style.height = _ih - '2' + 'px'; //赋予
}
if (str == "left") {
var _iw = _iparentwidth - _iL // 窗体改变前的宽度 减去 窗体拉伸的长度
obj1.style.left = _iparentleft + _iL + 'px'; //当前窗口距离可视窗口左部的距离 + 窗体要移动的距离 (通常为负数)
if (_iw < _dragMinWidth) {//之前定义了一个属性值宽度防止小于窗体宽度
var _bl = _iw
_iw = _dragMinWidth
obj1.style.left = (_siparentleft + _iL) - (_dragMinWidth - _bl) + 'px'; //(之前距离左边的距离 + 要添加的x值) - (之前设置的最小宽度值 - 获取拉伸后窗体改变的宽度)
}
obj1.style.width = _iw - '2' + 'px';
}
if (str == "rightBottom") {
var _iw = _iL + _iparentwidth; //获取拉伸后窗体改变的宽度
var _ih = _iT + _iparentheight; //获取拉伸后窗体改变的高度
if (_iw < _dragMinWidth) {//之前定义了一个属性值宽度防止小于窗体宽度
_iw = _dragMinWidth //赋予值
} else if (_iw > _maxw) {
_iw = _maxw;
}; //防止扩张的时候超出向右扩张最大范围
obj1.style.width = _iw - '2' + 'px'; //-2 是窗体的div本身的厚度
if (_ih < _dragMinHeight) {//之前定义了一个属性值高度防止小于窗体高度
_ih = _dragMinHeight; //赋予值
} else if (_ih > _maxh) {
_ih = _maxh;
}; //防止扩张的时候超出向下扩张最大高度
obj1.style.height = _ih + 'px'; //赋予值
}
if (str == "rightTop") {
var _iw = _iL + _iparentwidth; //获取拉伸后窗体改变的宽度
var _ih = _iparentheight - _iT; //获取拉伸后窗体改变的高度
obj1.style.top = _iparenttop + _iT + 'px'; //当前窗口距离可视窗口顶部的距离 + 改变后的距离
if (obj1.style.top < '0') { obj1.style.top = '0px'; document.onmousemove = null; } //为了防止拉伸的时候超出边界
if (_iw < _dragMinWidth) {//之前定义了一个属性值宽度防止小于窗体宽度
_iw = _dragMinWidth //赋予值
} else if (_iw > _maxw) { _iw = _maxw; }; //如果改变后的宽度超出最大的宽度则。
obj1.style.width = _iw + 'px'; //赋予值
if (_ih < _dragMinHeight) {//之前定义了一个属性值高度防止小于窗体高度
var _bh = _ih //赋予值
_ih = _dragMinHeight; //赋予值
obj1.style.top = (_iparenttop + _iT) - (_dragMinHeight - _bh) + 'px'; //(之前距离头部的距离 + 要添加的y值) - (之前设置的最小高度值 - 获取拉伸后窗体改变的高度)
} else if (_ih > (_iparenttop + _iparentheight)) {
_ih = (_iparenttop + _iparentheight)
}; //如果扩展的高度超过了 (当前窗口距离可视窗口顶部的距离 + 当前窗口的高度)则防止扩张的时候超出范围
obj1.style.height = _ih - '2' + 'px'; //赋予值
}
if (str == "leftTop") {
var _iw = _iparentwidth - _iL // 窗体改变前的宽度 减去 窗体拉伸的长度
obj1.style.left = _iparentleft + _iL + 'px'; //当前窗口距离可视窗口左部的距离 + 窗体要移动的距离 (通常为负数)
var _ih = _iparentheight - _iT //获取拉伸后窗体改变的高度
obj1.style.top = _iparenttop + _iT + 'px'; //当前窗口距离可视窗口顶部的距离 + 改变后的距离
if (obj1.style.top < '0') { obj1.style.top = '0px'; document.onmousemove = null; } //为了防止拉伸的时候超出边界
if (_iw < _dragMinWidth) {//之前定义了一个属性值宽度防止小于窗体宽度
var _bl = _iw; //赋予值
_iw = _dragMinWidth; //赋予值
obj1.style.left = (_iparentleft + _iL) - (_dragMinWidth - _bl) + 'px'; //(之前距离左边的距离 + 要添加的x值) - (之前设置的最小宽度值 - 获取拉伸后窗体改变的宽度)
} else if (_iw > (_iparentleft + _iparentwidth)) {
_iw = (_iparentleft + _iparentwidth)
}; //如果改变后的宽度超过当前窗口距离可视窗口左部的距离 + 窗体改变前的宽度则
obj1.style.width = _iw - '2' + 'px'; //赋予值
if (_ih < _dragMinHeight) {//之前定义了一个属性值高度防止小于窗体高度
var _bh = _ih; //赋予值
_ih = _dragMinHeight; //赋予值
obj1.style.top = (_iparenttop + _iT) - (_dragMinHeight - _bh) + 'px'; //(之前距离头部的距离 + 要添加的y值) - (之前设置的最小高度值 - 获取拉伸后窗体改变的高度)
} else if (_ih > (_iparenttop + _iparentheight)) {
_ih = (_iparenttop + _iparentheight)
}; //如果扩展的高度超过了 (当前窗口距离可视窗口顶部的距离 + 当前窗口的高度)则防止扩张的时候超出范围
obj1.style.height = _ih - '2' + 'px'; //赋予值
}
if (str == "leftBottom") {
var _iw = _iparentwidth - _iL; // 窗体改变前的宽度 减去 窗体拉伸的长度
obj1.style.left = _iparentleft + _iL + 'px'; //当前窗口距离可视窗口左部的距离 + 窗体要移动的距离 (通常为负数)
var _ih = _iT + _iparentheight; //获取拉伸后窗体改变的高度
if (_iw < _dragMinWidth) {//之前定义了一个属性值宽度防止小于窗体宽度
var _bl = _iw; //赋予值
_iw = _dragMinWidth; //赋予值
obj1.style.left = (_iparentleft + _iL) - (_dragMinWidth - _bl) + 'px'; //(之前距离左边的距离 + 要添加的x值) - (之前设置的最小宽度值 - 获取拉伸后窗体改变的宽度)
} else if (_iw > (_iparentleft + _iparentwidth)) {
_iw = (_iparentleft + _iparentwidth)
}; //如果改变后的宽度超过当前窗口距离可视窗口左部的距离 + 窗体改变前的宽度则
obj1.style.width = _iw - '2' + 'px'; //赋予值
if (_ih < _dragMinHeight) {//之前定义了一个属性值高度防止小于窗体高度
_ih = _dragMinHeight; //赋予值
} else if (_ih > _maxh) {
_ih = _maxh;
}; //防止扩张的时候超出向下扩张最大高度
obj1.style.height = _ih - '2' + 'px'; //赋予值
}
if (((str == 'left' || str == 'leftTop' || str == 'leftBottom') && _iw == _dragMinWidth) || ((str == 'top' || str == 'rightTop' || str == 'leftTop') && _ih == _dragMinHeight)) {
document.onmousemove = null;
}; //是为了当使用时拉伸时不会低于最小值
return false;
},
"mouseup": function () {//拉伸结束
document.onmousemove = null;
document.onmouseup = null;
if ($("#U_UF_F_drag_flag")[0]) {
U.selectEl("#U_UF_F_drag_flag").remove();
}
U.selectEl(document.body).unbind(_windowfun);
}
}
U.selectEl(document.body).bind(_windowfun);
}
//#endregion
//#region 拖动窗体
/*
* 函数功能:元素拖动函数,初始化函数
*
* @param el1 {element} 触发拖拽的对象元素
* @param el2 {element} 被拖拽的对象元素
* @param cb1 {function} 每次拖动时,触发的回调函数
* @param cb2 {function} 拖动完毕时,触发的回调函数
*/
U.UF.F.drag = function (el, cb1, cb2) {
/*
* _x {number} 记录元素的left值距离屏幕的差距
* _y {number} 记录元素的top值距离屏幕的差距
* _drag {element} 被拖拽的对象元素
* */
var _x, _y, _l, _t, _drag;
var _event = event || window.event; //var _event = event || window.event;这句话就是定义了一个变量来获取事件对象,因为不同的浏览器获取事件对象的方法有点不太一样,IE下是window.event,标准下是event,为了兼容所以写了event || window.event.
/*
* 说明:
* _event {element} 事件源
* _x {element} 记录元素的left值距离屏幕的差距
* _y {element} 记录元素的top值距离屏幕的差距
* */
_drag = el; //赋值被拖拽的对象元素
_x = _event.clientX; //记录元素的left值距离屏幕的差距
_y = _event.clientY; //记录元素的top值距离屏幕的差距
_l = _drag.offsetLeft; //元素的左偏移
_t = _drag.offsetTop; //元素的右偏移
/*
* 说明:对document树,进行事件的绑定。
* */
var _windowfun = {
/*
* 说明:绑定鼠标移动事件
* _event {element} 事件源
* */
"mousemove": function (event) {
//如果被拖拽的对象存在,执行以下代码
if (_drag) {
/*
* 说明:变量说明
* _event {element} 事件源
* _left {number} 元素水平移动的距离
* _top {number} 元素垂直移动的距离
* body {element} 页面body对象
* */
var _event = event || window.event, //var _event = event || window.event;这句话就是定义了一个变量来获取事件对象,因为不同的浏览器获取事件对象的方法有点不太一样,IE下是window.event,标准下是event,为了兼容所以写了event || window.event.
_newx = _event.clientX - _x,
_newy = _event.clientY - _y,
_left = _newx + _l, // 移动后鼠标的水平距离减去元素未移动时的水平距离,等到元素水平移动的距离。
_top = _newy + _t, // 移动后鼠标的垂直距离减去元素未移动时的垂直距离,等到元素垂直移动的距离。
_body = U.selectEl(document.body)[0]; //页面body对象,用于判断是否超出屏幕可视区域
// if (_left < 0) _left = 0; //如果元素水平移动超出屏幕最左侧,则使元素水平距离在屏幕的最左侧
// if (_left > _body.offsetWidth - _drag.offsetWidth) _left = _body.offsetWidth - _drag.offsetWidth; //如果元素水平移动超出屏幕最右侧,则使元素水平距离在屏幕的最右侧
// if (_top < 0) _top = 0; //如果元素垂直移动超出屏幕最上侧,则使元素垂直距离在屏幕的最上侧
// if (_top > (_body.offsetHeight - _drag.offsetHeight)) _top = (_body.offsetHeight - _drag.offsetHeight); //如果元素垂直移动超出屏幕最下侧,则使元素垂直距离在屏幕的最下侧
// _drag.style.cursor = 'move'; //改变被拖拽的对象元素的鼠标形状
_drag.style.left = _left + 'px'; //改变被拖拽的对象元素的水平位置
_drag.style.top = _top + 'px'; //变被拖拽的对象元素的垂直位置
if (!$("#U_UF_F_drag_flag")[0] && (_newx != 0 || _newy != 0)) {
var _div = $$("div", { "style": { "cssText": "width: 100%;height: 100%;z-index: 99999;position: absolute;top:0;left:0;" }, "id": "U_UF_F_drag_flag" }, document.body);
}
if (cb1 && typeof cb1 == "function" && _newx != 0 && _newy != 0) { cb1(); } //如果有拖动时的回调函数,则执行回调函数。
}
},
/*
* 说明:绑定松开鼠标事件
* event {element} 事件源
* */
"mouseup": function (event) {
//如果有拖动完成的回调函数,则执行回调函数。
if (_drag && cb2 && typeof cb2 == "function") { cb2(el) };
if ($("#U_UF_F_drag_flag")[0]) {
U.selectEl("#U_UF_F_drag_flag").remove();
}
//清空被拖拽的对象元素
_drag = null;
U.selectEl(document.body).unbind(_windowfun);
}
}
U.selectEl(document.body).bind(_windowfun);
}
//#endregion
//#region 拖动选择元素 暂未修改
/*
* 直接拖动元素不带虚拟框 一般常用于图标移动
*
* @param {element} 拖动元素
*/
U.UF.F.dragSelect = function (el, fun) {
//右键处理
if (event.button != 2) {
var _x,
_y,
_dragel,
_mousep = U.UF.EL.getMousePosition(el), //鼠标位置
_record = { x: _mousep.x, y: _mousep.y },
//拖动函数的处理
_mousemove = function () {
//拖动的处理
U.UF.F.dragSelect.drag(el, _mousep, _dragel, fun, _record);
},
//拖动释放的处理
_mouseup = function () {
U.selectEl(_dragel).remove();
//释放取消绑定的处理
U.selectEl(document).unbind({
"mousemove": _mousemove,
"mouseup": _mouseup
});
U.selectEl(el).unbind({
"scroll": _mousemove
});
};
//记录滚动条位置
_mousep.left = el.scrollLeft;
_mousep.top = el.scrollTop;
_x = _mousep.x; //鼠标的x轴坐标
_y = _mousep.y; //鼠标的y轴坐标
//创建选择元素
_dragel = $$("div", { "style": { "cssText": "position:absolute;width:0;height:0;font-size:0;margin:0;padding:0;border:1px solid #89b1e6;background-color:#c3d5ed;z-index:1000;filter:alpha(opacity:60);opacity:.6;background-image: url(/img/UXZT.png); display: inline-block; z-index: 1000; zoom: 1;" + "top:" + _y + "px;left:" + _x + "px;zIndex:" + US.ZINDEX + 1 } }, el);
//绑定元素的处理
U.selectEl(document).bind({
"mousemove": _mousemove,
"mouseup": _mouseup
});
U.selectEl(el).bind({
"scroll": _mousemove
});
}
else {
if (el.dragel) {
el.dragel = null;
}
}
}
/*
* 直接拖动元素不带虚拟框 一般常用于图标移动
*
* @param {element} 拖动元素
*/
U.UF.F.dragSelect.drag = function (el, mouseup, dragel, fun, record) {
var _m = event.type == "scroll" ? record : U.UF.EL.getMousePosition(el), //当前鼠标的位置
_left = mouseup.x + mouseup.left, //滚动条left
_top = mouseup.y + mouseup.top, //滚动条top
_ctop = _m.y + el.scrollTop,
_cleft = _m.x + el.scrollLeft,
_w = Math.abs(_cleft - _left), //拖动后的长
_h = Math.abs(_ctop - _top), //拖动后的宽
_l = Math.min(_cleft, _left), //拖动后的left
_t = Math.min(_ctop, _top) //拖动后的top
;
//如果是滚动出发的则找不到鼠标的位置 所以需要通过记录去找
record.x = _m.x;
record.y = _m.y;
//拉动大小变化
U.selectEl(dragel).addAttrArray({ "style": { "cssText": "width:" + _w + "px;height:" + _h + "px;top:" + _t + "px;left:" + _l + "px;" } });
//设置拉伸选取的处理
U.UF.F.dragSelect.isLocation(dragel, el, { "width": _w, "height": _h, "left": _l, "top": _t }, fun);
}
/*
* 选择元素逻辑范围逻辑
*
* @param {object} 选择的范围
*/
U.UF.F.dragSelect.isLocation = function (dragel, el, obj, fun) {
var i,
_left,
_top,
_width,
_height,
_arr = [],
_child = U.selectEl(el).Child() //所有的拖选取的元素
;
//循环子元素的处理
for (i = 0; i < _child.length; i++) {
//处理的元素不是拖选元素
if (_child[i] != dragel) {
_left = _child[i].offsetLeft;
_top = _child[i].offsetTop;
_width = _child[i].offsetWidth;
_height = _child[i].offsetHeight;
//范围判断
if ((obj.left < _left + _width && obj.left + obj.width > _left) && (obj.top < _top + _height && obj.top + obj.height > _top)) {
_arr.push(_child[i]);
}
}
}
//回调处理
if (fun) {
fun(_arr);
}
}
///*
//* 获取元素选择范围
//*
//* @param {object} 选择的范围
//*/
//U.UF.F.dragSelect.getElementRange = function (el, obj) {//
// // var _UL, _UDE = [0, 0];
// // _UDE[4] = _UL = Math.floor(this.ElO["SW"] / this.W); //每行占位的个数
// // _UDE[0] = ((Math.floor(ULE["Y"] / this.H) - 1) * _UL); //开始的位置
// // _UDE[1] = _UDE[0] + ((Math.ceil((ULE["BY"]) / this.H) - Math.floor(_UDE[0] / _UL)) * _UL); //结束的位置
// // _UDE[2] = Math.min(Math.ceil(ULE["X"] / this.W), _UL) - 1; _UDE[3] = Math.min(Math.ceil(ULE["BX"] / this.W), _UL) - 1; return _UDE;
//}
//#endregion
//#region 拖拉变化
///*
//* 获取元素选择范围
//*
//* @param {object} 拖选的元素
//* @param {object} 拖选的传参
//*/
//U.UF.F.dragTable = function (el, obj) {
// if (el) {
// obj = obj || {};
// new U.UF.F.dragTable.init(el, obj); //初始化拖选
// }
//}
///*
//* 拖动初始化
//*
//* @param {object} 拖选的元素
//* @param {object} 拖选的传参
//*/
//U.UF.F.dragTable.init = function (el, obj) {
// var _UDTD = U.selectEl(el),
// _UDSD = _UDTD.parentElement(), //上级元素
// _UDPD = _UDTD.prev(), //上面的兄弟节点
// _UDND = _UDTD.next(); //下面的兄弟节点
// //添加初始化值
// this.UDPD = _UDSD; //上级元素
// this.w = _UDSD.width(); //当前长度
// this.pw = _UDSD.parentElement().width(); //总长度
// this.el = el; //拖动的元素
// this.UE = U.UF.EL.getMousePosition(); //鼠标的位置
// this.prev = _UDPD; //上面的兄弟节点
// this.next = _UDND; //下面的兄弟节点
// this.uw = [_UDPD.width(), _UDND.width()]; //兄弟节点长度
// //拖动参数设置
// U.UF.C.AddObj(this, obj);
// //聚焦
// el.setCapture();
// //拖动元素
// U.selectEl(document.body).bind({
// "mousemove": (this.move = U.UF.C.apply(this, obj.tf ? this.dragB : this.drag)),
// "mouseup": (this.mup = function () { this.up(); })
// });
//}
//U.UF.F.dragTable.init.prototype = {
// //拖动左右使用
// drag: function () {
// var _UDVD = this.prev, //上级元素
// _UDND = this.next, //下面的兄弟节点
// _UW = this.uw, //不变的大小
// _UE = this.UE, //鼠标的位置
// _UME = U.UF.EL.getMousePosition(); //当前处理的鼠标位置
// _UME["X"] = Math.min(Math.max(-_UW[0], _UME["X"] - _UE["X"]), _UW[1]); _UDVD.css("width", _UW[0] + _UME["X"] + "px"); _UDND.css("width", _UW[1] + _UME["X"] + "px"); //拖动大小处理
// if (this.scb) { this.scb() }; //拖动回调
// },
// //拖动菜单
// dragB: function () {
// var _UW,
// _UDPD = this.UDPD, //上级元素
// _UDSD = this.prev, //上级元素
// _UPW = this.pw, //总长度
// _UW = this.uw[0], //上面兄弟节点的长度
// _UE = this.UE, //鼠标的位置
// _UME = U.UF.EL.getMousePosition(); //鼠标位置
// _UME["X"] = Math.max(-_UW, _UME["X"] - _UE["X"]); //获取left
// _UDSD.css("width", _UW + _UME["X"] + "px"); //设置下级兄弟的长度
// _UDPD.css("width", (_UW = (_UME["X"] + this.w)) > this.pw ? _UW + "px" : this.pw + "px"); //设置上级兄弟的长度
// if (this.scb) { this.scb() };
// },
// //拖动释放
// up: function () {
// this.el.releaseCapture(); //释放聚焦
// U.selectEl(document.body).unbind({ "mousemove": this.move, "mouseup": this.mup }); //释放拖动绑定
// if (this.upcb) { this.upcb() }; //回调处理
// }
//}
//#endregion
;
///
/*
1、检查UC里面还有没有自执行的函数。有的话添加此文件
2、重新归类整理所有的UC文件。主要的问题很多函数都是用U.UF.M的命名空间。每个文件开头要描述此文件是做什么的?
*/
U.UF.C.start = function () {
//加载String数据类型
U.UF.EV.addPrototype(String, U.UF.C.String);
//加载Number数据类型
U.UF.EV.addPrototype(Number, U.UF.C.Number);
//加载Array数据类型
U.UF.EV.addPrototype(Array, U.UF.C.Array);
//JSON方法的兼容
U.Json.init()
//生成系统兼容处理,兼容ie6以上,firefox,safiry,chrome
U.UF.CP.init();
//ArrayBuffer兼容处理
U.UF.S.ArrayBuffer();
//基础控件加载
U.UF.C.loadControls();
//手机端处理
//touch事件的处理方式
if ("ontouchstart" in document) {
U.UF.CP.touch();
}
}
/*
* 基础控件加载
*
*/
U.UF.C.loadControls = function () {
var _allscript = U.selectEl("script"), //获取页面上所有script标签
_flag = true, //用于设置是否需要引入基础控件,如果用户引入了全部控件,那么这个值为false。这个变量用于判断是否不再需要引入基础控件
i; //用户循环
//使用U.UF.CI.getUserPort()判断用户客户端是否为电脑端控件还是手机端。如果是电脑端,引入电脑端控件
//if (U.UF.CI.getUserPort()) {
//循环页面上所有的script标签
for (i = 0; i < _allscript.length; i++) {
//如果是复杂控件的话,那么引入复杂控件js和css文件
if ($(_allscript)[i].src == "/uform.js" && U.selectEl(_allscript).attr("include") === "complex") {
U.UF.DL.asynLoadJs({ type: "text/javascript", src: "/js/Controls/Complex.js" });
U.UF.DL.asynLoadCss({ "href": "/css/Controls/Complex.css", type: "text/css", rel: "stylesheet" });
}
//如果是全部控件的话,那么引入全部控件的js和css文件
if ($(_allscript)[i].src == "/uform.js" && U.selectEl(_allscript).attr("include") === "all") {
U.UF.DL.asynLoadJs({ type: "text/javascript", src: "/js/Controls/index.js" });
U.UF.DL.asynLoadCss({ "href": "/css/Controls/index.css", type: "text/css", rel: "stylesheet" });
_flag = false; //设置基础控件变量为false,因为引入了全部的控件,已经不需要再次引入基础控件了。
}
}
//如果引入了全部的控件,那么该变量的值会为false。
if (_flag) {
U.UF.DL.asynLoadJs({ type: "text/javascript", src: "/js/Controls/Basic.js" });
U.UF.DL.asynLoadCss({ "href": "/css/Controls/Basic.css", type: "text/css", rel: "stylesheet" });
}
//}
//如果是手机端控件,引入手机端的控件
// else {
// //循环页面上所有的script标签
// for (i = 0; i < _allscript.length; i++) {
// //如果是复杂控件的话,那么引入复杂控件js和css文件
// if ($(_allscript)[i].src == "/uform.js" && U.selectEl(_allscript).attr("include") === "mtcomplex") {
// U.UF.DL.asynLoadJs({ type: "text/javascript", src: "http://m.1473.cn/Js/Controls/Complex.js" });
// U.UF.DL.asynLoadCss({ "href": "http://m.1473.cn/Css/Controls/Complex.css", type: "text/css", rel: "stylesheet" });
// }
// //如果是全部控件的话,那么引入全部控件的js和css文件
// if ($(_allscript)[i].src == "/uform.js" && U.selectEl(_allscript).attr("include") === "mtall") {
// U.UF.DL.asynLoadJs({ type: "text/javascript", src: "http://m.1473.cn/Js/Controls/index.js" });
// U.UF.DL.asynLoadCss({ "href": "http://m.1473.cn/Css/Controls/index.css", type: "text/css", rel: "stylesheet" });
// _flag = false; //设置基础控件变量为false,因为引入了全部的控件,已经不需要再次引入基础控件了。
// }
// }
// //如果引入了全部的控件,那么该变量的值会为false。
// if (_flag) {
// U.UF.DL.asynLoadJs({ type: "text/javascript", src: "http://m.1473.cn/Js/Controls/Basic.js" });
// U.UF.DL.asynLoadCss({ "href": "http://m.1473.cn/Css/Controls/Basic.css", type: "text/css", rel: "stylesheet" });
// }
// }
}
U.UF.C.start(); //执行;
///
Namespace.register("U.MD.U.L"); //用户登录的命名空间
Namespace.register("U.MD.U.LO"); //用户登出的命名空间
//#region 登录
/*
问题:
1、验证码的接口问题
2、无窗体的接口
*/
//#region 配置数据
U.MD.U.L.loginCallBack; //登录后的回调使用
U.MD.U.L.isLogining = false; //判断用户登录状态。cookie登录状态为cookie,账号登录为true,没有登录为false
//#endregion
/**
* 弹出登录注册
*
* @param {int} type==3:登录页面,type==1:注册页面,type==2:找回密码页面
* @param {function} cb为回调函数
* @returns {boolean} 是否登录
*/
U.MD.U.L.login = U.MD.U.L.DLTC = function (fun) {
var _iframe = U.selectEl("#U_MD_HomeC_Pop iframe")[0];
if ($("#U_MD_HomeC_Pop")[0]) {
U.UF.F.windowTopCenter($("#U_MD_HomeC_Pop")[0]);
if (U.UF.C.queryString('code')) {
$("#U_MD_HomeC_Pop iframe")[0].contentWindow.location.reload(true);
}
try {
//登录有的其他回调,如,登陆后直接打开好友聊天等
if (U.UF.C.isFunction(fun)) {
U.MD.U.L.loginCallBack = fun; //回调处理
}
U.selectEl("input", _iframe.contentWindow.document)[0].focus();
_iframe.contentWindow.U.MD.U.L.init();
}
catch (e) { }
}
else {
if (U.UF.C.queryString('code')) {
var _iframe = $$("iframe", { "frameborder": "no", "border": "0", "scrolling ": "no", "style": { "cssText": "border:0; width:100%; height:100%;" }, "id": "UI_Login", "name": "UI_Login", "frameborder": "no", "border": "0", "scrolling ": "no", "src": US.Config.bpbl + "/pbl-teacher-table/dist/#/inviteLogin?code=" + U.UF.C.queryString('code') });
// var _iframe = $$("iframe", { "frameborder": "no", "border": "0", "scrolling ": "no", "style": { "cssText": "border:0; width:100%; height:100%;" }, "id": "UI_Login", "name": "UI_Login", "frameborder": "no", "border": "0", "scrolling ": "no", "src": "http://localhost:8080/#/inviteLogin?code="+U.UF.C.queryString('code') });
new U.UF.UI.form("登录", _iframe,
{
"id": "U_MD_HomeC_Pop",
"style": { "width": "490px", "height": "660px", "overflow": 'hidden', 'borderRadius': '10px' },
},
{
isdrag: false,
isstretching: false,
isenlarge: false,
isnarrow: false
}, { "style": { "height": "36px" }});
}else{
var _iframe = $$("iframe", { "frameborder": "no", "border": "0", "scrolling ": "no", "style": { "cssText": "border:0; width:100%; height:100%;" }, "id": "UI_Login", "name": "UI_Login", "frameborder": "no", "border": "0", "scrolling ": "no", "width": "360px", "height": "480px", "src": "https://edu.cocorobo.hk/LoginIframe?type=2" });
new U.UF.UI.form("", _iframe,
{
"id": "U_MD_HomeC_Pop",
"style": { "width": "500px", "height": "90%", "overflow": 'hidden' },
},
{
isdrag: false,
isstretching: false,
isenlarge: false,
isnarrow: false
});
//跨域回调设置
U.UF.DL.iframeLoad(_iframe, function () {
//登录有的其他回调,如,登陆后直接打开好友聊天等
if (U.UF.C.isFunction(fun)) {
U.MD.U.L.loginCallBack = fun; //回调处理
}
_iframe.contentWindow.U.MD.U.L.loginCallBack = U.MD.U.L.defaultCallBack; //设置登录回调
});
}
}
return _iframe;
}
/**
* 打开注册窗体
*/
U.MD.U.L.register = function (fun) {
var _iframe = U.MD.U.L.login();
try {
_iframe.contentWindow.U.MD.U.R.register();
}
catch (e) {
U.UF.DL.iframeLoad(_iframe, function () {
//登录有的其他回调,如,登陆后直接打开好友聊天等
if (U.UF.C.isFunction(fun)) {
U.MD.U.L.loginCallBack = fun; //回调处理
}
_iframe.contentWindow.U.MD.U.L.loginCallBack = U.MD.U.L.defaultCallBack; //设置登录回调
_iframe.contentWindow.U.UF.N.addHash('register'); //添加hash的处理
});
}
}
/**
* 打开找回密码窗体
*/
U.MD.U.L.retrieve = function () {
var _iframe = U.MD.U.L.login();
try {
_iframe.contentWindow.U.MD.U.F.findPassword();
}
catch (e) {
U.UF.DL.iframeLoad(_iframe, function () {
_iframe.contentWindow.U.UF.N.addHash('findPassword'); //添加hash的处理
});
}
}
/**
* 登录异步
*
* @param {object} 服务器返回的值
* @param {boolean} 是否是cookie登录
*/
U.MD.U.L.defaultCallBack = function (r, iscookie) {
var _userinfo, //用户个人信息
_backgroudimage, //背景图片
_str, //输出的提示
_context = r.context, //回调参数
_address = _context[1], //触发函数的地址
_username = _context[2], //用户名
_password = _context[3]; //密码
//登录后台返回的数据
r = r.value;
//判断登录状态
switch (r) {
case null:
_str = "系统繁忙!请重试";
break; //系统繁忙
case 0:
_str = "帐号不存在!";
break;
case 1:
_str = "密码错误!";
break; //帐号密码错误
case 2:
_str = "该用户不允许被访问!请联系管理员";
break; //用户给禁用
default:
if (r) {
//登录有的其他回调,如,登陆后直接打开好友聊天等
U.MD.U.LO.emptyUserInfo(); //登陆的时候先清空用户信息,防止前面登陆用户的信息有冲突
//如果刚刚登陆的时候没有用户的地址,这里重新获取,然后向后台发送
if (!_address) {
U.UF.CI.getUserLocation(U.MD.U.L.addUserAccess); //客户端信息加载,好像只加载了新浪ip地址?
}
_userinfo = U.MD.U.L.setUserInfo(r); //设置用户基本信息,包括用户信息,好友信息
U.MD.U.L.getLoginUserInfo(_username || US.userInfo.UserName); //去获取用户详细信息
if ($("#U_MD_D_BDI")[0] && U.selectEl('#U_MD_D_BG')[0]) {
//登录有用户的信息展示到页面中,包括背景图片、用户头像等
U.MD.U.L.printUserInfo(); //用户头部头像个人信息
_backgroudimage = U.MD.D.B.split(US.userInfo.UserBackGroundImage); //拆分用户的背景图片,里面包含了图片地址和展示的格式
U.MD.D.B.setBackgroundImage(_backgroudimage[0], _backgroudimage[1]); //设置用户背景图,以后需修改为设置用户桌面信息
}
//Cookie登录,即使密码错误也不弹出错误信息。
if (_str && iscookie !== true) {
U.alert(_str); //登录提示处理
}
//如果弹出了登录框,那么给登录框进行处理
if ($("#U_MD_HomeC_Pop")[0]) {
//登录框的样式还原
U.selectEl("#U_MD_HomeC_Pop")[0].close(); //关闭登陆款
}
U.MD.O && U.MD.O.P.connect();
}
// _str = "登录成功";
}
if (_str) {
U.alert(_str);
}
}
/**
* 判断用户是否登录如果未登陆则弹出登陆框
*
*/
U.MD.U.L.isLogin = function (fun) {
if (!US.userInfo.userid) { //判断用户id是否存在
U.MD.U.L.login(fun); //用户登录函数
return true; //用户未登录返回false
}
return false; //用户登录返回true
}
/**
* 登录调用回调使用
* @param {function} 回调函数
*
*/
U.MD.U.L.setLoginCallBack = function (fun) {
//未登录要求登录
if (U.MD.U.L.isLogin()) {
U.MD.U.L.loginCallBack = fun;
}
//登录直接转发
else {
fun();
return true;
}
}
//#endregion
//#region cookie登录
/*
功能:1473.cn域下各个应用的用户通过Cookie自动登录,Cookie登录入口。支持跨域
*/
U.MD.U.L.cookieLogin = function () {
var _cookie = U.MD.U.L.getCookieByUserId(), //获取用户的云端Cookie,选取最后一个账号进行登录。
_address = US.city.userAllLocation || ""; //找到自己登陆用户的地址
//如果获取到cookie的值,那么就进行cookie登陆
if (_cookie && _cookie.userid && _cookie.userid.length == 36) {
U.MD.U.L.isLogining = "cookie"; //设置cookie登陆状态
U.A.Request(US.USER, ["LoginByCookie", _cookie.userid, _cookie.username], U.MD.U.L.defaultCallBack, ["", _address]); //调用cookie登陆处理
}
}
/*
功能:获取用户cookie,云端cookie关键字为usestudiosso,格式为
Loginid:登录id
userstamp:账号13928417148的值为"1364812396"?奇怪?
userid:云端用户id
username:云端用户名
如果不传入参数,默认获取最后一个,否则获取传入userid的账号进行登录。
参数一:userid代表用户id。传入用户id,则判断cookie中是否有该账号,并使用该账号登录。
*/
U.MD.U.L.getCookieByUserId = function (userid) {
var i, _cookiearr = U.MD.U.L.cookieToArray("usestudiosso"); //获取保存的cookie值。
//如果传入参数userid并且cookie中有userid。则判断是否是自己的账号登录。
if (_cookiearr.userid) {
//如果传了userid,那么就根据userid找
if (userid) {
//数组里匹配
for (i = 0; i < _cookiearr.userid.length; i++) {
if (_cookiearr.userid[i] == userid) {
break;
}
}
}
//否则找到最后一个登陆用户的信息
else {
//允许多用户登录,则用户id减少一?
i = _cookiearr.userid.length - 1;
}
//循环所有Cookie。
for (var c in _cookiearr) {
//对中文进行解密。_cookiearr[c]中可能有多个userid,只获取最后选中的第i个。返回的数据在这里做了处理。
_cookiearr[c] = decodeURIComponent(_cookiearr[c][i]);
}
}
//返回的集合包括了Loginid:登录iduserstamp:账号13928417148的值为"1364812396"?奇怪?userid:云端用户idusername:云端用户名
return _cookiearr;
}
/**
*1473cookie格式专用
* 把形如:"userid=72854d28-f45c-48d7-92b7-3cd933e03022&username=13928417148&Loginid=fd02976d-993b-4437-bbd9-5efa99802c8f&userstamp=1364812396"的cookie转换为json对象。函数名有问题。
得到的形式为:_UAE.Loginid可得到用户id。
*
* @param {string} 获取cookie的key对应的值 如usestudio=aa=ff&ss=aa 的usestudio里的 aa=ff&ss=aa
* @return {object} {key:[value1,value2]}
*/
U.MD.U.L.cookieToArray = function (key) { //获取cookie
var i, //循环初始化
_cookieobj = {}, //初始化对象 作为返回值
_cookie = U.UF.Cookie.get("usestudiosso"); //获取用户指定的Cookie值
if (_cookie) { //是否存在
_cookie = _cookie.split("&");
for (i = 0; i < _cookie.length; i++) { //循环对应的值
_cookie[i] = _cookie[i].split("="); //切分key和value
//如果定义了cookie值的接受数组,则不再重复定义。_cookie[i][0]相当于key,例如userid
if (!_cookieobj[_cookie[i][0]]) {
_cookieobj[_cookie[i][0]] = [];
}
_cookieobj[_cookie[i][0]].push(decodeURIComponent(_cookie[i][1])); //生成{key:[value1,value2]}
}
}
return _cookieobj;
}
//#endregion
//#region 登录数据使用
/**
* 为了以后的扩展,给其他系统获取完整的用户信息,获取用户登录数据,后面还有一个登陆获取用户个人信息。好友信息,及消息通知,逻辑有问题。
* @param {string} 用户名
*
*/
U.MD.U.L.getLoginUserInfo = function (username) {
U.A.Request(US.USER, ["GetUserLoginData", username], U.MD.U.L.asynGetLoginUserInfo);
}
/**
* 异步获取数据
* @param {object} ajax返回的数据值
*
*/
U.MD.U.L.asynGetLoginUserInfo = function (r) {
r = r.value; //得到登录用户的数据
US.friend = r; //返回的r里面是用户的好友信息 包括 {"className":好友分组信息,friends:好友信息,group:好友群,groupusers:群好友,recentcontacts:最近联系人,unreadfirendmessage:未读好友消息,unreadgroupmessage:未读群消息,commonfriend:推荐好友}
U.MD.U.L.initUserLogin(US.userInfo); //登录初始化应用
if (U.MD.D && U.MD.D.IsUseStudio || U.selectEl("#usestudio_server")[0]) {
U.MD.F && U.MD.F.N.friendMessageHandle([r.unreadfirendmessage, r.unreadgroupmessage]); //用户消息区域
}
}
/**
* 添加用户初始化资料信息
* @param {array} 登录用户的数据
*
*/
U.MD.U.L.setUserInfo = function (userinfo) {
US.userInfo = userinfo[0]; //给用户信息全局变量赋值。
US.userInfo.LoginId = userinfo[2]; //用户前后台更新数据唯一识别id
US.friend.onlinefirendinfo = userinfo[1]; //添加在线信息。
return US.userInfo;
}
//登录成功执行事件
U.MD.U.L.initUserLogin = function () {
var _userinfo = US.userInfo; //初始化用户资料
U.MD.UI && U.MD.UI.flashEmptyUpload && U.MD.UI.flashEmptyUpload(); //清理上传文件
//登录有的其他回调,如,登陆后直接打开好友聊天等
if (U.UF.C.isFunction(U.MD.U.L.loginCallBack)) {
U.MD.U.L.loginCallBack(_userinfo); //回调处理
}
U.MD.F && U.MD.F.initFriend(); //初始化好友
//如果没有用url指引,同时又是1473的项目,那么弹出云盘,否则只是加载数据
if (U.MD.D && U.MD.D.IsUseStudio) {
U.MD.D.I.openApplication("disk", { "userid": _userinfo.UserId, "directoryid": US.FTPFOLDERID }); //弹出云盘的数据。
}
//外部加载1473框架的都会带有usestudio_server 这个元素,当用户没有填写邮箱信息的时候,同时是在1473主站点的,那么就弹出用户
if (!US.userInfo.UserEmail && !$("#usestudio_server")[0]) {
U.MD.U.P.userDataSet(); //用户数据加载
}
}
/**
* 添加用户登录信息
*
*/
U.MD.U.L.addUserAccess = function () {
//如果用户的城市信息不存在,则添加用户用户城市信息,应该不只是单单判断地址,此处逻辑还需要整理!
if (US.city.userAllLocation) {
U.A.Request(US.USER, ["RecordUserClientInfo", US.userInfo.UserName, "", "", US.city.userAllLocation, ""],
function () { }); //异步添加地址信息
}
}
/**
* 打印用户的信息
*
*/
U.MD.U.L.printUserInfo = function () {
var _childel,
_userinfo = US.userInfo, //用户的信息
_userimage = U.MD.C.getHeadImage(_userinfo.UserThumbnailImageHead), //获取用户头像
_el = U.selectEl("#U_MD_D_BDI"); //头像打印的区域
if (_el[0]) {
//设置头部的样式变化
_el.addAttrArray({
"className": "U_MD_D_BDI"
})[0];
//如果已经有头像了,那么直接修改头像
if (_el.find("img")[0]) {
//设置头像处理
_el.find("img").addAttrArray({
"onerror": U.MD.C.imgError,
"title": _userinfo.UserNickName,
"onclick": function () {
U.MD.D.I.openApplication("set");
},
"src": U.MD.C.getHeadImage(_userinfo.UserThumbnailImageHead)
});
}
//创建头像的处理
else {
$$("img", {
"onerror": U.MD.C.imgError,
"onerror": U.MD.C.imgError,
"title": _userinfo.UserNickName,
"onclick": function () {
U.MD.D.I.openApplication("set");
},
"src": U.MD.C.getHeadImage(_userinfo.UserThumbnailImageHead)
}, _el[0])
}
_childel = U.selectEl("#U_MD_D_BDL").Child();
_childel[0].style.display = _childel[1].style.display = "none";
_childel[2].style.display = "block";
}
}
//#endregion
//#region 退出
/**
* 退出登录提示
*
* @param callback {function} 登出回调函数
*/
U.MD.U.LO.logoutSystem = function (callback) {
//如果用户登录的情况
if (US.userInfo.userid) {
//弹出退出登录的提示
U.UF.UI.confirm("是否退出" + US.userInfo.username + "账号", function () {
U.A.Request(US.Config.server + "logout", [], function (res) {
U.A.Request(US.SCOKET, ["logout", US.userInfo.userid, US.pageId], function () {
U.alert("退出成功!")
window.location.reload();
}, [], { "type": "POST", "withCredentials": true }); //在状态服务退出
}, [], { "type": "POST", "withCredentials": true });
});
}
}
/**
* 禁止登录 执行推出
*
* @param callback {function} 登出回调函数
*/
U.MD.U.LO.logoutSystem2 = function (callback) {
//如果用户登录的情况
if (US.userInfo.userid) {
//弹出退出登录的提示
// U.UF.UI.confirm("是否退出" + US.userInfo.username + "账号", function () {
U.alert("您的账号已禁止登陆!")
U.A.Request(US.Config.server + "logout", [], function (res) {
U.A.Request(US.SCOKET, ["logout", US.userInfo.userid, US.pageId], function () {
setTimeout(() => {
window.location.reload();
}, 2000);
}, [], { "type": "POST", "withCredentials": true }); //在状态服务退出
}, [], { "type": "POST", "withCredentials": true });
// });
}
}
//确定注销
//b为是否清除cookie的参数。如果传递false,则清除cookie。
/**
* 退出登录的处理
*
*/
U.MD.U.LO.logout = function (callback) {
// if (U.MD.O) {
// //获取office内容
// // U.A.Request(US.SCOKET, ['logout', US.userInfo.userid, US.pageId], function () { });
// }
U.MD.U.LO.clearCookie(function () {
U.MD.U.LO.emptyUserInfo(); //清楚用户的前端的数据
if ($('#UI_Login')[0]) {
U.selectEl('#UI_Login')[0].contentWindow.U.MD.U.OT.logout(); //如果是第三方平台登录的,在第三方平台进行下线
}
//清理图形界面的处理
if ($("#U_MD_D_BDI")[0]) {
//清空所有的应用
U.MD.U.LO.logoutStyle(); //清除注册样式
U.MD.D.T.taskbar.clear(); //任务栏清除
U.UF.UI.form.closeWindows(); //关闭所有的窗体
}
U.UF.C.isFunction(callback) && callback();
}); //退出账号的cookie
}
/**
* 用户退出指定帐号 清理cookie
*
*/
U.MD.U.LO.clearCookie = function (callback) {
//判断用户是否登录
if (US.userInfo.userid) {
var _iscookie = U.UF.Cookie.get("usestudiosso", "userid").indexOf(US.userInfo.userid) > -1; //判断cookie是否还存在用户的id
//如果存在cookie的出力
if (_iscookie) {
//调用后台,让用户注销
U.A.Request(US.USER, ["UserOffline", US.userInfo.userid], function () { U.UF.C.isFunction(callback) && callback(); });
} else {
U.UF.C.isFunction(callback) && callback();
}
}
}
/**
* 清空用户前端的信息
*
*/
U.MD.U.LO.emptyUserInfo = function () {
US.userInfo = {}; //用户数据清空
US.friend = {}; //用户好友信息清空
if ($("#U_MD_D_BG")[0]) {
U.MD.D.B.setBackgroundImage(U.MD.D.B.url); //设置默认背景
}
}
/**
* 注销样式
*
*/
U.MD.U.LO.logoutStyle = function () {
//清楚登录用户的样式
U.selectEl("#U_MD_D_BDI").addAttrArray({
"innerHTML": "",
"className": "U_MD_D_BDI U_Img"
});
//获取子元素
var _childel = U.selectEl("#U_MD_D_BDL").childs();
_childel[0].style.display = _childel[1].style.display = "block"; //显示登录注册
_childel[2].style.display = "none"; //隐藏提出按钮
//右边好友框隐藏
U.selectEl("#U_MD_F_H_R").css("display", "none");
//隐藏消息提醒
U.selectEl("#U_MD_D_MG_OA").Parent(2).style.display = "none";
//隐藏所有的窗体
// U.selectEl("#U_MD_Home").childs().css("display", "none");
}
//#endregion
//#region 外链登录
Namespace.register("U.MD.U.OT"); //用户登录的命名空间
/**
* 填写登录信息
*
* @param {array} 登录值参数
* @param {array} 回调函数
*/
U.MD.U.OT.perfectUserInfo = function (userinfo, username) {
if ($("#U_MD_U_OT_B_Pop")[0]) {
U.UF.F.windowTopCenter($("#U_MD_U_OT_B_Pop")[0]);
}
else {
var _iframe = $$("iframe", { "style": { "border": "0", "float": "left" }, "id": "U_MD_U_OT_B_Iframe", "name": "UI_Login", "frameborder": "0", "width": "400px", "height": "290px", "src": US.MAINDOMAIN + "/CompleteInformation.htm" });
new U.UF.UI.form("", _iframe,
{
"id": "U_MD_U_OT_B_Pop",
"style": {
"width": "400px",
"height": "340px"
}
},
{
isdrag: false,
isstretching: false,
isenlarge: false,
isnarrow: false
});
//跨域回调设置
U.UF.DL.iframeLoad(_iframe, function () {
if ($("#U_MD_HomeC_Pop")[0]) {
U.selectEl("#U_MD_HomeC_Pop")[0].close();
}
_iframe.contentWindow.U.MD.U.OT.perfectUserInfoInit(userinfo, username); //设置登录回调
});
}
}
//#endregion
;
///
//#region 加密区域
Namespace.register("U.UF.EC"); //加密
/*
* Fastest md5 implementation around (JKM md5).
* Credits: Joseph Myers
*
* @see http://www.myersdaily.org/joseph/javascript/md5-text.html
* @see http://jsperf.com/md5-shootout/7
*/
/* this function is much faster,
so if possible we use it. Some IEs
are the only ones I know of that
need the idiotic second function,
generated by an if clause. */
U.UF.EC.add32 = function (a, b) {
return (a + b) & 0xFFFFFFFF;
};
U.UF.EC.hex_chr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
U.UF.EC.cmn = function (q, a, b, x, s, t) {
a = U.UF.EC.add32(U.UF.EC.add32(a, q), U.UF.EC.add32(x, t));
return U.UF.EC.add32((a << s) | (a >>> (32 - s)), b);
}
U.UF.EC.md5cycle = function (x, k) {
var a = x[0],
b = x[1],
c = x[2],
d = x[3];
a += (b & c | ~b & d) + k[0] - 680876936 | 0;
a = (a << 7 | a >>> 25) + b | 0;
d += (a & b | ~a & c) + k[1] - 389564586 | 0;
d = (d << 12 | d >>> 20) + a | 0;
c += (d & a | ~d & b) + k[2] + 606105819 | 0;
c = (c << 17 | c >>> 15) + d | 0;
b += (c & d | ~c & a) + k[3] - 1044525330 | 0;
b = (b << 22 | b >>> 10) + c | 0;
a += (b & c | ~b & d) + k[4] - 176418897 | 0;
a = (a << 7 | a >>> 25) + b | 0;
d += (a & b | ~a & c) + k[5] + 1200080426 | 0;
d = (d << 12 | d >>> 20) + a | 0;
c += (d & a | ~d & b) + k[6] - 1473231341 | 0;
c = (c << 17 | c >>> 15) + d | 0;
b += (c & d | ~c & a) + k[7] - 45705983 | 0;
b = (b << 22 | b >>> 10) + c | 0;
a += (b & c | ~b & d) + k[8] + 1770035416 | 0;
a = (a << 7 | a >>> 25) + b | 0;
d += (a & b | ~a & c) + k[9] - 1958414417 | 0;
d = (d << 12 | d >>> 20) + a | 0;
c += (d & a | ~d & b) + k[10] - 42063 | 0;
c = (c << 17 | c >>> 15) + d | 0;
b += (c & d | ~c & a) + k[11] - 1990404162 | 0;
b = (b << 22 | b >>> 10) + c | 0;
a += (b & c | ~b & d) + k[12] + 1804603682 | 0;
a = (a << 7 | a >>> 25) + b | 0;
d += (a & b | ~a & c) + k[13] - 40341101 | 0;
d = (d << 12 | d >>> 20) + a | 0;
c += (d & a | ~d & b) + k[14] - 1502002290 | 0;
c = (c << 17 | c >>> 15) + d | 0;
b += (c & d | ~c & a) + k[15] + 1236535329 | 0;
b = (b << 22 | b >>> 10) + c | 0;
a += (b & d | c & ~d) + k[1] - 165796510 | 0;
a = (a << 5 | a >>> 27) + b | 0;
d += (a & c | b & ~c) + k[6] - 1069501632 | 0;
d = (d << 9 | d >>> 23) + a | 0;
c += (d & b | a & ~b) + k[11] + 643717713 | 0;
c = (c << 14 | c >>> 18) + d | 0;
b += (c & a | d & ~a) + k[0] - 373897302 | 0;
b = (b << 20 | b >>> 12) + c | 0;
a += (b & d | c & ~d) + k[5] - 701558691 | 0;
a = (a << 5 | a >>> 27) + b | 0;
d += (a & c | b & ~c) + k[10] + 38016083 | 0;
d = (d << 9 | d >>> 23) + a | 0;
c += (d & b | a & ~b) + k[15] - 660478335 | 0;
c = (c << 14 | c >>> 18) + d | 0;
b += (c & a | d & ~a) + k[4] - 405537848 | 0;
b = (b << 20 | b >>> 12) + c | 0;
a += (b & d | c & ~d) + k[9] + 568446438 | 0;
a = (a << 5 | a >>> 27) + b | 0;
d += (a & c | b & ~c) + k[14] - 1019803690 | 0;
d = (d << 9 | d >>> 23) + a | 0;
c += (d & b | a & ~b) + k[3] - 187363961 | 0;
c = (c << 14 | c >>> 18) + d | 0;
b += (c & a | d & ~a) + k[8] + 1163531501 | 0;
b = (b << 20 | b >>> 12) + c | 0;
a += (b & d | c & ~d) + k[13] - 1444681467 | 0;
a = (a << 5 | a >>> 27) + b | 0;
d += (a & c | b & ~c) + k[2] - 51403784 | 0;
d = (d << 9 | d >>> 23) + a | 0;
c += (d & b | a & ~b) + k[7] + 1735328473 | 0;
c = (c << 14 | c >>> 18) + d | 0;
b += (c & a | d & ~a) + k[12] - 1926607734 | 0;
b = (b << 20 | b >>> 12) + c | 0;
a += (b ^ c ^ d) + k[5] - 378558 | 0;
a = (a << 4 | a >>> 28) + b | 0;
d += (a ^ b ^ c) + k[8] - 2022574463 | 0;
d = (d << 11 | d >>> 21) + a | 0;
c += (d ^ a ^ b) + k[11] + 1839030562 | 0;
c = (c << 16 | c >>> 16) + d | 0;
b += (c ^ d ^ a) + k[14] - 35309556 | 0;
b = (b << 23 | b >>> 9) + c | 0;
a += (b ^ c ^ d) + k[1] - 1530992060 | 0;
a = (a << 4 | a >>> 28) + b | 0;
d += (a ^ b ^ c) + k[4] + 1272893353 | 0;
d = (d << 11 | d >>> 21) + a | 0;
c += (d ^ a ^ b) + k[7] - 155497632 | 0;
c = (c << 16 | c >>> 16) + d | 0;
b += (c ^ d ^ a) + k[10] - 1094730640 | 0;
b = (b << 23 | b >>> 9) + c | 0;
a += (b ^ c ^ d) + k[13] + 681279174 | 0;
a = (a << 4 | a >>> 28) + b | 0;
d += (a ^ b ^ c) + k[0] - 358537222 | 0;
d = (d << 11 | d >>> 21) + a | 0;
c += (d ^ a ^ b) + k[3] - 722521979 | 0;
c = (c << 16 | c >>> 16) + d | 0;
b += (c ^ d ^ a) + k[6] + 76029189 | 0;
b = (b << 23 | b >>> 9) + c | 0;
a += (b ^ c ^ d) + k[9] - 640364487 | 0;
a = (a << 4 | a >>> 28) + b | 0;
d += (a ^ b ^ c) + k[12] - 421815835 | 0;
d = (d << 11 | d >>> 21) + a | 0;
c += (d ^ a ^ b) + k[15] + 530742520 | 0;
c = (c << 16 | c >>> 16) + d | 0;
b += (c ^ d ^ a) + k[2] - 995338651 | 0;
b = (b << 23 | b >>> 9) + c | 0;
a += (c ^ (b | ~d)) + k[0] - 198630844 | 0;
a = (a << 6 | a >>> 26) + b | 0;
d += (b ^ (a | ~c)) + k[7] + 1126891415 | 0;
d = (d << 10 | d >>> 22) + a | 0;
c += (a ^ (d | ~b)) + k[14] - 1416354905 | 0;
c = (c << 15 | c >>> 17) + d | 0;
b += (d ^ (c | ~a)) + k[5] - 57434055 | 0;
b = (b << 21 | b >>> 11) + c | 0;
a += (c ^ (b | ~d)) + k[12] + 1700485571 | 0;
a = (a << 6 | a >>> 26) + b | 0;
d += (b ^ (a | ~c)) + k[3] - 1894986606 | 0;
d = (d << 10 | d >>> 22) + a | 0;
c += (a ^ (d | ~b)) + k[10] - 1051523 | 0;
c = (c << 15 | c >>> 17) + d | 0;
b += (d ^ (c | ~a)) + k[1] - 2054922799 | 0;
b = (b << 21 | b >>> 11) + c | 0;
a += (c ^ (b | ~d)) + k[8] + 1873313359 | 0;
a = (a << 6 | a >>> 26) + b | 0;
d += (b ^ (a | ~c)) + k[15] - 30611744 | 0;
d = (d << 10 | d >>> 22) + a | 0;
c += (a ^ (d | ~b)) + k[6] - 1560198380 | 0;
c = (c << 15 | c >>> 17) + d | 0;
b += (d ^ (c | ~a)) + k[13] + 1309151649 | 0;
b = (b << 21 | b >>> 11) + c | 0;
a += (c ^ (b | ~d)) + k[4] - 145523070 | 0;
a = (a << 6 | a >>> 26) + b | 0;
d += (b ^ (a | ~c)) + k[11] - 1120210379 | 0;
d = (d << 10 | d >>> 22) + a | 0;
c += (a ^ (d | ~b)) + k[2] + 718787259 | 0;
c = (c << 15 | c >>> 17) + d | 0;
b += (d ^ (c | ~a)) + k[9] - 343485551 | 0;
b = (b << 21 | b >>> 11) + c | 0;
x[0] = a + x[0] | 0;
x[1] = b + x[1] | 0;
x[2] = c + x[2] | 0;
x[3] = d + x[3] | 0;
}
U.UF.EC.md5blk = function (s) {
var md5blks = [],
i; /* Andy King said do it this way. */
for (i = 0; i < 64; i += 4) {
md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24);
}
return md5blks;
}
U.UF.EC.md5blk_array = function (a) {
var md5blks = [],
i; /* Andy King said do it this way. */
for (i = 0; i < 64; i += 4) {
md5blks[i >> 2] = a[i] + (a[i + 1] << 8) + (a[i + 2] << 16) + (a[i + 3] << 24);
}
return md5blks;
}
U.UF.EC.md51 = function (s) {
var n = s.length,
state = [1732584193, -271733879, -1732584194, 271733878],
i,
length,
tail,
tmp,
lo,
hi;
for (i = 64; i <= n; i += 64) {
U.UF.EC.md5cycle(state, U.UF.EC.md5blk(s.substring(i - 64, i)));
}
s = s.substring(i - 64);
length = s.length;
tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
for (i = 0; i < length; i += 1) {
tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3);
}
tail[i >> 2] |= 0x80 << ((i % 4) << 3);
if (i > 55) {
U.UF.EC.md5cycle(state, tail);
for (i = 0; i < 16; i += 1) {
tail[i] = 0;
}
}
// Beware that the final length might not fit in 32 bits so we take care of that
tmp = n * 8;
tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
lo = parseInt(tmp[2], 16);
hi = parseInt(tmp[1], 16) || 0;
tail[14] = lo;
tail[15] = hi;
U.UF.EC.md5cycle(state, tail);
return state;
}
U.UF.EC.md51_array = function (a) {
var n = a.length,
state = [1732584193, -271733879, -1732584194, 271733878],
i,
length,
tail,
tmp,
lo,
hi;
for (i = 64; i <= n; i += 64) {
U.UF.EC.md5cycle(state, U.UF.EC.md5blk_array(a.subarray(i - 64, i)));
}
// Not sure if it is a bug, however IE10 will always produce a sub array of length 1
// containing the last element of the parent array if the sub array specified starts
// beyond the length of the parent array - weird.
// https://connect.microsoft.com/IE/feedback/details/771452/typed-array-subarray-issue
a = (i - 64) < n ? a.subarray(i - 64) : new Uint8Array(0);
length = a.length;
tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
for (i = 0; i < length; i += 1) {
tail[i >> 2] |= a[i] << ((i % 4) << 3);
}
tail[i >> 2] |= 0x80 << ((i % 4) << 3);
if (i > 55) {
U.UF.EC.md5cycle(state, tail);
for (i = 0; i < 16; i += 1) {
tail[i] = 0;
}
}
// Beware that the final length might not fit in 32 bits so we take care of that
tmp = n * 8;
tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
lo = parseInt(tmp[2], 16);
hi = parseInt(tmp[1], 16) || 0;
tail[14] = lo;
tail[15] = hi;
U.UF.EC.md5cycle(state, tail);
return state;
}
U.UF.EC.rhex = function (n) {
var s = '',
j;
for (j = 0; j < 4; j += 1) {
s += U.UF.EC.hex_chr[(n >> (j * 8 + 4)) & 0x0F] + U.UF.EC.hex_chr[(n >> (j * 8)) & 0x0F];
}
return s;
}
U.UF.EC.hex = function (x) {
var i;
for (i = 0; i < x.length; i += 1) {
x[i] = U.UF.EC.rhex(x[i]);
}
return x.join('');
}
//此处需要预先执行?
// In some cases the fast U.UF.EC.add32 function cannot be used..
/*if (U.UF.EC.hex(U.UF.EC.md51('hello')) !== '5d41402abc4b2a76b9719d911017c592') {
U.UF.EC.add32 = function (x, y) {
var lsw = (x & 0xFFFF) + (y & 0xFFFF),
msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xFFFF);
};
}*/
// ---------------------------------------------------
// ---------------------------------------------------
/**
* Helpers.
*/
U.UF.EC.toUtf8 = function (str) {
if (/[\u0080-\uFFFF]/.test(str)) {
str = unescape(encodeURIComponent(str));
}
return str;
}
U.UF.EC.utf8Str2ArrayBuffer = function (str, returnUInt8Array) {
var length = str.length,
buff = new ArrayBuffer(length),
arr = new Uint8Array(buff),
i;
for (i = 0; i < length; i += 1) {
arr[i] = str.charCodeAt(i);
}
return returnUInt8Array ? arr : buff;
}
U.UF.EC.arrayBuffer2Utf8Str = function (buff) {
return String.fromCharCode.apply(null, new Uint8Array(buff));
}
U.UF.EC.concatenateArrayBuffers = function (first, second, returnUInt8Array) {
var result = new Uint8Array(first.byteLength + second.byteLength);
result.set(new Uint8Array(first));
result.set(new Uint8Array(second), first.byteLength);
return returnUInt8Array ? result : result.buffer;
}
U.UF.EC.hexToBinaryString = function (hex) {
var bytes = [],
length = hex.length,
x;
for (x = 0; x < length - 1; x += 2) {
bytes.push(parseInt(hex.substr(x, 2), 16));
}
return String.fromCharCode.apply(String, bytes);
}
// ---------------------------------------------------
/**
* U.UF.EC.SparkMD5 OOP implementation.
*
* Use this class to perform an incremental md5, otherwise use the
* static methods instead.
*/
U.UF.EC.SparkMD5 = function () {
// call reset to init the instance
this.reset();
}
/**
* Appends a string.
* A conversion will be applied if an utf8 string is detected.
*
* @param {String} str The string to be appended
*
* @return {U.UF.EC.SparkMD5} The instance itself
*/
U.UF.EC.SparkMD5.prototype.append = function (str) {
// Converts the string to utf8 bytes if necessary
// Then append as binary
this.appendBinary(U.UF.EC.toUtf8(str));
return this;
};
/**
* Appends a binary string.
*
* @param {String} contents The binary string to be appended
*
* @return {U.UF.EC.SparkMD5} The instance itself
*/
U.UF.EC.SparkMD5.prototype.appendBinary = function (contents) {
this._buff += contents;
this._length += contents.length;
var length = this._buff.length,
i;
for (i = 64; i <= length; i += 64) {
U.UF.EC.md5cycle(this._hash, U.UF.EC.md5blk(this._buff.substring(i - 64, i)));
}
this._buff = this._buff.substring(i - 64);
return this;
};
/**
* Finishes the incremental computation, reseting the internal state and
* returning the result.
*
* @param {Boolean} raw True to get the raw string, false to get the U.UF.EC.hex string
*
* @return {String} The result
*/
U.UF.EC.SparkMD5.prototype.end = function (raw) {
var buff = this._buff,
length = buff.length,
i,
tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
ret;
for (i = 0; i < length; i += 1) {
tail[i >> 2] |= buff.charCodeAt(i) << ((i % 4) << 3);
}
this._finish(tail, length);
ret = U.UF.EC.hex(this._hash);
if (raw) {
ret = U.UF.EC.hexToBinaryString(ret);
}
this.reset();
return ret;
};
/**
* Resets the internal state of the computation.
*
* @return {U.UF.EC.SparkMD5} The instance itself
*/
U.UF.EC.SparkMD5.prototype.reset = function () {
this._buff = '';
this._length = 0;
this._hash = [1732584193, -271733879, -1732584194, 271733878];
return this;
};
/**
* Gets the internal state of the computation.
*
* @return {Object} The state
*/
U.UF.EC.SparkMD5.prototype.getState = function () {
return {
buff: this._buff,
length: this._length,
hash: this._hash
};
};
/**
* Gets the internal state of the computation.
*
* @param {Object} state The state
*
* @return {U.UF.EC.SparkMD5} The instance itself
*/
U.UF.EC.SparkMD5.prototype.setState = function (state) {
this._buff = state.buff;
this._length = state.length;
this._hash = state.hash;
return this;
};
/**
* Releases memory used by the incremental buffer and other additional
* resources. If you plan to use the instance again, use reset instead.
*/
U.UF.EC.SparkMD5.prototype.destroy = function () {
delete this._hash;
delete this._buff;
delete this._length;
};
/**
* Finish the final calculation based on the tail.
*
* @param {Array} tail The tail (will be modified)
* @param {Number} length The length of the remaining buffer
*/
U.UF.EC.SparkMD5.prototype._finish = function (tail, length) {
var i = length,
tmp,
lo,
hi;
tail[i >> 2] |= 0x80 << ((i % 4) << 3);
if (i > 55) {
U.UF.EC.md5cycle(this._hash, tail);
for (i = 0; i < 16; i += 1) {
tail[i] = 0;
}
}
// Do the final computation based on the tail and length
// Beware that the final length may not fit in 32 bits so we take care of that
tmp = this._length * 8;
tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
lo = parseInt(tmp[2], 16);
hi = parseInt(tmp[1], 16) || 0;
tail[14] = lo;
tail[15] = hi;
U.UF.EC.md5cycle(this._hash, tail);
};
/**
* Performs the md5 hash on a string.
* A conversion will be applied if utf8 string is detected.
*
* @param {String} str The string
* @param {Boolean} [raw] True to get the raw string, false to get the U.UF.EC.hex string
*
* @return {String} The result
*/
U.UF.EC.SparkMD5.hash = function (str, raw) {
// Converts the string to utf8 bytes if necessary
// Then compute it using the binary function
return U.UF.EC.SparkMD5.hashBinary(U.UF.EC.toUtf8(str), raw);
};
/**
* Performs the md5 hash on a binary string.
*
* @param {String} content The binary string
* @param {Boolean} [raw] True to get the raw string, false to get the U.UF.EC.hex string
*
* @return {String} The result
*/
U.UF.EC.SparkMD5.hashBinary = function (content, raw) {
var hash = U.UF.EC.md51(content),
ret = U.UF.EC.hex(hash);
return raw ? U.UF.EC.hexToBinaryString(ret) : ret;
};
// ---------------------------------------------------
/**
* U.UF.EC.SparkMD5 OOP implementation for array buffers.
*
* Use this class to perform an incremental md5 ONLY for array buffers.
*/
U.UF.EC.SparkMD5.ArrayBuffer = function () {
// call reset to init the instance
this.reset();
};
/**
* Appends an array buffer.
*
* @param {ArrayBuffer} arr The array to be appended
*
* @return {U.UF.EC.SparkMD5.ArrayBuffer} The instance itself
*/
U.UF.EC.SparkMD5.ArrayBuffer.prototype.append = function (arr) {
var buff = U.UF.EC.concatenateArrayBuffers(this._buff.buffer, arr, true),
length = buff.length,
i;
this._length += arr.byteLength;
for (i = 64; i <= length; i += 64) {
U.UF.EC.md5cycle(this._hash, U.UF.EC.md5blk_array(buff.subarray(i - 64, i)));
}
this._buff = (i - 64) < length ? new Uint8Array(buff.buffer.slice(i - 64)) : new Uint8Array(0);
return this;
};
/**
* Finishes the incremental computation, reseting the internal state and
* returning the result.
*
* @param {Boolean} raw True to get the raw string, false to get the U.UF.EC.hex string
*
* @return {String} The result
*/
U.UF.EC.SparkMD5.ArrayBuffer.prototype.end = function (raw) {
var buff = this._buff,
length = buff.length,
tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
i,
ret;
for (i = 0; i < length; i += 1) {
tail[i >> 2] |= buff[i] << ((i % 4) << 3);
}
this._finish(tail, length);
ret = U.UF.EC.hex(this._hash);
if (raw) {
ret = U.UF.EC.hexToBinaryString(ret);
}
this.reset();
return ret;
};
/**
* Resets the internal state of the computation.
*
* @return {U.UF.EC.SparkMD5.ArrayBuffer} The instance itself
*/
U.UF.EC.SparkMD5.ArrayBuffer.prototype.reset = function () {
this._buff = new Uint8Array(0);
this._length = 0;
this._hash = [1732584193, -271733879, -1732584194, 271733878];
return this;
};
/**
* Gets the internal state of the computation.
*
* @return {Object} The state
*/
U.UF.EC.SparkMD5.ArrayBuffer.prototype.getState = function () {
var state = U.UF.EC.SparkMD5.prototype.getState.call(this);
// Convert buffer to a string
state.buff = U.UF.EC.arrayBuffer2Utf8Str(state.buff);
return state;
};
/**
* Gets the internal state of the computation.
*
* @param {Object} state The state
*
* @return {U.UF.EC.SparkMD5.ArrayBuffer} The instance itself
*/
U.UF.EC.SparkMD5.ArrayBuffer.prototype.setState = function (state) {
// Convert string to buffer
state.buff = U.UF.EC.utf8Str2ArrayBuffer(state.buff, true);
return U.UF.EC.SparkMD5.prototype.setState.call(this, state);
};
U.UF.EC.SparkMD5.ArrayBuffer.prototype.destroy = U.UF.EC.SparkMD5.prototype.destroy;
U.UF.EC.SparkMD5.ArrayBuffer.prototype._finish = U.UF.EC.SparkMD5.prototype._finish;
/**
* Performs the md5 hash on an array buffer.
*
* @param {ArrayBuffer} arr The array buffer
* @param {Boolean} [raw] True to get the raw string, false to get the U.UF.EC.hex one
*
* @return {String} The result
*/
U.UF.EC.SparkMD5.ArrayBuffer.hash = function (arr, raw) {
var hash = U.UF.EC.md51_array(new Uint8Array(arr)),
ret = U.UF.EC.hex(hash);
return raw ? U.UF.EC.hexToBinaryString(ret) : ret;
};
//
//参数一:文件对象
//参数二:进度条回调
//参数三:文件计算md5完毕后的回调,回调函数中得到md5值。
U.UF.EC.MD5 = function (file, progressCb, cb) {
}
;
///
Namespace.register("U.UF.API"); //第三方接口
/*
* 初始化用户系统
*
*/
U.UF.API.user = function () {
U.UF.DL.asynLoadJs({ type: "text/javascript", charset: "utf8", async: true, src: "http://user.1473.cn/js/User.js" });
}
/*
* 初始化好友系统
*
*/
U.UF.API.friend = function () {
U.UF.DL.asynLoadJs({ type: "text/javascript", charset: "utf8", async: true, src: "http://friend.1473.cn/js/Friend.js" });
}
/*
* 初始化
*
*/
U.UF.API.disk = function () {
U.UF.DL.asynLoadJs({ type: "text/javascript", charset: "utf8", async: true, src: "http://disk.1473.cn/js/Disk.js" });
};
///
Namespace.register("U.UF.E");
//初始化table
/**
* 表格总接口
* range为编辑器的光标对象
*/
U.UF.E.table = function (range) {
var _p,
_inputo,
_inputt,
_frag = $$("frag"),
_table = U.UF.E.table; //简写命名空间
_table._range = range;
_p = $$("p", { "style": { "cssText": "text-align: left;font-weight: bold;padding: 10px 0 0 15px;" }, "innerHTML": "表格尺寸: " }, _frag);
_p = $$("p", { "style": { "cssText": "text-align: left;margin-top: 15px;font-size: 14px;padding-left: 30px;" }, "innerHTML": "列数: " }, _frag);
_inputo = $$("input", { "type": "number", "style": { "cssText": "width: 80px;margin-left: 65px;" }, "min": "1" }, _p);
_p = $$("p", { "style": { "cssText": "text-align: left;padding-left: 30px;margin-top: 15px;font-size: 14px;margin-bottom: 22px;" }, "innerHTML": "行数: " }, _frag);
_inputt = $$("input", { "type": "number", "style": { "cssText": "width: 80px;margin-left: 65px;" }, "min": "1" }, _p);
//弹出框的html代码
U.UF.UI.confirm(_frag, function () { //弹框输入 行 和 列
var _row = _inputo.value; //行
var _col = _inputt.value; //列
if (_row >= 1 && _col >= 1) { //如果 行和列的值大于1 则添加表格
_table.addTable(_row, _col);
}
});
U.selectEl(document).unbind('mousedown', U.UF.E.table.removeFocus); //先取消事件监听 在添加 防止重复绑定
U.selectEl(document).bind('mousedown', U.UF.E.table.removeFocus); //添加点击时的聚焦效果 并且若存在textarea元素 则删除并获取textarea的值给td
};
//初始化整理table,功能作用: 给外部添加的table元素添加样式和事件
U.UF.E.table.load = function (tableel) {
var _table = U.UF.E.table; //简写命名空间
var _tableEl = tableel;
if (_tableEl.features) return; //如果已初始化 则直接返回
_tableEl.features = true; //代表已初始化过
var _pelDiv = _tableEl.parentNode; //父节点的初始化
var _allTd = _tableEl.querySelectorAll("td");
_allTd.forEach(function (v) { /*删除所有display为none的dt元素*/
U.selectEl(v).rmAttr("width");
var _value = U.selectEl(v).css("display");
if (_value === "none") {
v.remove();
}
});
_pelDiv.style.cssText = "overflow-y:hidden;padding-bottom:5px;padding-right:7px;"; //_div的样式
_tableEl.style.cssText = _tableEl.style.cssText + "border-spacing: 0;border-collapse: collapse;position: relative;";
_tableEl.contentEditable = "false";
_table.tableOver(_tableEl); //添加选中选出事件 防止选中td时 选中外面的元素 而报错
var _trList = _tableEl.querySelectorAll("tr");
var _tdList = U.selectEl(_tableEl).find("td");
//列拉升处理
for (var i = 0; i < _tdList.length; i++) {
var _tdCopy = _tdList[i];
_tdCopy.contentEditable = "true";
_tdCopy.style.cssText += ";outline:0;box-sizing:border-box;position:relative;padding:0px;border:2px solid #333;" //这样子写csstext不会给覆盖
var _tdWidth = _tdCopy.clientWidth;
_tdCopy.style.width = _tdWidth + "px"; //给td添加width
_table.loadCell(_tdCopy); //初始有合并单元格 的情况
var _colRule = $$("div", { "style": { "outline": "0", "zIndex": "1", "position": "absolute", "top": 0, "right": 0, "cursor": "col-resize", "width": "3px", "height": "100%" }, "tabindex": "0", "contenteditable": "false", "className": "U_MD_O_W_Table_colRule", "inline": true }, _tdCopy); //列尺
_table.colExpanding(_colRule); //给列尺 添加左右拉伸事件
_table.dragCheckd(_tdCopy); //td拖拽的选中事件
_table.rightClick(_tableEl); //添加右键
}
//行拉升处理
for (var i = 0; i < _trList.length; i++) {
var _trEl = _trList[i];
_trEl.style.cssText += ";position:relative;overflow:hidden;";
var _rowRule = $$("div", { "style": { "outline": "0", "zIndex": "1", "position": "absolute", "left": 0, "margin-top": _trEl.clientHeight + "px", cursor: "row-resize", height: "3px", width: "100%" }, tabindex: "0", "contenteditable": "false", "className": "U_MD_O_W_Table_rowRule", "inline": true }, _trEl); //行尺
_table.rowExpanding(_rowRule); //行尺 上下拉伸事件
};
}
/**
* 初始有合并单元格 的情况
* tdEl td元素
*/
U.UF.E.table.loadCell = function (tdEl) {
var _table = U.UF.E.table; //简写命名空间
var _tableEl = _table.parentSelect(tdEl, "table"); //获取table元素
var _colSpan = tdEl.colSpan - 1; //跨了_colSpan列
var _rowSpan = tdEl.rowSpan - 1; //跨了_rowSpan行
if (_colSpan >= 1) {
for (var i = 0; i < _colSpan; i++) {
var _newTd = $$("td");
_newTd.style.display = "none";
_table.After(tdEl, _newTd);
}
}
if (_rowSpan >= 1) {
var _tdIndex = _table.index(tdEl); //获取该td的所在索引
var _trIndex = _table.index(tdEl.parentNode); //获取该行tr所在位置
var _trList = _tableEl.querySelectorAll("tr"); //获取所有的tr
for (var i = 1; i <= _rowSpan; i++) { //获取该tr的下_rowSpan个tr
var _tdList = _trList[_trIndex + i].querySelectorAll("td"); //获取该tr的所有td
var _td = _tdList[_tdIndex - 1];
for (var j = 0; j <= _colSpan; j++) {
var _newTd = $$("td");
_newTd.style.display = "none";
_table.After(_td, _newTd);
}
}
}
}
/**
* 创建表格
* @param row 表格的行
* @param col 表格的列
*/
U.UF.E.table.addTable = function (row, col) {
var i, j, _tr, _td,
_frag = $$("frag"),
_pel = U.UF.E.table.createTablePel(), //table父节点
_table = $$("table", { style: { cssText: "border-spacing: 0;border-collapse: collapse;width: 100%;position: relative;table-layout:fixed;" } }, _pel),
_tbody = $$("tbody", {}, _table),
_width = Math.max(Math.floor(_table.clientWidth / col), 50)
;
// var _width = Math.max(Math.floor(_table.clientWidth / col), 50);
//循环创建tr td
for (i = 0; i < row; i++) {
_tr = $$("tr", {}, _frag); //创建tr
for (j = 0; j < col; j++) {
_td = $$("td", { style: { width: _width + "px" }, "innerHTML": "
" }, _tr);
}
}
_tbody.appendChild(_frag); //修改
U.UF.E.table.load(_table);
};
/**
* 换行并返回该行的div 然后在该行下面创建空div(防止表格后无法聚焦)
* return 创建表格的div(父节点)
*/
U.UF.E.table.createTablePel = function () {
var _table = U.UF.E.table;
//console.log(_table._range);
var _range = U.UF.E.table._range, //获取光标
_div = U.UF.E.getLineElement(_range.startContainer); //获取光标所在行的div
if (_div.textContent !== "") { //如果该行有内容 则新建一行div
var _div = U.selectEl("#" + U.UF.E.key.addLine(_range).addLine)[0];
}
// U.selectEl(_div).attr("contenteditable", "false"); //无内容的div(表格的父节点) 取消编辑效果
_div.style.cssText = "overflow-y:hidden;padding-bottom:5px;padding-right:7px;width:90%"; //_div的样式
U.UF.E.key.addLine(_range); //在表格的父节点下添加div 防止无法聚焦
_table.placeCaretAtEnd(_div);
return _div;
};
/**
* 将表格的第一个tr里的所有列尺元素 添加 zindex为1 的样式
* tableEl 表格元素
*/
U.UF.E.table.firstLinePeak = function (tableEl) {
U.selectEl(tableEl).find(".U_UF_E_Table_peak").css("height", 0); //原来有列尺的元素高度清0
U.selectEl(tableEl).find(".U_UF_E_Table_peak").removeClass("U_UF_E_Table_peak"); //改变 删除所有列尺的zIndex为1的样式
var _height = tableEl.clientHeight; //获取表格的高
var _colRuleList = tableEl.querySelectorAll("tr")[0].querySelectorAll(".U_MD_O_W_Table_colRule"); //获取第一行的列尺
for (var i = 0, len = _colRuleList.length; i < len; i++) {
var _colRule = _colRuleList[i];
_colRule.style.height = _height + "px"; //所有列尺的高等于表格的高
U.selectEl(_colRule).addClass("U_UF_E_Table_peak");
}
};
/**
*
* @param table 防止选中事件时选中到表格外的元素而报错
*/
U.UF.E.table.tableOver = function (table) {
U.selectEl(table).bind('mouseover', function () { //判断鼠标是否在该table里 如果在 才可以选择区域
this.over = true;
});
U.selectEl(table).bind('mouseout', function () {
this.over = false;
});
};
/**
*
* @param colrule 列尺(div) 添加左右拉伸事件
*/
U.UF.E.table.colExpanding = function (colrule) {
var _div = colrule;
U.selectEl(_div).bind({
'mousedown': function (e) {
U.selectEl("#U_UF_EL_rightmenu")[0] && U.selectEl("#U_UF_EL_rightmenu")[0].remove(); //删除右键元素
U.UF.EV.stopBubble(e); //阻止冒泡
this.style.backgroundColor = "#8cb3e0"; //修改列尺(div)的颜色
var _table = U.UF.E.table;
var _this = this;
var _tdEl = this.parentNode; //获取td(每个列对应一个td父节点)
var _tableEl = _table.parentSelect(this, "table"); //获取所在的table
var _tableElWidth = _tableEl.clientWidth; //table当前的宽度
var _trList = _tableEl.querySelectorAll("tr"); //获取所有的tr
var _tdElIndex = _table.index(_tdEl); //获取td在tr的索引位置(列)
var _dis, //移动的距离
_disX; //移动后的位置
var _oMouseX = e.pageX; //获取鼠标按下时的X坐标
var _oX = parseInt(this.style.right); //获取当前Left坐标
var expandingMove = function (e) { //拖拽时移动用的函数
U.UF.EV.stopDefault(e); //取消默认拖拽
var _mouseX = e.pageX; //鼠标移动时的x坐标
_dis = _mouseX - _oMouseX; //移动的距离
_disX = _dis + _oX; //移动后的位置
U.selectEl(_this).css("right", -_disX + "px"); //同步当前的left
};
var expandingUp = function () { //拖拽时松开用的函数
_this.style.backgroundColor = ""; //列尺颜色 变为空
var _child;
for (var i = 0, len = _trList.length; i < len; i++) {
var _colTdEl = U.selectEl("td", _trList[i])[_tdElIndex]; //列的td _trList[i].querySelectorAll("td")
_colTdEl.style.width = _colTdEl.offsetWidth + _disX + "px"; //同步宽度
var _colRule = _colTdEl.querySelectorAll('.U_MD_O_W_Table_colRule'); //该td对应的列尺
U.selectEl(_colRule).css("right", "0px"); //同步当前的left
_child = U.selectEl("div", _trList[i]);
_child[_child.length - 1].style.marginTop = _trList[i].offsetHeight + "px";
}
U.selectEl(document).unbind('mousemove', expandingMove);
U.selectEl(document).unbind('mouseup', expandingUp);
};
U.selectEl(document).bind('mousemove', expandingMove);
U.selectEl(document).bind('mouseup', expandingUp)
},
'dblclick': function (e) {
U.UF.EV.stopBubble(e); //阻止冒泡
}, //阻止td的双击
'mousemove': function (e) {
U.UF.EV.stopBubble(e); //阻止冒泡
U.UF.EV.stopDefault(e); //取消默认拖拽
}
});
};
/**
*
* @param rowrule 行尺(div) 添加上下拉伸事件
*/
U.UF.E.table.rowExpanding = function (rowrule) { //高度扩张
var _div = rowrule;
U.selectEl(_div).bind({
'mousedown': function (e) {
U.selectEl("#U_UF_EL_rightmenu")[0] && U.selectEl("#U_UF_EL_rightmenu")[0].remove(); //删除右键元素
this.style.backgroundColor = "#8cb3e0";
U.UF.EV.stopBubble(e); //阻止冒泡
var _oMouseY = e.pageY; //获取鼠标按下时的Y坐标
var _this = this;
var _oY = parseInt(this.style.marginTop); //获取当前Top坐标
var _trEl = this.parentNode; //获取tr
var expandingMove = function (e) { //拖拽时移动用的函数
U.UF.EV.stopDefault(e); //取消默认拖拽
var _mouseY = e.pageY; //鼠标移动时的Y坐标
var _dis = _mouseY - _oMouseY + _oY; //移动的距离
_dis = Math.max(30, _dis); //拉伸后的tr的高度不能小于30px
_trEl.style.height = _dis + "px";
var clienHeight = _trEl.clientHeight; //tr的高度 会根据内容有个最小值 因此 这个tr最后的高度 才是最终值
_dis = Math.max(clienHeight, _dis);
_trEl.style.height = _dis + "px";
U.selectEl(_this).css("margin-top", _dis + "px");
};
var expandingUp = function () { //拖拽时松开用的函数
var _table = U.UF.E.table; //简写命名空间
var _tableEl = _table.parentSelect(_this, "table"); //获取table元素
_table.firstLinePeak(_tableEl); //更新第一行的列尺高度
_this.style.backgroundColor = "";
U.selectEl(document).unbind('mousemove', expandingMove);
U.selectEl(document).unbind('mouseup', expandingUp);
};
U.selectEl(document).bind('mousemove', expandingMove);
U.selectEl(document).bind('mouseup', expandingUp)
},
'mousemove': function (e) {
U.UF.EV.stopBubble(e); //阻止冒泡
U.UF.EV.stopDefault(e); //取消默认拖拽
}
});
};
/*
* 添加文本框 并给文本框添加事件
* parent td元素(文本框父元素)
* text 为文本 可要可不要
*/
U.UF.E.table.createTextArea = function (parent, text) {
var _textArea = $$("textarea", { className: "U_UF_E_Table_tdText", value: text || "", contenteditable: "true", inline: true }, parent); //添加textarea 并且将td的内容放入textarea
U.selectEl(_textArea).bind('mousedown', function (e) {
U.selectEl("#U_UF_EL_rightmenu")[0] && U.selectEl("#U_UF_EL_rightmenu")[0].remove(); //删除右键元素 //阻止冒泡
}); //阻止td的冒泡 (选中效果 和 聚焦效果)
var autoHeight = function (el) { //表格自动适应高
el.nodeType === 1 ? "" : el = el.target; //el只能为textarea
el.scrollHeight ? el.style.height = el.scrollHeight + "px" : ""; //此处为textarea的高度跟随文字输入的内容自动增高
var _rowRuleList = U.selectEl(".U_MD_O_W_Table_rowRule"); //获取所有行尺
for (var i = 0, len = _rowRuleList.length; i < len; i++) {
var _trPel = _rowRuleList[i].parentNode; //每个行尺 对应一个 tr元素
_trPel.style.height = _trPel.clientHeight; //使每个tr的height 等于 clientHeight
U.selectEl(_rowRuleList[i]).css("margin-top", _trPel.clientHeight + "px"); //同步margintop 的位置
}
};
autoHeight(_textArea); //由于textarea输入自后td的高度会变化 因此所有行尺的位置重新定位
U.selectEl(_textArea).bind('keydown', autoHeight); //键盘监听 自动适应高
U.selectEl(_textArea).bind('keyup', autoHeight); //键盘监听 自动适应高
U.selectEl(_textArea).bind('blur', function () {
var _textla = U.selectEl(".U_UF_E_Table_tdText");
var _tdEl = U.selectEl(".U_UF_E_Table_tdText")[0].parentNode;
_tdEl.innerText = _textla[0].value;
_textla.remove();
});
}
/**
*
* @param td 添加鼠标拖拽效果的 td
* 给td添加鼠标拖拽的选中效果
*/
U.UF.E.table.dragCheckd = function (td) {
var _tdEl = td;
U.selectEl(_tdEl).bind('mousedown', function (e) {
U.UF.EV.stopBubble(e); //阻止冒泡
U.selectEl("#U_UF_EL_rightmenu")[0] && U.selectEl("#U_UF_EL_rightmenu")[0].remove(); //删除右键元素
if (e.button != 2) {
var _table = U.UF.E.table;
//移除原本选中的效果
U.selectEl(".U_UF_E_Table_tdCheckd").removeClass("U_UF_E_Table_tdCheckd");
U.selectEl(".U_UF_E_Table_tdCurrent").removeClass("U_UF_E_Table_tdCurrent");
//给td添加聚焦样式
U.selectEl(this).addClass("U_UF_E_Table_tdCurrent");
var _start = this; //获取点击元素
var _startX = _table.index(_start); //记录x坐标轴
var _startY = _table.index(this.parentNode); //获取y坐标轴
var _checkFlag = true; //注意下面的_table.over是一个属性 防止选中区域在表格外面
var _tableEl = _table.parentSelect(this, "table"); //获取父节点table
//拖拽时移动用的函数
var _drapMove = function (e) {
var tagEl = e.path.filter(_filter)[0];
if (tagEl) {
U.UF.EV.stopBubble(e); //阻止冒泡
if (!(_tableEl.over) || (tagEl === _start && _checkFlag)) return; //此处防止选中table外元素 与 鼠标必须选中两个td才会有选中效果
_checkFlag = false; //如果不同 则选中过两个元素
var _endX = _table.index(tagEl); //结束点的x坐标
var _endY = _table.index(tagEl.parentNode); //结束点的y坐标
U.selectEl(".U_UF_E_Table_tdCheckd").removeClass("U_UF_E_Table_tdCheckd");
_table.tdAddClass(tagEl.parentNode, _startX, _startY, _endX, _endY); //给开始点和结束点组成的矩形 添加选中的class
}
};
var _dragUp = function () { //拖拽时松开用的函数
U.selectEl(document).unbind('mousemove', _drapMove);
U.selectEl(document).unbind('mouseup', _dragUp);
_checkFlag = true;
};
var _filter = function (el) {
return el.nodeName && el.nodeName === "TD"
}
U.selectEl(document).bind('mousemove', _drapMove);
U.selectEl(document).bind('mouseup', _dragUp);
}
});
};
/**
* 添加右键
* tableEl 表格元素
*/
U.UF.E.table.rightClick = function (tableEl) {
var _table = U.UF.E.table;
var leftAddCol = {
innerHTML: '左侧添加列',
onclick: function () {
_table.addColumn("left");
U.selectEl("#U_UF_EL_rightmenu")[0] && U.selectEl("#U_UF_EL_rightmenu")[0].remove(); //删除右键元素
},
onmousedown: function (e) {
U.UF.EV.stopBubble(e); //阻止冒泡
}
};
var rightAddCol = {
innerHTML: '右侧添加列',
onclick: function () {
_table.addColumn("right");
U.selectEl("#U_UF_EL_rightmenu")[0] && U.selectEl("#U_UF_EL_rightmenu")[0].remove(); //删除右键元素
},
onmousedown: function (e) {
U.UF.EV.stopBubble(e); //阻止冒泡
}
};
var upAddLine = {
innerHTML: '向上添加行',
onclick: function () {
_table.addTr("up");
U.selectEl("#U_UF_EL_rightmenu")[0] && U.selectEl("#U_UF_EL_rightmenu")[0].remove(); //删除右键元素
},
onmousedown: function (e) {
U.UF.EV.stopBubble(e); //阻止冒泡
}
};
var downAddLine = {
innerHTML: '向下添加行',
onclick: function () {
_table.addTr("down");
U.selectEl("#U_UF_EL_rightmenu")[0] && U.selectEl("#U_UF_EL_rightmenu")[0].remove(); //删除右键元素
},
onmousedown: function (e) {
U.UF.EV.stopBubble(e); //阻止冒泡
}
};
var removeCol = {
innerHTML: '删除列',
onclick: function () {
_table.removeColumn();
U.selectEl("#U_UF_EL_rightmenu")[0] && U.selectEl("#U_UF_EL_rightmenu")[0].remove(); //删除右键元素
},
onmousedown: function (e) {
U.UF.EV.stopBubble(e); //阻止冒泡
}
};
var removeLine = {
innerHTML: '删除行',
onclick: function () {
_table.removeTr();
U.selectEl("#U_UF_EL_rightmenu")[0] && U.selectEl("#U_UF_EL_rightmenu")[0].remove(); //删除右键元素
},
onmousedown: function (e) {
U.UF.EV.stopBubble(e); //阻止冒泡
}
};
var mergeCells = {
innerHTML: '合并单元格',
onclick: function () {
_table.mergeCells();
U.selectEl("#U_UF_EL_rightmenu")[0] && U.selectEl("#U_UF_EL_rightmenu")[0].remove(); //删除右键元素
},
onmousedown: function (e) {
U.UF.EV.stopBubble(e); //阻止冒泡
}
};
var _arr = [leftAddCol, rightAddCol, upAddLine, downAddLine, removeCol, removeLine, mergeCells];
U.selectEl(tableEl).bind('contextmenu', function (e) {
U.UF.EV.stopBubble(e); //阻止冒泡
U.UF.EV.stopDefault();
U.UF.EL.rightMenu(_arr, tableEl);
U.selectEl("#U_UF_EL_rightmenu").bind('contextmenu', function (e) { //右键元素属于table 因此需要阻止冒泡
U.UF.EV.stopBubble(e); //阻止冒泡
});
});
U.selectEl(tableEl).bind('mousedown', function (e) {
U.selectEl("#U_UF_EL_rightmenu")[0] && U.selectEl("#U_UF_EL_rightmenu")[0].remove(); //删除右键元素
});
};
/**
*
* @param direction 参数为 "left" 或 "right"
* 左右侧添加列
*/
U.UF.E.table.addColumn = function (direction) {
var _table = U.UF.E.table;
var tdList = U.selectEl(".U_UF_E_Table_tdCheckd");
if (!tdList[0]) { //如果没有 选中的td
if ($(".U_UF_E_Table_tdCurrent")[0]) { //再判断 有无聚焦的 td
tdList = U.selectEl(".U_UF_E_Table_tdCurrent");
} else {
return; //如果没有 则直接返回
}
}
var _tdEl;
if (direction === "left") {
_tdEl = tdList[0];
} else if (direction === "right") {
_tdEl = tdList[tdList.length - 1];
}
_table.insertTd(_tdEl, direction);
};
/**
*
* @param td td元素
* @param direction 供添加左右列用的api 参数为 "left" 或 "right"
* 向每个tr的列(td) 前方或后方插入td
*/
U.UF.E.table.insertTd = function (td, direction) {
var _table = U.UF.E.table;
var _tdEl = td,
_index = _table.index(_tdEl), //在tr中位于所有td的位置
_dir = direction;
var _tableEl = _table.parentSelect(_tdEl, 'table');
var _trList = U.selectEl(_tableEl).find("tr");
var _tableElWidth = _tableEl.offsetWidth; //记住当前的宽度
for (var i = 0, len = _trList.length; i < len; i++) { //遍历每个tr的列(td) 在前方或后方插入td
var _currentColumn = U.selectEl(_trList[i]).find("td")[_index]; //当前列
var _tdElClone = _tdEl.cloneNode(); //克隆td
if (_dir === "left") {
_table.Before(_currentColumn, _tdElClone); //在列的前面添加td
}
else if (_dir === "right") {
_table.After(_currentColumn, _tdElClone); //在列的后面添加td
}
var _colRule = $$("div", { style: { position: "absolute", top: 0, left: "-7px", "margin-left": _tdElClone.style.width, cursor: "col-resize", width: "7px" }, className: "U_MD_O_W_Table_colRule", inline: true }, _tdElClone); //列尺
_table.colExpanding(_colRule); //添加左右拉伸事件
_table.createTextArea(_tdElClone); //添加文本框
_table.dragCheckd(_tdElClone); //td拖拽的选中事件
U.selectEl(_tdElClone).removeClass("U_UF_E_Table_tdCheckd"); //清楚添加后的列的选中的样式
U.selectEl(_tdElClone).removeClass("U_UF_E_Table_tdCurrent");
}
_tableEl.style.width = _tableElWidth + _tdEl.offsetWidth + "px";
_table.firstLinePeak(_tableEl); //第一行tr的所有列尺添加zIndex为1
};
/**
*
* @param direction 参数为 "up" 或 "down"
* 上下添加行
*/
U.UF.E.table.addTr = function (direction) {
var _table = U.UF.E.table;
var tdList = U.selectEl(".U_UF_E_Table_tdCheckd");
if (!tdList[0]) { //如果没有 选中的td
if ($(".U_UF_E_Table_tdCurrent")[0]) { //再判断 有无聚焦的 td
tdList = U.selectEl(".U_UF_E_Table_tdCurrent");
} else {
return; //如果没有 则直接返回
}
}
var _trEl, _trElClone;
if (direction === "up") {
_trEl = tdList[0].parentNode;
_trElClone = _table.cloneTr(_trEl); //克隆tr 并给td 添加表格事件
_table.Before(_trEl, _trElClone);
} else if (direction === "down") {
_trEl = tdList[tdList.length - 1].parentNode; //向下插入行
_trElClone = _table.cloneTr(_trEl); //克隆tr 并给td 添加表格事件
_table.After(_trEl, _trElClone);
}
var _tableEl = _table.parentSelect(tdList[0], 'table');
_table.firstLinePeak(_tableEl); //将表格的第一个tr里的所有列尺元素 添加 zindex为1 的样式
};
/**
* 删除行
*/
U.UF.E.table.removeTr = function () {
var _table = U.UF.E.table;
var tdList = U.selectEl(".U_UF_E_Table_tdCheckd");
if (!tdList[0]) { //如果没有 选中的td
if ($(".U_UF_E_Table_tdCurrent")[0]) { //再判断 有无聚焦的 td
tdList = U.selectEl(".U_UF_E_Table_tdCurrent");
} else {
return; //如果没有 则直接返回
}
}
var start = _table.index(tdList[0].parentNode);
var end = _table.index(tdList[tdList.length - 1].parentNode);
var _tableEl = _table.parentSelect(tdList[0], "table");
var _parentDiv = _table.parentSelect(_tableEl, "div");
var _trList = U.selectEl(_tableEl).find("tr");
for (var i = start; i <= end; i++) {
_trList[i].remove();
}
if (!(_tableEl.querySelectorAll("tr").length)) {
_parentDiv.remove();
return
}
_table.firstLinePeak(_tableEl); //将表格的第一个tr里的所有列尺元素 添加 zindex为1 的样式
};
/**
*
* @param tr 需要克隆的tr
* 克隆tr 并添加表格事件
*/
U.UF.E.table.cloneTr = function (tr) {
var _table = U.UF.E.table;
var _trNodes = tr.cloneNode(true); //带子节点的tr
var _trClone = tr.cloneNode(); //无子节点的tr
var _cloneTd = U.selectEl(_trNodes).find("td");
for (var i = 0, len = _cloneTd.length; i < len; i++) {
var _td = _cloneTd[i].cloneNode();
U.selectEl(_td).rmAttr("rowspan"); //删除跨行的属性
_trClone.appendChild(_td);
var _colRule = $$("div", { style: { position: "absolute", top: 0, left: "-7px", "margin-left": _td.style.width, cursor: "col-resize", width: "7px" }, className: "U_MD_O_W_Table_colRule", inline: true }, _td); //列尺
_table.colExpanding(_colRule); //添加左右拉伸事件
//_table.tdDbClick(_td); //添加双击事件
_table.createTextArea(_td);
_table.dragCheckd(_td); //td拖拽的选中事件
}
var _rowRule = $$("div", { style: { position: "absolute", zIndex: "1", left: 0, "margin-top": "30px", cursor: "row-resize", height: "3px", width: "100%" }, className: "U_MD_O_W_Table_rowRule", inline: true }, _trClone); //行尺
_table.rowExpanding(_rowRule); //上下拉伸事件
U.selectEl(_trClone).find(".U_UF_E_Table_tdCheckd").removeClass("U_UF_E_Table_tdCheckd"); //删除所有选中表格和 聚焦表格的样式
U.selectEl(_trClone).find(".U_UF_E_Table_tdCurrent").removeClass("U_UF_E_Table_tdCurrent");
return _trClone;
};
/**
* 合并单元格功能
*/
U.UF.E.table.mergeCells = function () {
var _table = U.UF.E.table;
var _tdList = U.selectEl(".U_UF_E_Table_tdCheckd");
if (_tdList.length <= 1) return;
var _x1 = _table.index(_tdList[0]); //x坐标开始点
var _y1 = _table.index(_tdList[0].parentNode); //y坐标开始点
var _x2 = _table.index(_tdList[_tdList.length - 1]); //x坐标结束点
var _y2 = _table.index(_tdList[_tdList.length - 1].parentNode); //y坐标结束点
var _tableEl = _table.parentSelect(_tdList[0], "table"); //获取table元素
var _trList = _tableEl.querySelectorAll("tr"); //获取table里所有tr
var _text = ""; //合并后的总内容
var allWidth = 0; //合并后的总宽度
for (var i = _y1; i <= _y2; i++) { /*该循环*/
var _trAllTd = _trList[i].querySelectorAll("td"); //获取选中表格的所在tr
for (var j = _x1; j <= _x2; j++) { // 获取选中表格的 所在td
var _tdEl = _trAllTd[j]; //获取每个选中的单元格
_text += _tdEl.innerText; //合并内容
if (i === _y1) { //只计算选中表格第一行 的总宽度
allWidth += _tdEl.offsetWidth;
}
if (i === _y1 && j === _x1) continue; //第一个td就跳过 其他的则display为 none
U.selectEl(_tdEl).css("display", "none");
}
}
var _textNode = document.createTextNode(_text); //文字节点 _text为总内容
var _firstNode = _table.getFirstText(_tdList[0]); //获取被合并单元格的td所在的文字节点
_firstNode ? _firstNode.remove() : ""; //如果存在文字节点 则删除
_tdList[0].appendChild(_textNode); //然后将新创建的总文字节点 添加到该单元格里
_tdList[0].style.width = allWidth + "px"; //添加总宽度
var _col = U.selectEl(_tdList[0]).attr("colspan");
_col <= _x2 - _x1 + 1 ? U.selectEl(_tdList[0]).attr("colspan", _x2 - _x1 + 1) : ""; //跨的列数
U.selectEl(_tdList[0]).attr("rowspan", _y2 - _y1 + 1); //跨的行数
U.selectEl(_tdList[0].querySelector(".U_MD_O_W_Table_colRule")).css("margin-left", allWidth + 'px'); //更新 列尺的位置
_table.firstLinePeak(_tableEl); //将表格的第一个tr里的所有列尺元素 添加 zindex为1 的样式
};
/**
* 删除列
*/
U.UF.E.table.removeColumn = function () {
var _table = U.UF.E.table
var tdList = U.selectEl(".U_UF_E_Table_tdCheckd");
if (!tdList[0]) { //如果没有 选中的td
if ($(".U_UF_E_Table_tdCurrent")[0]) { //再判断 有无聚焦的 td
tdList = U.selectEl(".U_UF_E_Table_tdCurrent");
} else {
return; //如果没有 则直接返回
}
}
var _start = _table.index(tdList[0]); //列的开始位置
var _end = _table.index(tdList[tdList.length - 1]); //列的结束位置
var _tableEl = _table.parentSelect(tdList[0], 'table');
var _trList = U.selectEl(_tableEl).find("tr");
var _widthSum = 0; //删除列的总宽
for (var i = 0, len = _trList.length; i < len; i++) {
var _tdList = U.selectEl(_trList[i]).find("td");
for (var j = _start; j <= _end; j++) {
i === 0 ? _widthSum += _tdList[j].offsetWidth : ""; //只计算第一行删除的列宽
_tdList[j].remove();
}
}
_tableEl.style.width = _tableEl.offsetWidth - _widthSum + "px";
var _tdLen = _tableEl.querySelectorAll("td").length; //获取当前列的长度
if (!_tdLen) { //如果table不存在td 则删除table和 table父节点(div)
var _parentDiv = _table.parentSelect(_tableEl, "div");
_parentDiv.remove();
return
}
_table.firstLinePeak(_tableEl); //将表格的第一个tr里的所有列尺元素 添加 zindex为1 的样式
};
/**
* 添加点击时的聚焦效果 并且若存在textarea元素 则删除并获取textarea的值给td
*/
U.UF.E.table.removeFocus = function () { //添加点击时的聚焦效果 并且若存在textarea元素 则删除并获取textarea的值给td
U.selectEl(".U_UF_E_Table_tdCheckd").removeClass("U_UF_E_Table_tdCheckd");
U.selectEl(".U_UF_E_Table_tdCurrent").removeClass("U_UF_E_Table_tdCurrent");
return;
var _textArea = U.selectEl(".U_UF_E_Table_tdText")[0], //如果存在textarea元素 则将其变为文本
_pel;
_textArea ? _pel = _textArea.parentNode : ""; //如果textArea存在 先获取父节点td 然后将其变为文本
if (_pel) {
var _textNode = document.createTextNode(_textArea.value);
_pel.appendChild(_textNode);
_textArea.remove();
}
var _rowRuleList = U.selectEl(".U_MD_O_W_Table_rowRule"); //使div的margintop 及时更新
for (var i = 0, len = _rowRuleList.length; i < len; i++) {
var _trEl = _rowRuleList[i].parentNode;
_trEl.style.height = _trEl.clientHeight;
U.selectEl(_rowRuleList[i]).css("margin-top", _trEl.clientHeight + "px");
}
};
/**
*
* @param tr 获取所有tr用的(遍历所有tr)
* @param x1 开始点x坐标
* @param y1 开始点y坐标
* @param x2 结束点x坐标
* @param y2 结束点y坐标
*/
U.UF.E.table.tdAddClass = function (tr, x1, y1, x2, y2) { //获取首尾坐标轴 最后组成矩形 然后添加选中的class
var _trList = tr.parentNode.querySelectorAll("tr");
var _x1 = Math.min(x1, x2);
var _x2 = Math.max(x1, x2);
var _y1 = Math.min(y1, y2);
var _y2 = Math.max(y1, y2);
for (var i = _y1; i <= _y2; i++) {
var _tdList = _trList[i].querySelectorAll("td");
for (var j = _x1; j <= _x2; j++) {
U.selectEl(_tdList[j]).addClass("U_UF_E_Table_tdCheckd");
}
}
}
/**
*
* @param el 元素
* @returns {number} 返回当前元素在所有同类型元素 的第几个位置
*/
U.UF.E.table.index = function (el) {
var _el = el;
var _name = _el.nodeName; //获取该元素的节点名
var _list = _el.parentNode.querySelectorAll(_name); //获取父节下的所有自己的节点
for (var i = 0, len = _list.length; i < len; i++) {
if (_list[i] === _el) {
return i; //返回在数组的索引
}
}
};
/**
* 获取td的第一个文本元素
*/
U.UF.E.table.getFirstText = function (td) {
var _child = td.childNodes;
for (var i = 0, len = _child.length; i < len; i++) {
if (_child[i].nodeType === 3) {
return _child[i];
}
}
return false;
}
/*获取指定标签的父节点*/
U.UF.E.table.parentSelect = function (el, type) {
var _this = el;
var type = type.toUpperCase();
if (_this.tagName === type) return _this;
var parent = _this.parentNode;
while (parent.tagName !== type) {
parent = parent.parentNode;
}
return parent;
};
/*在元素前面插入新元素*/
U.UF.E.table.Before = function (el, newEl) {
var _this = el;
var parentEl = _this.parentNode;
parentEl.insertBefore(newEl, _this);
};
/*在元素后面插入新元素*/
U.UF.E.table.After = function (el, newEl) {
var _this = el;
if (_this && _this.parentNode) {
var parentEl = _this.parentNode;
var child = parentEl.childNodes;
var last = child[child.length - 1] || parentEl.lastChild;
if (last === _this) {
parentEl.appendChild(newEl);
} else {
parentEl.insertBefore(newEl, _this.nextSibling);
}
return newEl;
}
};
/**
* 使光标聚焦在该元素后面
* @param el 需要文字聚焦的 元素节点
*/
U.UF.E.table.placeCaretAtEnd = function (el) { //传入光标要去的节点对象
if (el.collapse) { //如果存在el.collapsed 则是range
var range = el;
range.collapse(false);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
return;
}
if (typeof window.getSelection != "undefined" && typeof document.createRange != "undefined") {
el.focus && el.focus();
var range = document.createRange();
range.selectNodeContents(el);
range.collapse(false);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else if (typeof document.body.createTextRange != "undefined") {
var textRange = document.body.createTextRange();
textRange.moveToElementText(el);
textRange.collapse(false);
textRange.select();
}
};
/*
合并单元格使用bug:
1.选中表格时 如出现行和列对不齐时 除了删除列不会有问题以外 其他都会出问题
解决思路:由于合并单元格后 每行的td都对不齐了 因此需要修改选中td的接口 不准出现参差不齐的情况
2.在合并单元格的那一列用添加列 删除列会有bug
解决思路: 由于合并单元格时 有占用两列或两行的情况 因此需要在添加列删除列那里将占用两列以上的情况考虑进去 针对colspan属性做判断
3.在合并单元格的那一行除了 向上添加行功能 其他都会有bug
解决思路:由于跨行合并单元格 会使第第一行变成占2行或以上 其他行display为none 因此如果向下添加行则需要将display为none 消掉 主要也是需要针对rowspan属性做判断
*/
;
///
Namespace.register("U.UF.OT"); //第三方接口
/**
* 生成微信二维码
*
* @bindel {element} 绑定点击的元素 必填
* @href {string} 分享的地址 选填 默认值:当前游览器网页地址
* return {element} 返回创建好得元素
*/
U.UF.OT.weChatShareCode = function codeLayout(bindel, href, parent) {
if (typeof bindel != 'object') //判断bindel是否是元素
return false;
parent = parent ? parent : document.body; //parente默认为document.body
var _codeBox;
if (!$('#wxfrom', parent)[0]) {// 判断二维码是否存在
_codeBox = $$('div', { id: "wxfrom", style: { cssText: 'display: none; position:fixed; top:0; left:0; bottom:0; right:0; margin:auto; width:251px; height:332px; padding:10px; background-color: #f4f4f4; border: 1px solid #b9b9b9;' } }, parent || document.body);
$$('span', { innerText: "分享到微信朋友圈", style: { cssText: 'font-weight: bold' } }, _codeBox);
$$('span', {
innerText: 'x', style: { cssText: 'margin-left:140px; font-size: 18px; font-weight: bold; cursor:pointer' }, onclick: function () {
_codeBox.style.display = 'none';
}
}, _codeBox);
var _codeShowArea = $$('div', { style: { cssText: "padding:20px 10px;" } }, _codeBox);
// U.UF.QR.generate("230", "235", "black", "#f4f4f4", href || window.location.href, _codeShowArea);
$$('div', { innerHTML: "打开微信,点击底部的“发现”,
使用“扫一扫”即可将网页分享至朋友圈。" }, _codeBox);
} else {
_codeBox = U.selectEl('#wxfrom', parent)[0];
}
U.selectEl(bindel).bind({
click: function () {
U.UF.QR.generate("230", "235", "black", "#f4f4f4", href || window.location.href, _codeShowArea);
_codeBox.style.display = '';
}
})
return _codeBox;
}
/**
* qq好友分享
*
* @url {string} 分享的网页地址
* @title {string} 标题
* @pic {string} 图片绝对路径
* @desc {string} 分享介绍
* @summary {string} 分享内容
*/
U.UF.OT.qqFriendShare = function (url, title, pic, desc, summary) {
var _sharesinastring = 'https://connect.qq.com/widget/shareqq/index.html?url=' + encodeURIComponent(url || window.location.href)
+ '&title=' + encodeURIComponent(title || '这文件超棒的,分享给你看看!')
+ '&pic=' + pic || ""
+ '&desc=' + desc || ""
+ '&summary=' + summary || "";
window.open(_sharesinastring, 'newwindow', 'height=600,width=864,top=300,left=300');
}
/**
* 新浪微博分享
*
* @url {string} 分享的网页地址
* @title {string} 标题
* @pic {string} 图片绝对路径
*/
U.UF.OT.weiboShare = function (url, title, pic) {
var _sharesinastring = 'http://v.t.sina.com.cn/share/share.php?url=' + encodeURIComponent(url || window.location.href)
+ '&title=' + encodeURIComponent(title || '这文件超棒的,分享给你看看!') + '&content=utf-8'
+ '&pic=' + pic || "";
window.open(_sharesinastring, 'newwindow', 'height=500,width=800,top=300,left=300');
}
;