Web前端 – 清风亦平凡 https://www.mlplus.net 关注IT世界,记录平凡生活 Fri, 10 Nov 2023 16:07:10 +0000 zh-CN hourly 1 https://wordpress.org/?v=6.4.3 JS录音获取麦克风权限被拒绝访问 https://www.mlplus.net/2023/11/10/js%e5%bd%95%e9%9f%b3%e8%8e%b7%e5%8f%96%e9%ba%a6%e5%85%8b%e9%a3%8e%e6%9d%83%e9%99%90%e8%a2%ab%e6%8b%92%e7%bb%9d%e8%ae%bf%e9%97%ae/ https://www.mlplus.net/2023/11/10/js%e5%bd%95%e9%9f%b3%e8%8e%b7%e5%8f%96%e9%ba%a6%e5%85%8b%e9%a3%8e%e6%9d%83%e9%99%90%e8%a2%ab%e6%8b%92%e7%bb%9d%e8%ae%bf%e9%97%ae/#respond Thu, 09 Nov 2023 16:04:00 +0000 https://www.mlplus.net/?p=4447 背景

因业务需求原因,需要在网页上进行录音,使用Javascript来进行操作,完成录音并保存上传到指定服务器。实现相关代码后进行测试,发现访问音频设备最后被拒绝。

原因

网页上反馈的异常信息如下图所示

网页访问音频设备被拒绝

经过再次的查看,确认未经处理的异常信息如下:

DOMException: Permission denied by system
控制台显示的异常信息

查下浏览器的设置,浏览器是否禁用麦克风,经过确认浏览器并没有发现什么问题。

JS录音获取麦克风权限被拒绝访问-第2张图片
JS录音获取麦克风权限被拒绝访问-第3张图片

浏览器各项检查都非常的正常,尝试录音错误依然再次出现,按道理来讲,应该是没有什么问题的。就目前情况而言,的确可能存在不讲道理的情况呀。随后更换一台电脑进行了一下测试,经过测试发现没有任何问题,正常录音。这就诡异了!也许是音频硬件原因?将这音频设备在其他电脑上进行再次确认,测试结果还是没有问题。这就让人郁闷了.

哎!万万没有想到,麦克风的访问权限在系统设置中根本就没有开。真是服了自己,这个问题竟然没有第一时间确认,真有一巴掌拍在脸上的感觉!

系统声音设置界面
系统麦克风访问权限设置页面

解决

知道了引起异常的具体原因后,解决起来就无比的简单。针对以上问题来说,更改设置就好了。

更改麦克风访问权限
麦克风权限允许后的图例

总结

一些时候往往会忽视一些简单的问题,就默认了这些基础内容不会出现任何问题。当一些基础内容出现问题,就被忽略掉了!还是要避免一些惯性思维,防止不必要的低级问题再次出现。此事记录,更好的警示自己!



转载请注明:清风亦平凡 » JS录音获取麦克风权限被拒绝访问

]]>
https://www.mlplus.net/2023/11/10/js%e5%bd%95%e9%9f%b3%e8%8e%b7%e5%8f%96%e9%ba%a6%e5%85%8b%e9%a3%8e%e6%9d%83%e9%99%90%e8%a2%ab%e6%8b%92%e7%bb%9d%e8%ae%bf%e9%97%ae/feed/ 0
HTML5音频资源加载失败的处理方法 https://www.mlplus.net/2023/07/16/html5-audio-load-fail/ https://www.mlplus.net/2023/07/16/html5-audio-load-fail/#respond Sun, 16 Jul 2023 14:00:00 +0000 https://www.mlplus.net/?p=4202 背景

页面加载很多音频标签,音频资源一些加载不成功,音频标签不可用,并且排除以下几种情况:

  • 检查音频的链接是否有效
  • 检查音频格式是否支持
  • 检查网络连接是否通畅

如果确认以上内容没有任何问题,则是页面加载过多的音频资源而导致部分音频资源加载失败。可以使用JavaScript进行资源加载重试,当然重试的策略需要进行限制,避免无限制尝试。

实现方式

以下是使用JavaScript代码实现自动重新加载资源的一个简单的示例,当音频标签加载失败时,它会自动尝试重新加载音频:


const audio = document.querySelector('audio');

audio.addEventListener('error', () => {
  audio.load();
});



在上面示例中,首先选择了音频标签,并添加了一个错误事件监听器。当发生错误时,错误事件会触发,并调用load()方法来重新加载音频并尝试播放。

如果希望重试的次数有限制,可以使用一个计数器来限制次数,例如:


const audio = document.querySelector('audio');
let retryCount = 0;
const maxRetries = 3;
audio.addEventListener('error', () => {
  if (retryCount < maxRetries) {
    audio.load();
    retryCount++;
  } else {
    console.log('音频加载失败');
  }
});

在以上的示例中,添加了一个retryCount变量来跟踪尝试次数,并添加了一个maxRetries变量来限制最大尝试次数。

如果重试次数小于最大尝试次数,将重新加载音频,并增加重试计数器。如果达到最大尝试次数,将打印一条错误消息。

这样,就可以使用JavaScript代码来实现自动重新加载音频标签了。这只是一个简单的示例,而实际情况可能需要考虑更多的情况,此示例仅供一个参考!



转载请注明:清风亦平凡 » HTML5音频资源加载失败的处理方法

]]>
https://www.mlplus.net/2023/07/16/html5-audio-load-fail/feed/ 0
Chrome浏览器中的XPath https://www.mlplus.net/2022/12/04/chrome%e6%b5%8f%e8%a7%88%e5%99%a8%e4%b8%ad%e7%9a%84xpath/ https://www.mlplus.net/2022/12/04/chrome%e6%b5%8f%e8%a7%88%e5%99%a8%e4%b8%ad%e7%9a%84xpath/#respond Sat, 03 Dec 2022 16:52:11 +0000 https://www.mlplus.net/?p=4030 背景

某一个应用自动在网页上获取一些文本内容,本来是通过document.querySelector来找指定节点。经过一段时间网页貌似升级了,一些节点的class属性的值会出现随机的变动,每次class属性的值都会不一样。最初的方式就失去了作用,根据节点内容的分析发现可以通过xpath来获取。曾经在IE浏览器上使用过XPath,并且API相当简单。在非IE浏览器上貌似没有这么好用。以下内容在Chrome浏览器进行尝试,经过测试可以完成自己的预期工作。

浏览器支持

Mozilla是根据DOM标准来实现对XPath的支持的。DOM Level 3附加标准DOM Level 3 XPath定义了用于在DOM中计算XPath表达式的接口。遗憾的是,这个标准要比微软直观的方式复杂得多。虽然有好多与XPath相关的对象,最重要的两个是:XPathEvaluatorXPathResultXPathEvaluator利用方法evaluate()计算XPath表达式。

evaluate()方法有五个参数:XPath表达式、上下文节点、命名空间解释程序和返回的结果的类型,同时在XPathResult中存放结果(通常为null)。命名空间解释程序,只有在XML代码用到了XML命名空间时才是必要的,所以通常留空,置为null。返回结果的类型,可以是以下十个常量值之一

