前言
这篇Blog主要用来记录前端开发中碰到的一些问题,以及一些开发技巧的备忘。
调用子IFrame页面上的方法
1
| $(element)[0].contentWindow.methodName();
|
在使用这个方法前,我碰到一个问题。因为子Iframe中的方法只有一行,我就想直接在父页面定义这个方法,但是测试时发现这样方法并不能执行。代码如下:
1 2 3
|
$($("#auditFlowNav li")[authType]).find('a').click();
|
后续修改为:
1 2 3 4 5 6 7
| $(_self)[0].contentWindow.doChangeTab(authType);
function doChangeTab(i) { $($("#auditFlowNav li")[i]).find('a').click(); }
|
使用闭包管理变量作用域
1 2 3 4 5 6 7 8 9 10 11 12 13
| (function(window, $) { window.baseUtil = { add: add };
let tmpArg = '';
function add(arg1, arg2) { return arg1 + arg2; } })(window, jQuery);
|
requireJs的使用
参考Demo:链接
合并两个数组
参考链接:JS合并两个数组的方法
1 2 3 4 5 6 7 8 9 10 11 12 13
| let arr1 = [1,2,3]; let arr2 = [4,5,6];
let arr3 = arr1.concat(arr2);
for(let i in arr2) { arr1.push(arr2[i]); }
arr1.push.apply(arr1, arr2);
|
滚动条下拉加载数据
参考链接:js实现 web页面的滚动条下拉时加载更多
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| let pageSize = 15; let pageNo = 1; let C = 10; let ajaxFlag = true; let dataList = [];
function bindScrollEvent() { let $currentElement = $('#elementId'); $currentElement.unbind("scroll").scroll(function () { let scrollTop = $(this)[0].scrollTop; let scrollHeight = $(this)[0].scrollHeight; let clientHeight = $(this)[0].clientHeight; let leftHeight = (scrollTop + clientHeight) - scrollHeight; if (leftHeight >= -C && ajaxFlag) { ajaxFlag = false; pageNo++; addHtmlElement($currentElement); } }); }
function addHtmlElement($currentElement) { let elementHtml = ''; let lastIndex = $currentElement.find('li').length; let rows = getData(); dataList.push.apply(dataList, rows); rows.forEach(function (data, index) { elementHtml += assembleHtmlElement(data); }); $currentElement[0].innerHTML += elementHtml; ajaxFlag = !isStrEmpty(elementHtml); }
function getData() { let params = { condition: $("#searchForm").serializeObject(), pageSize: pageSize, page: pageNo, }; let rows = []; $.ajax({ type: "get", url: "xxx", data: params, dataType: "json", async: false, success: function (data) { if (data.code == 200) { rows = data.rows; } } }); pageNo++; return rows; }
function isStrEmpty(str) { return str == '' || str == undefined || str == null; }
|
css实现鼠标悬浮文字提示
1 2
| <span data-tips="查看" class="fa fa-search-plus detail"></span>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| <style> .detail { color: #91BD91; font-size: 18px; float: right; position: relative; } .detail:hover { color: #C8DBC8; cursor: pointer; } .detail:after { font-size: 14px; color: #91BD91; content: attr(data-tips); position: absolute; left: -7px; white-space: nowrap; opacity: 0; transform: translateY(-120%); transition: .1s; } .detail:hover:after { opacity: 1; transform: translateY(-100%); } </style>
|
如果需要动态修改 content
值,在 js
中调用下面代码即可
1
| $(element).attr("data-tips", "修改后的内容");
|
利用Promise管理多个异步请求
浏览器端的渲染效果想要达到体验最佳,那就需要对请求进行异步处理,如果想等到所有的异步请求全部执行完毕再进行下一步操作的话,可以引入 Promise
,Demo如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| function executePromiseFun(urls) { let apiDatas = []; urls.forEach(function(url) { let apiItem = getPromiseFun(url); apiDatas.push(apiItem) }); return Promise.all(apiDatas).then(function (data) { return data; }) }
function getPromiseFun(url) { return new Promise(function(resolve, reject) { $.ajax({ type: "get", url: url, async: true, success: function(json) { resolve(json); } }) }) }
|
innerHTML存在的问题
innerHTML的修改和添加,元素中旧的内容被移除新的内容会被重新写入元素。innerHTML内容将会被重新解析和构建元素。例如: innerHTML+ = ‘’ 时,内容”归零” 重写,所有的图片和资源重新加载,这样会消耗更多的时间。@[js] innerHTML有什么缺点?
在 滚动条下拉加载数据 中,渲染数据是通过 innerHTML
完成的,如下

上次的需求中加载的数据没有图片和音视频资源,因此没有问题。这次又收到一个相似的需求,但加载的数据中多了图片和音视频资源,因此出现了问题。每次加载数据后,所有的图片音视频资源都会重新加载一遍。
因此,可以使用替代方案,我这里使用的是 jQuery.append()
方法,替换之后页面资源没有重新加载。
innerHTML
方式页面资源加载情况

替换为 Jquery.append()
后,页面资源加载情况

CSS子元素浮动导致父元素高度坍塌
具体事例详解见:子元素浮动导致父元素高度不够问题的解决方案
解决方案如下:为父元素加上 display: flow-root
。
页面元素垂直居中
推荐下面的方法,不用考虑父元素是否设置的height
值,代码如下:
1 2 3 4 5 6 7 8
| .parent{ position: relative; } .child{ position: absolute; top: 50%; transform: translateY(-50%); }
|
其他的一些情况,参考:CSS垂直居中的12种实现方式
jQuery.data() 方法
有一个 input
表单,注意 data-value
1
| <input type="text" class="form-control" id="publishRegion" name="publishRegion" data-value="" placeholder="选择地区" readonly/>
|
jQuery.data()
就是操作这种 data-xxx
的方法,下面给出示例:
1 2
| let dataValue = $('#publishRegion').data("value"); $('#publishRegion').data("value", "测试");
|
文本溢出显示省略号,鼠标浮动查看全部内容
1 2 3 4 5 6 7
| .ellipse { overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
|
1
| <p class="ellipse" title="这里填写字符串内容">{{this.message}}</p>
|
JS下载文件
第一种,弹出一个新页面进行下载
1
| window.open(url, "_blank");
|
第二种,在当前页面下载
1 2 3 4 5 6 7 8 9
| function fileDownload(url) { let $form = $('<form>'); $form.attr("target",""); $form.attr("method","get"); $form.attr("style","display:none"); $form.attr('action', url); $('body').append($form); $form.submit(); }
|
在页面引入代码编辑器
经过调研,发现了两款插件:Ace 和 Monaco Editor。
我使用的是Ace,下面是相关代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Insert title here</title> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <div th:replace="common/layout :: headerCss"></div> </head> <body> <div class="form-group"> <label class="col-sm-3 control-label">代码编辑</label> <div class="col-sm-10"> <pre class="ace_editor" id="ace_editor" style="min-height:400px"></pre> </div> </div> </form> <div th:replace="common/layout :: footerJs"></div> <script th:src="@{/webjars/hplus/js/plugins/ace/ace.js}"></script> <script th:src="@{/webjars/hplus/js/plugins/ace/ext-language_tools.js}"></script> <script th:src="@{/webjars/hplus/js/plugins/ace/mode-html.js}"></script> <script th:src="@{/webjars/hplus/js/plugins/ace/worker-html.js}"></script> <script th:src="@{/webjars/hplus/js/plugins/ace/html.js}"></script> <script th:src="@{/webjars/hplus/js/plugins/ace/theme-sqlserver.js}"></script> <script th:inline="javascript"> let editor; initAceCode();
function initAceCode() { editor = ace.edit("ace_editor"); editor.setTheme("ace/theme/sqlserver"); editor.session.setMode("ace/mode/html"); editor.setFontSize(14); editor.setReadOnly(false); editor.setOption("wrap", "free"); ace.require("ace/ext/language_tools"); editor.setOptions({ enableBasicAutocompletion: true, enableSnippets: true, enableLiveAutocompletion: true }); } </script> </body> </html>
|
Demo
并不完善,只是方便理解,引入方式大致就是如此。相关的js文件去 Ace插件包下载地址 下载即可。其中可以设置语言和代码样式,这些也可以自定义,关于代码样式的可以参考 Ace主题。其他相关的操作参考 Ace Editor中文文档。
实现效果如下: