JS学习笔记
后端开发者偶尔写写前端页面,记录的笔记,大佬勿喷。
判断是否为JSON
直接给出源码:
const isJson = (str: any) => {
try {
if (typeof JSON.parse(str) == "object") {
return true;
}
} catch (e) {
}
return false;
}
元素居左
一般有2种做法:
- 设置这一行的div的style为:
text-align:left; / text-align:center; / text-align:right;
- 设置该元素的style为:
float:left; / float:right;
注意:元素浮动没有向中间,只有向左或向右。
html的img标签设置大小的问题
- 不设置width和height,默认显示图片的真实大小;
- img只设置width或height中一个,另一个会按比例自动缩放;
- 设置width和height,指定图片的大小,会变形失真。
Array去重
result = net Set(result);
// 不行
result = new Array(result);
// 可行
Array.from(result);
前端传参undefined
很常见的问题,前端通过map形式调用后端接口,传参为undefined:
解决方法:const params = JSON.parse(JSON.stringify(values));
莫名其妙的each问题
如上图,勾选下拉选项之后,右侧没有小勾勾。乍一看以为是样式问题,而且在排查问题过程中也把精力在html样式上。生生耗费2小时,最后一一排除,定位到问题是JS代码片段:
$scope.showZxUser = function (o) {
_.each($scope.selectZxUserList, function (u) {
if (u.realName === o.realName) {
return true;
}
});
return false;
};
修改如下:
$scope.showZxUser = function (o) {
let have = false;
_.each($scope.selectZxUserList, function (u) {
if (u.realName === o.realName) {
have = true;
return have;
}
});
return have;
};
即解决问题:
原因还没整明白。
附:全网为数不多的中文解析:underscore.js 源码分析之 _.each() 函数
弹窗Tip
https://mdbootstrap.com/snippets/jquery/ascensus/333171#html-tab-view
<button type="button" class="kf_flag"
ng-click="openUserFlag3();"
data-placement="top">
<a data-toggle="popover-click" class="kf_flag" data-img="imgs/zjUser.png">
<img ng-show="openFlag3" src="imgs/noselect.svg"/>
<img ng-show="!openFlag3" src="imgs/select.svg"/>
</a>
</button>
<style>
.popover.top {
margin-top: -50px;
}
</style>
// popovers initialization - on click
$('[data-toggle="popover-click"]').popover({
html: true,
trigger: 'click',
placement: 'auto',
content: function () {
return '<img src="' + $(this).data('img') + '" />';
}
});
$scope.openUserFlag1 = function () {
$scope.openFlag1 = !$scope.openFlag1;
};
$scope.openUserFlag2 = function () {
$scope.openFlag2 = !$scope.openFlag2;
};
input元素实现cursor:pointer
在做文件上传时,希望鼠标放到上传按钮后,鼠标指针由箭头变为手型,因此对input元素中type="file"
的样式追加cursor: pointer;
:
<a href="javascript:" class="file" style="!important;">导入
<input type="file" name="file" ng-click="chooseFile(3)" ng-disabled="zjInputWay" id="uploadZjUserFile" />
</a>
<style>
.file input {
cursor: pointer;
}
</style>
参考input元素 实现不了cursor:pointer
解决方法:font-size:0;
ERR_ABORTRD 404
在IDEA中开发Angular JS程序时,遇到报错:
可是这个JS文件明明已经添加进来,而且路径绝对正确无误。
原因:IDEA的热部署功能,对于JS文件远远比Java class文件高效,但是新添加的JS文件,并不能被项目识别,需要重新启动应用!!
所使用的IDEA版本:
类似地,对于已经启动的应用,添加图片资源,此时发现文件预览失败,重启应用即可。
合并
两个 array 合并,使用 array1.concat(array2)
,注意可能会重复。
简单的两个 array 合并且去重,使用array1.concat(array2).unique()
(需要ES6高版本语法支持),或者使用Array.from(new Set(array1.concat(array1)));
借助Set的不可重复性。
两个 array of object 合并且去重,当然,需要指定根据 object 的某个 property 来去重:
const callIdList = new Set(array1.map(d => d.callid));
array1 = [...array1, ...array2.filter(d => !callIdList.has(d.callid))];
scope array concat not updated
JS使用array1.concat(array2)
发现array1
数据并不更新。
解决方法,需要重新赋值:$scope.list = $scope.list.concat(anotherList);
参考链接:scope array concat not updated
日期计算
需求:
日期相加减,具体来说,给定yyyy-MM-dd
形式的日期数据2020-11-11
(实际上是String),希望得到2020-11-05
第一步:
String转Date,Date相加减:
let dateOffset = (24 * 60 * 60 * 1000) * days;
const date = new Date(dateStr);
date.setTime(date.getTime() + dateOffset);
第二步:
Date转String:
const date = new Date();
date.toISOString().split('T')[0];
/**
* 日期格式相加减
* @param dateStr yyyy-MM-dd
* @param days 可正可负
* @returns {string} yyyy-MM-dd
*/
function addDays(dateStr, days) {
if (dateStr == null || dateStr === '') {
return "";
}
let dateOffset = (24 * 60 * 60 * 1000) * days;
const date = new Date(dateStr);
date.setTime(date.getTime() + dateOffset);
return date.toISOString().split('T')[0];
}
JS Date document
JS date subtract
JS date format
预览
图片
<a href="" target="_blank"><img class="img" src="" title="Image" alt="Image"></a>
无需额外的JS库
<a href="http://remote-url/aa.pdf" target="_blank">net pdf</a>
<a href="C:\Users\awesomeme\Downloads\CLICKHOUSE_AND_THE_MAGIC_OF_MATERIALIZED_VIEWS.pdf" target="_blank">local pdf</a>
视频
<a href="C:\Users\wangjian14\Desktop\4\1.mp4" target="_blank"> local mp4 </a>
OFFICE
使用上面的方式,不能预览,只会自动下载。
微软office online提供接口来实现Word、Excel、PPT文档在线预览:http://view.officeapps.live.com/op/view.aspx?src=<Document Location>
export const viewFile = function (url) {
let onlineViewType = ['doc', 'docx', 'xls', 'xlsx', 'xlsm', 'ppt', 'pptx']
let fileTypeName = url.substring(url.lastIndexOf('.') + 1, url.length).split('?')[0]
let isWord = onlineViewType.find((type) => type === fileTypeName)
if (isWord) {
url = 'http://view.officeapps.live.com/op/view.aspx?src=' + url
}
window.open(url, '_blank')
}
如果文件过大,则报错:
File too large,The file specified is larger than what the Office Online Viewers are configured to support.Reduce the size of the file to view it online.
使用Office Online时,注意:Word、PPT文件不能大于10M,Excel文件不能大于5M。
参考:JS实现Word、Excel、PPT在线预览
angular下拉列表
简单可穷举
<select ng-model="stutas">
<option value="">全部</option>
<option value="0">男</option>
<option value="1">女</option>
</select>
简单列表
ng-option指令需要绑定两个属性:
- ng-model:用于获取选定的值;
- ng-options:用于确定下拉列表的元素数组。
<select style="" ng-model="data.startHour" ng-options="hour for hour in hourArray"></select>
// 数组初始化
$scope.hourArray = [];
$scope.initArray = (num) => {
for (let i = 0; i < num; i++) {
$scope.hourArray.push(i);
}
return $scope.hourArray;
};
$scope.initArray(25);
效果图:
分组下拉列表
https://www.cnblogs.com/xing901022/p/5122702.html
Angular2解决方案
AngularJS: ng-bind-html with custom style
HTML页面展示ng-bind-html
绑定的数据,可以是变量或者函数定义,当是函数(JS文件里面定义)时,如果期望返回带有HTML元素的内容时,需要使用符号`引用起来。
<div ng-bind-html="contentShow(rr)"/>
对应的JS函数
controller: function ($scope, $uibModalInstance, $location, $anchorScroll) {
$scope.contentShow = function (item) {
if (item.content != null && item.content !=='') {
return item.content;
} else {
let picType = ['png', 'jpge', 'jpg'];
let suffixCheck = picType.includes(item.fileSuffix);
if (suffixCheck) {
return `<a href="${item.url}" target="_blank"><img class="img" src="${item.url}" title=\"Image\" alt=\"Image\"></a>`;
}
// OFFICE自动下载,PDF/MP4可预览
let otherType = ['pptx', 'ppt', 'xlsx', 'xls', 'docx', 'doc', 'mp4', 'pdf'];
suffixCheck = otherType.includes(item.fileSuffix);
if (suffixCheck) {
return `<a href="${item.url}" target="_blank" style="color:white;text-decoration: underline;">${item.fileName}</a>`;
}
}
};
}
但是,当希望在函数返回的HTML片段里面添加标签如style时,由于跨域问题的存在,style不能生效。
解决方法:
<div ng-bind-html="trustAsHtml(contentShow(rr))"/>
controller: function ($scope, $sce, $uibModalInstance, $location, $anchorScroll) {
$scope.contentShow = function (item) {
if (item.content != null && item.content !=='') {
return item.content;
} else {
let picType = ['png', 'jpge', 'jpg'];
let suffixCheck = picType.includes(item.fileSuffix);
if (suffixCheck) {
return `<a href="${item.url}" target="_blank"><img class="img" src="${item.url}" title=\"Image\" alt=\"Image\"></a>`;
}
let otherType = ['pptx', 'ppt', 'xlsx', 'xls', 'docx', 'doc', 'mp4', 'pdf'];
suffixCheck = otherType.includes(item.fileSuffix);
if (suffixCheck) {
return `<a href="${item.url}" target="_blank" style="color:white;text-decoration: underline;">${item.fileName}</a>`;
}
}
};
$scope.trustAsHtml = function(string) {
return $sce.trustAsHtml(string);
};
}
<div ng-bind-html="trustAsHtml(contentShow(rr))"/>
ng-bind-html style not working
ng-bind-html style
form post with multiple param
$scope.downloadRecord = function (bb) {
// 创建隐藏的可下载链接
const src = 'check/downloadLuyinRecord.do';
let form = document.createElement("form");
form.style.display = 'none';
form.action = src;
form.target = "_blank";
form.method = "post";
document.body.appendChild(form);
let input = document.createElement("input");
input.type = "hidden";
input.name = 'callid';
input.value = id;
form.appendChild(input);
// 必须创建同名的input
let input1 = document.createElement("input");
input1.type = "hidden";
input1.name = 'lineStyle';
input1.value = lineStyle;
form.appendChild(input1);
form.submit();
form.remove();
};
viewBoard.controller('registerCtrl', function ($rootScope, $scope, $http) {
$scope.isinputuser = false;
$scope.register = function () {
let warmMsg = "";
if (!$scope.username || $scope.username.trim().length <= 0) {
warmMsg = "请输入姓名(带数字)";
new hullabaloo().send("添加失败", warmMsg, "danger");
return false;
}
$http.post("/commons/registerUser.do", {
username: $scope.username,
domainName: $scope.domainName,
department: $scope.department,
mail: $scope.mail,
role: $scope.role
}).success(function (response) {
if (response.status === '1') {
new hullabaloo().send("添加成功", "", "success");
} else {
new hullabaloo().send("添加失败", response.msg, "danger");
}
});
};
});