参数解释
XPathResult.ANY_TYPE返回符合XPath表达式类型的数据
XPathResult.ANY_UNORDERED_NODE_TYPE返回匹配节点的节点集合,但顺序可能与文档中的节点的顺序不匹配
XPathResult.BOOLEAN_TYPE返回布尔值
XPathResult.FIRST_ORDERED_NODE_TYPE返回只包含一个节点的节点集合,且这个节点是在文档中第一个匹配的节点
XPathResult.NUMBER_TYPE返回数字值
XPathResult.ORDERED_NODE_ITERATOR_TYPE返回匹配节点的节点集合,顺序为节点在文档中出现的顺序。这是最常用到的结果类型
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE返回节点集合快照,在文档外捕获节点,这样将来对文档的任何修改都不会影响这个节点列表。节点集合中的节点与它们出现在文档中的顺序一样
XPathResult.STRING_TYPE返回字符串值
XPathResult.UNORDERED_NODE_ITERATOR_TYPE返回匹配节点的节点集合,不过顺序可能不会按照节点在文档中出现的顺序排列
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE返回节点集合快照,在文档外捕获节点,这样将来对文档的任何修改都不会影响这个节点列表。节点集合中的节点和文档中原来的顺序不一定一样。

JavaScript实现XPath选择节点


function xpathQuery(xpath){
  let resultXpath = document.evaluate(xpath, document, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
  let result=[];
  if(resultXpath){
     let item;
     while(item=resultXpath.iterateNext())
     {
        result.push(item);
     }
  } 
  return result;
}

xpathQuery("//div[@class='container-body']/div[contains(@class,'order-item')]");
JavaScript 使用XPath



转载请注明:清风亦平凡 » Chrome浏览器中的XPath

]]>
https://www.mlplus.net/2022/12/04/chrome%e6%b5%8f%e8%a7%88%e5%99%a8%e4%b8%ad%e7%9a%84xpath/feed/ 0
Javascript判断当前页面是否处于激活状态 https://www.mlplus.net/2022/11/21/javascript%e5%88%a4%e6%96%ad%e5%bd%93%e5%89%8d%e9%a1%b5%e9%9d%a2%e6%98%af%e5%90%a6%e5%a4%84%e4%ba%8e%e6%bf%80%e6%b4%bb%e7%8a%b6%e6%80%81/ https://www.mlplus.net/2022/11/21/javascript%e5%88%a4%e6%96%ad%e5%bd%93%e5%89%8d%e9%a1%b5%e9%9d%a2%e6%98%af%e5%90%a6%e5%a4%84%e4%ba%8e%e6%bf%80%e6%b4%bb%e7%8a%b6%e6%80%81/#respond Mon, 21 Nov 2022 05:44:00 +0000 https://www.mlplus.net/?p=4020 背景

现有一个考试项目,当在浏览器进行考试时需要判断用户是否存在切屏,如果切屏就对当前考试进行自动强制交卷。浏览器中可通过window对象的onbluronfocus判断,或者documenthidden属性判断。

获取焦点(onfocus)和失去焦点(onblur)

关于是否失焦点,浏览器对象有onfocus onblur事件可以监听。但是触发这两个事件的前提是页面之前是获取焦点的,就是说要是激活的。也就是说页面刚刚渲染完,用户在没有页面上任何操作时,页面是不会正常监听这两个事件的;或者页面在打开状态下,但是触发了onblur之后并无页面操作的情况下也不会正常监听这两个事件。直到,用户操作页面触发focus,之后离开页面才会触发blur,再次点击到当前页面时才会触发focus,如此反复都会触发相应的事件。

onblur

  • chrome浏览器下,点击console面板也会触发blur事件,前提是之前是focus的状态。
  • 页面最小化;
  • 浏览器切换tab页面;
  • 页面中的任何弹窗;
  • focus状态下切换到其他应用

onfocus

  • 用户存在页面操作(包括页面中js脚本运行。如页面加载完无js运行,用户无操作,则不会触发 );
  • 事件触发前提下,页面最大化;
  • 事件触发前提下,页面从其他tab页切换回当前页面;

onblur与onfocus示例

  
//离开          
window.onblur = function () {
         console&&console.log("切屏了onblur");
 };
 //回来
 window.onfocus = function () {
        console&&console.log("切屏了onfocus");
  };

HTML5新增API

HTML5新增的API, visibilitychange, document.hidden, document.visibilityState来实现相关内容。

visibilitychange

  • 浏览器支持 visibilitychangeHTML5API所以支持持最新浏览器 Chrome, Firefox, IE10+
  • addEventListener添加事件,当页面发生改变就会触发

老版本浏览器如果失效需要添加前缀

  • mozvisibilitychange 火狐
  • msvisibilitychange IE
  • webkitvisibilitychange 谷歌,Safari

document.hidden

hiddendocument的属性,可以判断页面是否显示的是当前的页面。visibilitychange事件就是触发页面可见的事件。当然不同的浏览器内核记得要加前缀。表示页面处于非激活状态,反之处于激活状态。

  • 页面最小化
  • 页面在后台运行
  • 切换tab栏到其他页面

当其hiddenfalse的时候就是当前网页正在被用户浏览,其值为ture就是当前网页进入后台。

document.visibilityState

  • visible 是浏览器当前激活,窗口不是最小化状态
  • hidden 不是当前激活,或者窗口最小化了
  • prerender 重新生成,对用户不可见

visibilitychange事件示例

        
var hiddenProperty = 'hidden' in document ? 'hidden' :
            'webkitHidden' in document ? 'webkitHidden' :
                'mozHidden' in document ? 'mozHidden':null;
        var visibilityChangeEvent = hiddenProperty.replace(/hidden/i, 'visibilitychange');
        var onVisibilityChange = function () {
            if (!document[hiddenProperty]) {
                console && console.log('页面激活');
            } else {
                console && console.log('页面非激活');
            }
        }
        document.addEventListener(visibilityChangeEvent, onVisibilityChange);

以上两种方式在某些情况下存在一定差异,为了实现一些需求,可能需要组合使用。



转载请注明:清风亦平凡 » Javascript判断当前页面是否处于激活状态

]]>
https://www.mlplus.net/2022/11/21/javascript%e5%88%a4%e6%96%ad%e5%bd%93%e5%89%8d%e9%a1%b5%e9%9d%a2%e6%98%af%e5%90%a6%e5%a4%84%e4%ba%8e%e6%bf%80%e6%b4%bb%e7%8a%b6%e6%80%81/feed/ 0
在非HTTPS站点中使用Content Security Policy引发的问题 https://www.mlplus.net/2022/10/25/csp/ https://www.mlplus.net/2022/10/25/csp/#respond Tue, 25 Oct 2022 08:40:42 +0000 https://www.mlplus.net/?p=4011 背景

有一个客户需要对以前老项目部分功能进行升级,需要升级页面按照最新版本的内容进行更新,测试发现页面无法加载。F12使用开发者工具发现所有资源文件异常,所有的资源文件竟然自动将HTTP协议换成 HTTPS 协议。异常信息如下图所示:

资源加载HTTPS错误

项目目前部署是非HTTPS的,很奇怪为什么会自动转换为HTTPS资源。经过排查在异常页面中发现了问题,在head节点下发现以下代码


<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">

以上内容会将HTTP协议自动转换为HTTPS协议。

Content-Security-Policy

Content-Security-PolicyCSP)允许站点管理者控制用户代理能够为指定的页面加载哪些资源。除了少数例外情况,设置的政策主要涉及指定服务器的源和脚本结束点。这将帮助防止跨站脚本攻击(Cross-Site Script)。

CSP 的实质就是白名单制度,大大增强了网页的安全性。攻击者即使发现了漏洞,也没法注入脚本,除非还控制了一台列入了白名单的可信主机。

两种方法可以启用 CSP。一种是通过 HTTP 头信息的Content-Security-Policy的字段。

另一种是通过网页的<meta>标签。

  • 脚本:只信任当前域名
  • <object>标签:不信任任何URL,即不加载任何资源
  • 样式表:只信任cdn.example.orgthird-party.org
  • 框架(frame):必须使用HTTPS协议加载
  • 其他资源:没有限制

限制选项

资源加载限制

以下选项限制各类资源的加载。

  • script-src:外部脚本
  • style-src:样式表
  • img-src:图像
  • media-src:媒体文件(音频和视频)
  • font-src:字体文件
  • object-src:插件(比如 Flash
  • child-src:框架
  • frame-ancestors:嵌入的外部资源(比如<frame><iframe><embed><applet>
  • connect-srcHTTP 连接(通过 XHRWebSocketsEventSource等)
  • worker-srcworker脚本
  • manifest-src:manifest 文件

default-src

default-src用来设置上面各个选项的默认值。


Content-Security-Policy: default-src 'self

上面代码限制所有的外部资源,都只能从当前域名加载。

如果同时设置某个单项限制(比如font-src)和default-src,前者会覆盖后者,即字体文件会采用font-src的值,其他资源依然采用default-src的值。

URL 限制

有时,网页会跟其他 URL 发生联系,这时也可以加以限制。

  • frame-ancestors:限制嵌入框架的网页
  • base-uri:限制<base#href>
  • form-action:限制<form#action>

其他限制

其他一些安全相关的功能,也放在了 CSP 里面。

  • block-all-mixed-contentHTTPS 网页不得加载 HTTP 资源(浏览器已经默认开启)
  • upgrade-insecure-requests:自动将网页上所有加载外部资源的 HTTP 链接换成 HTTPS 协议
  • plugin-types:限制可以使用的插件格式
  • sandbox:浏览器行为的限制,比如不能有弹出窗口等。

参考

https://www.ruanyifeng.com/blog/2016/09/csp.html



转载请注明:清风亦平凡 » 在非HTTPS站点中使用Content Security Policy引发的问题

]]>
https://www.mlplus.net/2022/10/25/csp/feed/ 0
移动端页面禁用缩放 https://www.mlplus.net/2022/01/15/user-scalable-no/ https://www.mlplus.net/2022/01/15/user-scalable-no/#respond Sat, 15 Jan 2022 15:59:00 +0000 https://www.mlplus.net/?p=3589 背景

在调整一个移动端的页面,测试过程中发现在苹果IOS系统的浏览器中缩放异常,其实页面操作上来讲是不需要当前页面缩放的。所以,就需要禁止当前页面的缩放操作。经过确认,可以使用以下代码实现禁止缩放操作。


<meta name="viewport" content="width=device-width,initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">

Viewport

属性名取值描述
width正整数或device-width定义视口的宽度,单位为像素
height正整数或device-height定义视口的高度,单位为像素,一般不用
initial-scale[0.0-10.0]定义初始缩放值
minimum-scale[0.0-10.0]定义放大最大比例,它必须小于或等于maximum-scale设置
maximum-scale[0.0-10.0]定义缩小最小比例,它必须大于或等于minimum-scale设置
user-scalableyes / no定义是否允许用户手动缩放页面,默认值 yes

注意

  • viewport 标签只对移动端浏览器有效,对 PC 端浏览器是无效的
  • 当缩放比例为 100% 时,dip 宽度 = CSS 像素宽度 = 理想视口的宽度 = 布局视口的宽度
  • 单独设置 initial-scalewidth 都会有兼容性问题,所以设置布局视口为理想视口的最佳方法是同时设置这两个属性
  • 即使设置了 user-scalable = no,在 Android Chrome 浏览器中也可以强制启用手动缩放



转载请注明:清风亦平凡 » 移动端页面禁用缩放

]]>
https://www.mlplus.net/2022/01/15/user-scalable-no/feed/ 0
CSS层叠样式表实现全站灰度(grayscale ) https://www.mlplus.net/2020/04/04/cssgrayscale/ https://www.mlplus.net/2020/04/04/cssgrayscale/#respond Sat, 04 Apr 2020 01:00:00 +0000 https://www.mlplus.net/?p=2679 为表达全国各族人民对抗击新冠肺炎疫情斗争牺牲烈士和逝世同胞的深切哀悼,国务院今天发布公告,决定2020年4月4日举行全国性哀悼活动。在此期间,全国和驻外使领馆下半旗志哀,全国停止公共娱乐活动。4月4日10时起,全国人民默哀3分钟,汽车、火车、舰船鸣笛,防空警报鸣响。而各大网站均实现全站灰度,腾讯视频、爱奇艺停止所有娱乐类型视频入口。

实现全站灰度可以使用CSS或者使用其他JS插件处理,例如:grayscale js。本博使用的是CSS处理全站灰度,代码示例如下:


html {
-webkit-filter: grayscale(100%);
-moz-filter: grayscale(100%);
-ms-filter: grayscale(100%);
-o-filter: grayscale(100%);
filter: grayscale(100%);
filter:progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);
_filter:none;
}



转载请注明:清风亦平凡 » CSS层叠样式表实现全站灰度(grayscale )

]]>
https://www.mlplus.net/2020/04/04/cssgrayscale/feed/ 0
js Date 操作之神奇的 date https://www.mlplus.net/2018/12/03/jsdateoperation/ https://www.mlplus.net/2018/12/03/jsdateoperation/#respond Mon, 03 Dec 2018 02:35:33 +0000 http://www.skyfinder.cc/?p=1009 Date 对象算是较常用的对象之一,但很多人完全不会操作,就算一些简单的操作也用 moment 而不自己尝试一下。本次分享下 Date 中的 date 使用技巧,希望能给大家启发。

MDN官网介绍

setDate()方法根据本地时间来指定一个日期对象的天数。如果 dayValue 超出了月份的合理范围,setDate 将会相应地更新 Date 对象。例如,如果为 dayValue 指定0,那么日期就会被设置为上个月的最后一天。

获取月份天数


// 获取月份天数
function getMonthDayCount(year, month) {
  return new Date(year, month, 0).getDate();
}
console.log(getMonthDayCount(2017, 10)); // 31

Date 第三个参数的本质跟 setDate 是一样的。因为 date 为 0 时自动退到上个月的最后一天,所以这里月份也不需要减,正好的。

获取所有月份天数

function getAllMonthDayCount(year) {
  var days = [31, new Date(year, 2, 0).getDate(), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
  return days;
}
console.log(getAllMonthDayCount(2016));// [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

这个算是上面的延伸,不多解释。

是否是闰年

 function isLeapYear(year) {
  return (year % 4 == 0) && (year % 100 != 0 || year % 400 == 0);
}

这是网上的代码,相信大多数人都用。但其实你真的理解或者能记住么?反正我不能。。

function isLeapYear(year) {
  return new Date(year, 2, 0).getDate() === 29;
}
console.log([
  isLeapYear(2000),
  isLeapYear(2016),
  isLeapYear(2017),
  isLeapYear(2018)
]); // [ true, true, false, false ]

这样看,是不是就非常简单容易理解了。而且都不需要记,是不是想忘都忘不了?

天数加减操作

之前看到有人用相对秒数在计算几天前或几天后,甚至还在算跨月,跨年的情况。其实直接 setDate 就好了,自动处理 跨月,跨年 的情况。

 

// 10天后是几月几号
var dt = new Date('2016-12-25');
dt.setDate(dt.getDate() + 10);
console.log(dt.toLocaleDateString()); // 2017/1/4


// 10天前是几月几号
var dt = new Date('2017-01-04');
dt.setDate(dt.getDate() - 10);
console.log(dt.toLocaleDateString()); // 2016/12/25

小结

虽然这些东西很基础,说方法名,可能大家都知道,但很多人却依然不会去使用。就跟用 jq 却依然 for 循环处理结果一样。这里只列举了部分例子,也许会有其他神奇的操作技巧等你去发现。

 

作者: 楼教主

链接: http://www.52cik.com/2017/10/11/js-date-month.html

 

 

 

转载请注明:清风亦平凡 » js Date 操作之神奇的 date

]]>
https://www.mlplus.net/2018/12/03/jsdateoperation/feed/ 0
JQuery特效单击漂浮文字 https://www.mlplus.net/2018/11/22/javascriptspecialeffect/ https://www.mlplus.net/2018/11/22/javascriptspecialeffect/#respond Thu, 22 Nov 2018 01:13:13 +0000 http://www.skyfinder.cc/?p=857 在一些博客上遇到点击鼠标的时候有文字或者符号漂浮,感觉挺不错的。如下图:

JQuery特效单击漂浮文字-第0张图片
JQuery特效单击漂浮文字-第1张图片

JQuery代码实现类似效果:

var a_idx = 0;
jQuery(document).ready(function($) {
    $("body").click(function(e){
var a = new Array("Javascript", "DotNet", "C#", "Java", "C", "C++", "HTML", "CSS", "NodeJS", "PHP", "SQL");
        var $i = $("<span/>").text(a[a_idx]);
a_idx = (a_idx + 1) % a.length;
        var x = e.pageX, y = e.pageY;
        $i.css({
            "z-index":99999,
            "top":y-20,
            "left":x,
            "position":"absolute",
            "color":"red"
        });
        $("body").append($i);
        $i.animate(
            {"top":y-180,"opacity":0},
            1500,
            function(){$i.remove();}
        );
    });
});



转载请注明:清风亦平凡 » JQuery特效单击漂浮文字

]]>
https://www.mlplus.net/2018/11/22/javascriptspecialeffect/feed/ 0
JavaScript获取URL地址参数 https://www.mlplus.net/2018/10/11/javascriptgeturlparameter/ https://www.mlplus.net/2018/10/11/javascriptgeturlparameter/#respond Thu, 11 Oct 2018 04:30:32 +0000 http://www.skyfinder.cc/?p=535 有时候需要通过JavaScript中获取网址中传递的参数,以下就提供两种方法,仅供参考。这个也是很早时候的内容了,由原来的QQ空间整理出来,这里也做下记录。

方法一:正则分析法

function getQueryString(name) {
    var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
    var r = window.location.search.substr(1).match(reg);
    if (r != null) {
        return unescape(r[2]);
    }
    return null;
}

调用方法:

alert(GetQueryString("参数名1"));
alert(GetQueryString("参数名2"));
alert(GetQueryString("参数名3"));

方法二:split分割法

function GetQueryString(key) {
    var param = window.location.search.replace(/^\?/, "");
    var returnValue = [];
    var TempValue = param.split("&");
    var TempArr = [];
    for (var i = 0; i < TempValue.length; i++) {
        TempArr = TempValue[i].split("=");
        returnValue[TempArr[0].toLowerCase()] = TempArr[1];
    }
    return returnValue[key.toLowerCase()] || null;
}

调用方法:

alert(GetQueryString("参数名1"));

 

 

 

 

 

转载请注明:清风亦平凡 » JavaScript获取URL地址参数

]]>
https://www.mlplus.net/2018/10/11/javascriptgeturlparameter/feed/ 0
Javascript实现数组类 https://www.mlplus.net/2018/09/03/javascriptarrayclass/ https://www.mlplus.net/2018/09/03/javascriptarrayclass/#respond Mon, 03 Sep 2018 04:21:18 +0000 http://www.skyfinder.cc/?p=540 //数组类 function ArrayList() { this.length = 0; this.array = new Array(); this.Item = function(index) { return this.array[index]; } this.Add = function(value) { this.array[this.length] = value; this.length++; } this.Remove = function(value) { if (this.length >= 1) { for (var i = 0; i < this.length; i++) { if (this.array[i] == value) { for (var j = i; j < (this.length - 1); j++) { this.array[j] = this.array[j + 1]; } this.length--; this.array[this.length] = null; this.array.length--; break; } } } else { this.length = 0; } } this.Insert = function(value, index) { if (index < 0){ index = 0; } if ((this.length >= 1) && (index < this.length)) { for (var i = this.length; i > index; i--) { this.array[i] = this.array[i - 1]; } this.array[index] = value; this.length++; } else { this.Add(value); } } this.Exist = function(value) { if (this.length > 1) { for (var i = 0; i < this.length; i++) { if (this.array[i] == value) { return true; } } } return false; } this.Clear = function() { this.array.length = 0; this.length = 0; } this.GetArray = function() { return this.array; } this.Getlength = function() { return this.length; } this.Import = function(splitString, splitChar) { this.array = splitString.split(splitChar); this.length = this.array.length; } this.Export = function(joinChar) { var strReturn = ""; if (this.length >= 1) { for (var i = 0; i < this.length; i++) { strReturn += this.array[i]; if (i < (this.length - 1)) { strReturn += joinChar; } } } return strReturn; } }

 

 

 

转载请注明:清风亦平凡 » Javascript实现数组类

]]>
https://www.mlplus.net/2018/09/03/javascriptarrayclass/feed/ 0
Jquery插件实现outerHTML https://www.mlplus.net/2016/11/09/outerhtmlforjquery/ https://www.mlplus.net/2016/11/09/outerhtmlforjquery/#respond Wed, 09 Nov 2016 04:55:36 +0000 http://www.skyfinder.cc/?p=55 $.fn.outerHTML = function() { return (!this.length) ? this: (this[0].outerHTML || (function(el) { var div = document.createElement('div'); div.appendChild(el.cloneNode(true)); var contents = div.innerHTML; div = null; return contents; })(this[0])); }

转载请注明:清风亦平凡 » Jquery插件实现outerHTML

]]>
https://www.mlplus.net/2016/11/09/outerhtmlforjquery/feed/ 0
require.js的用法 https://www.mlplus.net/2016/08/22/requireusemethod/ https://www.mlplus.net/2016/08/22/requireusemethod/#respond Mon, 22 Aug 2016 14:07:11 +0000 http://www.skyfinder.cc/?p=92 一、为什么要用require.js?

最早的时候,所有Javascript代码都写在一个文件里面,只要加载这一个文件就够了。后来,代码越来越多,一个文件不够了,必须分成多个文件,依次加载。下面的网页代码,相信很多人都见过。


<script src="1.js"></script>
<script src="2.js"></script>
<script src="3.js"></script>
<script src="4.js"></script>
<script src="5.js"></script>
<script src="6.js"></script>

这段代码依次加载多个js文件。

这样的写法有很大的缺点。首先,加载的时候,浏览器会停止网页渲染,加载文件越多,网页失去响应的时间就会越长;其次,由于js文件之间存在依赖关系,因此必须严格保证加载顺序(比如上例的1.js要在2.js的前面),依赖性最大的模块一定要放到最后加载,当依赖关系很复杂的时候,代码的编写和维护都会变得困难。

require.js的诞生,就是为了解决这两个问题:

 

(1)实现js文件的异步加载,避免网页失去响应;

(2)管理模块之间的依赖性,便于代码的编写和维护;

二、require.js的加载

使用require.js的第一步,是先去官方网站下载最新版本。下载后,假定把它放在js子目录下面,就可以加载了。


<script src="js/require.js"></script>t>

有人可能会想到,加载这个文件,也可能造成网页失去响应。解决办法有两个,一个是把它放在网页底部加载,另一个是写成下面这样:


<script src="js/require.js" defer async="true" ></script>

async属性表明这个文件需要异步加载,避免网页失去响应。IE不支持这个属性,只支持defer,所以把defer也写上。加载require.js以后,下一步就要加载我们自己的代码了。假定我们自己的代码文件是main.js,也放在js目录下面。那么,只需要写成下面这样就行了:


<script src="js/require.js" data-main="js/main"></script>

data-main属性的作用是,指定网页程序的主模块。在上例中,就是js目录下面的main.js,这个文件会第一个被require.js加载。由于require.js默认的文件后缀名是js,所以可以把main.js简写成main。

三、主模块的写法

上一节的main.js,我把它称为”主模块”,意思是整个网页的入口代码。它有点像C语言的main()函数,所有代码都从这儿开始运行。下面就来看,怎么写main.js。如果我们的代码不依赖任何其他模块,那么可以直接写javascript代码。


     // main.js
alert("加载成功!");

但这样的话,就没必要使用require.js了。真正常见的情况是,主模块依赖于其他模块,这时就要使用AMD规范定义的的require()函数。


// main.js
require(['moduleA', 'moduleB', 'moduleC'], function (moduleA, moduleB, moduleC){
  // some code here
});

require()函数接受两个参数。第一个参数是一个数组,表示所依赖的模块,上例就是[‘moduleA’, ‘moduleB’, ‘moduleC’],即主模块依赖这三个模块;第二个参数是一个回调函数,当前面指定的模块都加载成功后,它将被调用。加载的模块会以参数形式传入该函数,从而在回调函数内部就可以使用这些模块。

require()异步加载moduleA,moduleB和moduleC,浏览器不会失去响应;它指定的回调函数,只有前面的模块都加载成功后,才会运行,解决了依赖性的问题。下面,我们看一个实际的例子。

假定主模块依赖jquery、underscore和backbone这三个模块,main.js就可以这样写:

    require(['jquery', 'underscore', 'backbone'], function ($, _, Backbone){
  // some code here
});

equire.js会先加载jQuery、underscore和backbone,然后再运行回调函数。主模块的代码就写在回调函数中。

四、模块的加载

上一节最后的示例中,主模块的依赖模块是[‘jquery’, ‘underscore’, ‘backbone’]。默认情况下,require.js假定这三个模块与main.js在同一个目录,文件名分别为jquery.js,underscore.js和backbone.js,然后自动加载。

使用require.config()方法,我们可以对模块的加载行为进行自定义。require.config()就写在主模块(main.js)的头部。参数就是一个对象,这个对象的paths属性指定各个模块的加载路径。

require.config({
   paths: {
     "jquery": "jquery.min",
     "underscore": "underscore.min",
     "backbone": "backbone.min"
   }
 });

上面的代码给出了三个模块的文件名,路径默认与main.js在同一个目录(js子目录)。如果这些模块在其他目录,比如js/lib目录,则有两种写法。一种是逐一指定路径。


require.config({
   paths: {
     "jquery": "lib/jquery.min",
     "underscore": "lib/underscore.min",
     "backbone": "lib/backbone.min"
   }
 });

另一种则是直接改变基目录(baseUrl)。


require.config({
   baseUrl: "js/lib",
   paths: {
     "jquery": "jquery.min",
     "underscore": "underscore.min",
     "backbone": "backbone.min"
   }
 });

如果某个模块在另一台主机上,也可以直接指定它的网址,比如:


 require.config({
  paths: {
    "jquery": "https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min"
  }
});

require.js要求,每个模块是一个单独的js文件。这样的话,如果加载多个模块,就会发出多次HTTP请求,会影响网页的加载速度。因此,require.js提供了一个优化工具,当模块部署完毕以后,可以用这个工具将多个模块合并在一个文件中,减少HTTP请求数。

五、AMD模块的写法

require.js加载的模块,采用AMD规范。也就是说,模块必须按照AMD的规定来写。具体来说,就是模块必须采用特定的define()函数来定义。如果一个模块不依赖其他模块,那么可以直接定义在define()函数之中。

假定现在有一个math.js文件,它定义了一个math模块。那么,math.js就要这样写:


// math.js
define(function (){
   var add = function (x,y){
     return x+y;
   };
   return {
     add: add
   };
 });

加载方法如下:


// main.js
require(['math'], function (math){
  alert(math.add(1,1));
});

如果这个模块还依赖其他模块,那么define()函数的第一个参数,必须是一个数组,指明该模块的依赖性。


define(['myLib'], function(myLib){
   function foo(){
     myLib.doSomething();
   }
   return {
     foo : foo
   };
});

当require()函数加载上面这个模块的时候,就会先加载myLib.js文件。

六、加载非规范的模块

理论上,require.js加载的模块,必须是按照AMD规范、用define()函数定义的模块。但是实际上,虽然已经有一部分流行的函数库(比如jQuery)符合AMD规范,更多的库并不符合。那么,require.js是否能够加载非规范的模块呢?

回答是可以的。

这样的模块在用require()加载之前,要先用require.config()方法,定义它们的一些特征。

举例来说,underscore和backbone这两个库,都没有采用AMD规范编写。如果要加载它们的话,必须先定义它们的特征。

require.config({
   shim: {
 
     'underscore':{
       exports: '_'
     },
     'backbone': {
       deps: ['underscore', 'jquery'],
       exports: 'Backbone'
     }
   }
 });

require.config()接受一个配置对象,这个对象除了有前面说过的paths属性之外,还有一个shim属性,专门用来配置不兼容的模块。具体来说,每个模块要定义(1)exports值(输出的变量名),表明这个模块外部调用时的名称;(2)deps数组,表明该模块的依赖性。

比如,jQuery的插件可以这样定义:


shim: {
   'jquery.scroll': {
     deps: ['jquery'],
     exports: 'jQuery.fn.scroll'
   }
 }

七、require.js插件

require.js还提供一系列插件,实现一些特定的功能。

domready插件,可以让回调函数在页面DOM结构加载完成后再运行


require(['domready!'], function (doc){
  // called once the DOM is ready
});

text和image插件,则是允许require.js加载文本和图片文件。


define([
   'text!review.txt',
   'image!cat.jpg'
   ],
 
   function(review,cat){
     console.log(review);
     document.body.appendChild(cat);
   }
 );

类似的插件还有json和mdown,用于加载json文件和markdown文件。

以上文章转载于(阮一峰):http://www.ruanyifeng.com/blog/2012/11/require_js.html

转载请注明:清风亦平凡 » require.js的用法

]]>
https://www.mlplus.net/2016/08/22/requireusemethod/feed/ 0
javascript实现的iframe数据共享接口 https://www.mlplus.net/2016/08/17/javascriptiframedatashare/ https://www.mlplus.net/2016/08/17/javascriptiframedatashare/#respond Wed, 17 Aug 2016 10:03:54 +0000 http://www.skyfinder.cc/?p=88 在iframe与父窗口或者与子窗口传递数据是一个麻烦的事情,如果我们能够写一个一劳永逸的接口那就再方便不过了,下面就来简答介绍一下如何实现此功能。原理就是将数据缓存早window.top这个窗口,这样无论子窗口父窗口的层次如何变化,数据总是存在不会变化的。


var dataShare = {
    setData: function(name, value) {
        var top = window.top,
        cache = top['_CACHE'] || {};
        top['_CACHE'] = cache;
        return value ? cache[name] = value: cache[name];
    },
    removeData: function(name) {
        var cache = window.top['_CACHE'];
        if (cache && cache[name]) {
            delete cache[name];
        }
    }
};
dataShare.setData("Url", "https://www.mlplus.net");

转载请注明:清风亦平凡 » javascript实现的iframe数据共享接口

]]>
https://www.mlplus.net/2016/08/17/javascriptiframedatashare/feed/ 0
JavaScript获取用户的DPI https://www.mlplus.net/2016/07/02/javascript-dpi/ https://www.mlplus.net/2016/07/02/javascript-dpi/#respond Sat, 02 Jul 2016 08:54:18 +0000 http://www.skyfinder.cc/?p=86 在某些情况下,需要获得用户的DPI。以下方法是用JavaScript实现获取用户的DPI。


function getDPI() {
        var arrDPI = new Array;
        var devicePixelRatio = window.devicePixelRatio || 1;
        var tmpNode = document.createElement("DIV");
        tmpNode.style.cssText = "height: 1in; left: -100%; position: absolute; top: -100%; width: 1in;";
        document.body.appendChild(tmpNode);
        arrDPI[0] = parseInt(tmpNode.offsetWidth)* devicePixelRatio;
        arrDPI[1] = parseInt(tmpNode.offsetHeight)*devicePixelRatio;
        tmpNode.parentNode.removeChild(tmpNode);
         
        return arrDPI;
}
alert(getDPI());

转载请注明:清风亦平凡 » JavaScript获取用户的DPI

]]>
https://www.mlplus.net/2016/07/02/javascript-dpi/feed/ 0
JavaScript实现金额转为大写 https://www.mlplus.net/2016/07/02/jamountcapital/ https://www.mlplus.net/2016/07/02/jamountcapital/#respond Sat, 02 Jul 2016 08:51:17 +0000 http://www.skyfinder.cc/?p=84 此方法为招商银行网上银行对金额进行大写的转换方法。


function ConvertUpperMoney(whole) {
 //金额转换。输入数字字符串,低至分位,高位不为零
    var GBK_unit1 = "分角";
    var GBK_unit2 = "圆拾佰仟";
    var GBK_unit3 = "万拾佰仟"
    var GBK_unit4 = "亿拾佰仟";
    var GBK_num = "零壹贰叁肆伍陆柒捌玖";
    var section1 = "";
    if (whole.length - 2 >= 0) section1 = whole.substr(whole.length - 2, 2);
    else section1 = whole.substr(0, whole.length);

    var section2 = "";
    if (whole.length - 6 >= 0) section2 = whole.substr(whole.length - 6, 4);
    else if (whole.length - 2 > 0) section2 = whole.substr(0, whole.length - 2);

    var section3 = "";
    if (whole.length - 6 > 0) section3 = whole.substr(0, whole.length - 6);
    var str_GBK = "";

    //分角处理
    if (section1 == "") return str_GBK;
    for (var i = 0; i < section1.length; i++) {
        var n = section1.charAt(section1.length - 1 - i);
        if (n != '0') str_GBK = GBK_num.substr(Number(n), 1) + GBK_unit1.substr(i, 1) + str_GBK;
        else if (i == 1 && str_GBK.substr(0, 1) != "" && section2 != "") //角位加零
        str_GBK = GBK_num.substr(Number(n), 1) + str_GBK;
    }

    //圆拾佰仟处理
    if (str_GBK == "") str_GBK = "整";
    if (section2 == "") return str_GBK;
    for (var i = 0; i < section2.length; i++) {
        var n = section2.charAt(section2.length - 1 - i);
        if (n != '0') str_GBK = GBK_num.substr(Number(n), 1) + GBK_unit2.substr(i, 1) + str_GBK;
        else if (i == 0) //圆位零字处理
        str_GBK = GBK_unit2.substr(i, 1) + str_GBK;
        else if (str_GBK.substr(0, 1) != "零" && str_GBK.substr(0, 1) != "圆") //拾佰仟位零字处理
        str_GBK = GBK_num.substr(Number(n), 1) + str_GBK;
    }

    //万拾佰仟、亿拾佰仟循环处理
    if (section3 == "") return str_GBK;
    for (var i = 0,
    k = 0; i < section3.length; i = i + 4, k = (k + 1) % 2) { var sectionSub = ""; var start = section3.length - (4 + i); if (start >= 0) {
            sectionSub = section3.substr(start, 4);
        } else {
            sectionSub = section3.substr(0, 4 + start);
        }

        if (parseInt(sectionSub) == 0 && k == 0) //万拾佰仟节全为零跳过
        {
            continue;
        }

        for (var j = 0; j < sectionSub.length; j++) {
            var n = sectionSub.charAt(sectionSub.length - 1 - j);
            if (k == 0) //万拾佰仟处理
            {
                if (n != '0') str_GBK = GBK_num.substr(Number(n), 1) + GBK_unit3.substr(j, 1) + str_GBK;
                else if (j == 0) //万位零字处理
                str_GBK = GBK_unit3.substr(j, 1) + str_GBK;
                else if (str_GBK.substr(0, 1) != "零" && str_GBK.substr(0, 1) != "万") //拾佰仟零字处理
                str_GBK = GBK_num.substr(Number(n), 1) + str_GBK;
            } else //亿拾佰仟处理
            {
                if (n != '0') str_GBK = GBK_num.substr(Number(n), 1) + GBK_unit4.substr(j, 1) + str_GBK;
                else if (j == 0) //亿位零字处理
                str_GBK = GBK_unit4.substr(j, 1) + str_GBK;
                else if (str_GBK.substr(0, 1) != "零" && str_GBK.substr(0, 1) != "亿") //拾佰仟零字处理
                str_GBK = GBK_num.substr(Number(n), 1) + str_GBK;
            }
        }
    }
    return str_GBK;
}
var Money = 50000000;
//传入函数的时候要转换为分
console.log(ConvertUpperMoney(String((Money * 100))));

转载请注明:清风亦平凡 » JavaScript实现金额转为大写

]]>
https://www.mlplus.net/2016/07/02/jamountcapital/feed/ 0
Javascript简单实现HTML元素抖动效果 https://www.mlplus.net/2016/07/02/javascript-html/ https://www.mlplus.net/2016/07/02/javascript-html/#respond Sat, 02 Jul 2016 08:07:06 +0000 http://www.skyfinder.cc/?p=77 <!doctype html> <html> <head> <meta charset="utf-8"> <title></title> <script type="text/javascript">function shake(id) { var style = document.getElementById(id).style, p = [4, 8, 4, 0, -4, -8, -4, 0], fx = function() { style.marginLeft = p.shift() + 'px'; if (p.length <= 0) { style.marginLeft = 0; clearInterval(timerId); }; }; p = p.concat(p.concat(p)); timerId = setInterval(fx, 13); } window.onload = function() { shake("txtUserName"); };</script> </head> <body> <input type="text" id="txtUserName" value="www.skyfinder.cc" /> <div> <input type="button" id="btnStartShake" value="抖动" onclick='shake("txtUserName");' /></div> </body> </html>



转载请注明:清风亦平凡 » Javascript简单实现HTML元素抖动效果

]]>
https://www.mlplus.net/2016/07/02/javascript-html/feed/ 0
TpLink路由器登录密码加密算法 https://www.mlplus.net/2016/07/01/tplink/ https://www.mlplus.net/2016/07/01/tplink/#respond Fri, 01 Jul 2016 07:51:24 +0000 http://www.skyfinder.cc/?p=74 var TpLinkPassWordEnCode = { _strDe: "RDpbLfCPsJZ7fiv", _dic: "yLwVl0zKqws7LgKPRQ84Mdt708T1qQ3Ha7xv3H7NyU84p21BriUWBU43odz3iP4rBL3cD02KZciX" + "TysVXiV8ngg6vL48rPJyAUw0HurW20xqxv9aYb4M9wK1Ae0wlro510qXeU07kV57fQMc8L6aLgML" + "wygtc0F10a0Dg70TOoouyFhdysuRMO51yY5ZlOZZLEal1h0t9YQW0Ko7oBwmCAHoic4HYbUyVeU3" + "sfQ1xtXcPcf1aT303wAQhv66qzW", securityEncode: function (pwd) { var dictionary = this._dic; var output = ""; var len, len1, len2, lenDict; var cl = 0xBB, cr = 0xBB; len1 = pwd.length; len2 = this._strDe.length; lenDict = dictionary.length; len = len1 > len2 ? len1 : len2; for (var index = 0; index < len; index++) { cl = 0xBB; cr = 0xBB; if (index >= len1) { cr = this._strDe.charCodeAt(index); } else if (index >= len2) { cl = pwd.charCodeAt(index); } else { cl = pwd.charCodeAt(index); cr = this._strDe.charCodeAt(index); } output += dictionary.charAt((cl ^ cr) % lenDict); } return output; } }; console.log(TpLinkPassWordEnCode.securityEncode("admin"));

转载请注明:清风亦平凡 » TpLink路由器登录密码加密算法

]]>
https://www.mlplus.net/2016/07/01/tplink/feed/ 0
JavaScript对象深浅拷贝 https://www.mlplus.net/2016/07/01/javascriptobjectdepthcopy/ https://www.mlplus.net/2016/07/01/javascriptobjectdepthcopy/#respond Fri, 01 Jul 2016 07:47:27 +0000 http://www.skyfinder.cc/?p=72 浅拷贝:


function extendCopy(p) {    
    var c = {};    
    for (var i in p) {      
        c[i] = p[i];    
    }    
    c.uber = p;    
    return c;
}

深拷贝:


function deepCopy(p, c) {    
    var c = c || {};    
    for (var i in p) {      
        if (typeof p[i] === 'object') {
            c[i] = (p[i].constructor === Array) ? [] : {};
            deepCopy(p[i], c[i]);      
        } else {      
            c[i] = p[i];      
        }    
    }    
    return c;  
}

转载请注明:清风亦平凡 » JavaScript对象深浅拷贝

]]>
https://www.mlplus.net/2016/07/01/javascriptobjectdepthcopy/feed/ 0
javaScript日期格式化 https://www.mlplus.net/2016/07/01/javascriptdateformatter/ https://www.mlplus.net/2016/07/01/javascriptdateformatter/#respond Fri, 01 Jul 2016 07:44:15 +0000 http://www.skyfinder.cc/?p=70 /* var d=new Date(); console.log(d.toString()); //2012-7-27 9:26:52 console.log(d.toString("")); //2012-7-27 9:26:52 console.log(d.toString("yyyy-MM-dd HH:mm:ss")); //2012-07-27 09:26:52 console.log(d.toString("yyyy年MM月dd日 HH:mm:ss")); //2012年07月27日 09:26:52 console.log(d.toString("yyyy-MM-dd HH:mm:ss fff")); //2012-07-27 09:26:52 237 console.log(d.toString("yyyy年 MMM dd EEE")); //2012年 七月 27 星期五 console.log(d.toString("yyyy MMM dd EEE","en")); //2012 Jul 27 Fri */ Date.prototype.toString = function(format, loc) { var time = {}; time.Year = this.getFullYear(); time.TYear = ("" + time.Year).substr(2); time.Month = this.getMonth() + 1; time.TMonth = time.Month < 10 ? "0" + time.Month: time.Month; time.Day = this.getDate(); time.TDay = time.Day < 10 ? "0" + time.Day: time.Day; time.Hour = this.getHours(); time.THour = time.Hour < 10 ? "0" + time.Hour: time.Hour; time.hour = time.Hour < 13 ? time.Hour: time.Hour - 12; time.Thour = time.hour < 10 ? "0" + time.hour: time.hour; time.Minute = this.getMinutes(); time.TMinute = time.Minute < 10 ? "0" + time.Minute: time.Minute; time.Second = this.getSeconds(); time.TSecond = time.Second < 10 ? "0" + time.Second: time.Second; time.Millisecond = this.getMilliseconds(); time.Week = this.getDay(); var MMMArrEn = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; var MMMArr = ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"]; var WeekArrEn = ["Sun", "Mon", "Tue", "Web", "Thu", "Fri", "Sat"]; var WeekArr = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]; var oNumber = time.Millisecond / 1000; if (format != undefined && format.replace(/\s/g, "").length > 0) { if (loc != undefined && loc == "en") { MMMArr = MMMArrEn.slice(0); WeekArr = WeekArrEn.slice(0); } format = format.replace(/yyyy/ig, time.Year).replace(/yyy/ig, time.Year).replace(/yy/ig, time.TYear).replace(/y/ig, time.TYear).replace(/MMM/g, MMMArr[time.Month - 1]).replace(/MM/g, time.TMonth).replace(/M/g, time.Month).replace(/dd/ig, time.TDay).replace(/d/ig, time.Day).replace(/HH/g, time.THour).replace(/H/g, time.Hour).replace(/hh/g, time.Thour).replace(/h/g, time.hour).replace(/mm/g, time.TMinute).replace(/m/g, time.Minute).replace(/ss/ig, time.TSecond).replace(/s/ig, time.Second).replace(/fff/ig, time.Millisecond).replace(/ff/ig, oNumber.toFixed(2) * 100).replace(/f/ig, oNumber.toFixed(1) * 10).replace(/EEE/g, WeekArr[time.Week]); } else { format = time.Year + "-" + time.Month + "-" + time.Day + " " + time.Hour + ":" + time.Minute + ":" + time.Second; } return format; } /* var time1 = new Date("2012/01/01 00:00:00 UTC+800"); var str1 = time1.format("yyyy年MM月dd日 H时mm分ss秒 TT") console.log("Date["+time1+"]"); console.log("格式化结果为:" + str1); var str2 = "2012年1月23日"; var time2 = Date.parseFormat(str2, "yyyy年M月dd日"); console.log("时间字符串:"+str2); console.log("格式化结果: Date["+time2+"]"); */ Date.format = function(d, mask) { var zeroize = function(value, length) { if (!length) length = 2; value = String(value); for (var i = 0, zeros = ''; i < (length - value.length); i++) { zeros += '0'; } return zeros + value; }; return mask.replace(/"[^"]*"|'[^']*'|\b(?:d{1,4}|m{1,4}|yy(?:yy)?|([hHMstT])\1?|[lLZ])\b/g, function($0) { switch ($0) { case 'd': return d.getDate(); case 'dd': return zeroize(d.getDate()); case 'ddd': return ['Sun', 'Mon', 'Tue', 'Wed', 'Thr', 'Fri', 'Sat'][d.getDay()]; case 'dddd': return ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][d.getDay()]; case 'M': return d.getMonth() + 1; case 'MM': return zeroize(d.getMonth() + 1); case 'MMM': return ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'][d.getMonth()]; case 'MMMM': return ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'][d.getMonth()]; case 'yy': return String(d.getFullYear()).substr(2); case 'yyyy': return d.getFullYear(); case 'h': return d.getHours() % 12 || 12; case 'hh': return zeroize(d.getHours() % 12 || 12); case 'H': return d.getHours(); case 'HH': return zeroize(d.getHours()); case 'm': return d.getMinutes(); case 'mm': return zeroize(d.getMinutes()); case 's': return d.getSeconds(); case 'ss': return zeroize(d.getSeconds()); case 'l': return zeroize(d.getMilliseconds(), 3); case 'L': var m = d.getMilliseconds(); if (m > 99) m = Math.round(m / 10); return zeroize(m); case 'tt': return d.getHours() < 12 ? 'am': 'pm'; case 'TT': return d.getHours() < 12 ? 'AM': 'PM'; case 'Z': return d.toUTCString().match(/[A-Z]+$/); // Return quoted strings with the surrounding quotes removed default: return $0.substr(1, $0.length - 2); } }); }; Date.prototype.format = function(mask) { return Date.format(this, mask); }; Date.parseFormat = function(str, format) { var pattern = format.replace(/(yyyy)/g, "([0-9]{4})").replace(/(yy)|(MM)|(dd)|(hh)|(mm)|(ss)/g, "([0-9]{2})").replace(/[Mdhms]/g, "([0-9]{1,2})"); var getIndex = function(expr1, expr2) { var index = format.indexOf(expr1); if (index == -1) index = format.indexOf(expr2); return index; } var returnDate; if (new RegExp(pattern).test(str)) { var yPos = getIndex("yyyy", "yy"); var mPos = getIndex("MM", "M"); var dPos = getIndex("dd", "d"); var hPos = getIndex("hh", "h"); var miPos = getIndex("mm", "m"); var sPos = getIndex("ss", "s"); var data = { y: 0, m: 0, d: 0, h: 0, mi: 0, s: 0 }; var pos = [yPos + ",y", mPos + ",m", dPos + ",d", hPos + ",h", miPos + ",mi", sPos + ",s"].sort(function(a, b) { a = parseInt(a.split(',')[0]); b = parseInt(b.split(',')[0]); return a > b; }); var tmpIndex = 0; var newPos = []; for (var i = 0, l = pos.length; i < l; i++) { if (parseInt(pos[i].split(',')[0]) != -1) { newPos[tmpIndex] = pos[i]; tmpIndex++; } } var m = str.match(pattern); for (var i = 1, l = m.length; i < l; i++) { if (i == 0) break; var flag = newPos[i - 1].split(',')[1]; data[flag] = m[i]; }; data.y = data.y || today.getFullYear(); data.d = data.d || today.getDate(); if (data.y.toString().length == 2) data.y = parseInt('20' + data.y); data.m -= 1; returnDate = new Date(data.y, data.m, data.d, data.h, data.mi, data.s); } return returnDate; };

转载请注明:清风亦平凡 » javaScript日期格式化

]]>
https://www.mlplus.net/2016/07/01/javascriptdateformatter/feed/ 0