归档: 2021

利用Nvidia的API设置数字振动数值源码_显示器亮度、对比度等设置源码

开始是一位朋友有这个需求,他给了我一个英伟达官网的开发包,名字是:R410-developer.zip(诸位可以自己到英伟达官网下载),里面提供了一些示例,包含自定义分辨率、显示器颜色设置等,但是显示器色彩设置的例子一致没有跑通,而且我也没有找到哪个参数是可以设置数字振动值的,所以憋屈了很多天。但直到看到了一个 AHK 版本实现的设置工具通过代码发现,其实实现方法是通过 nvapi.dll 动态库导出的一个查询函数地址的方法,将指定接口导出来执行具体业务。在加上在 github 上搜索的各类示例,最终实现了这个功能,下面详细介绍实现步骤。 需要的方法和结构设置数字振动数值需要先通过 nvapi.dll 导出的 NvAPI_QueryInterface_t 方法获取 NvAPI_Initialize_t 方法来初始化 NvAPI。然后依次获取显示器句柄、获取当前显示器数字振动值、设置数字振动值的函数地址,他们的声明分别对应如下:12345678910// 查询在 nvapi.dll 中函数的地址方法函数声明typedef int*(*NvAPI_QueryInterface_t)(unsigned int offset);// 初始化 NvAPI 的方法typedef int(*NvAPI_Initialize_t)();// 根据 ID 枚举显示器句柄的方法typedef int(*NvAPI_EnumNvidiaDisplayHandle_t)(int thisEnum, int* pNvDispHandle);// 获取数字振动当前值typedef int(*NvAPI_GetDVCInfoEx_t)(int hNvDisplay, int outputId, NV_DISPLAY_DVC_INFO_EX* pDVCInfo);// 设置数字振动值typedef int(*NvAPI_SetDVCLevelEx_t)(int hNvDisplay, int outputId, NV_DISPLAY_DVC_INFO_EX* pDVCInfo); 其中设置和获取数字振动值需要一个结构体 NV_DISPLAY_DVC_INFO_EX,其声明如下:12345678typedef struct{ unsigned int version; // 结构体版本 int currentLevel; // 当前级别 int minLevel; // 最低级别 int maxLevel; // 最高级别 int defaultLevel; // 默认级别} NV_DISPLAY_DVC_INFO_EX, *PNV_DISPLAY_DVC_INFO_EX; 获取各个接口地址我们首先 Load nvapi.dll 然后得到 nvapi_QueryInterface 方法的地址,然后通过 nvapi_QueryInterface 方法查询另外一些接口的地址。如下所示:123456789101112131415161718192021222324bool NvController::Initialize(){ hModule = LoadLibraryW(TEXT("nvapi.dll")); if (hModule == nullptr) { std::cerr << "Failed to load nvapi.dll." << std::endl; return false; } NvAPI_QueryInterface = (NvAPI_QueryInterface_t)GetProcAddress(hModule, "nvapi_QueryInterface"); NvAPI_Initialize = (NvAPI_Initialize_t)(*NvAPI_QueryInterface)(_NvAPI_Initialize); NvAPI_EnumNvidiaDisplayHandle = (NvAPI_EnumNvidiaDisplayHandle_t)(*NvAPI_QueryInterface)(_NvAPI_EnumNvidiaDisplayHandle); NvAPI_GetDVCInfoEx = (NvAPI_GetDVCInfoEx_t)(*NvAPI_QueryInterface)(_NvAPI_GetDVCInfoEx); NvAPI_SetDVCLevelEx = (NvAPI_SetDVCLevelEx_t)(*NvAPI_QueryInterface)(_NvAPI_SetDVCLevelEx); _NvAPI_Status status = (_NvAPI_Status)(*NvAPI_Initialize)(); if (status != NVAPI_OK) { std::cerr << "NvAPI initialization failed." << std::endl; return false; } return true;} 其中以下划线开头的枚举名字是每个函数在 dll 中的对应地址,这些是写死的,如下所示:12345678enum NvAPIs{ _NvAPI_Initialize = 0x150E828, _NvAPI_EnumNvidiaDisplayHandle = 0x9ABDD40D, _NvAPI_GetAssociatedNvidiaDisplayName = 0x22A78B05, _NvAPI_GetDVCInfoEx = 0x0E45002D, _NvAPI_SetDVCLevelEx = 0x4A82C2B1}; 你可能会问,你怎么知道这些函数地址的?其实我也是搜索到的,也看了以前 NvAPI 老版本提供的代码,可以搜索到相关痕迹。点击查看此文件里面有完整的所有函数地址。 获取和设置数字振动得到了各个函数的地址,我们就可以设置数字振动值了,代码如下:12345678910111213141516171819202122232425bool NvController::SetDVCLevelEx(int nDisp, int level){ int NvDispHandle; if (EnumNvidiaDisplayHandle(nDisp, &NvDispHandle) != 0) { NV_DISPLAY_DVC_INFO_EX oldInfo = GetDvcInfoEx(nDisp); NV_DISPLAY_DVC_INFO_EX info; info.version = oldInfo.version; info.currentLevel = level; info.minLevel = oldInfo.minLevel; info.maxLevel = oldInfo.maxLevel; info.defaultLevel = oldInfo.defaultLevel; _NvAPI_Status status = (_NvAPI_Status)(*NvAPI_SetDVCLevelEx)(NvDispHandle, 0, &info); if (status != NVAPI_OK) { return false; } return true; } return false;} 我们首先获得用户传入的显示器编号所对应的句柄,然后根据这个句柄获取当前数字振动的数值,然后修改其 currentLevel 成员数值来设置数字振动效果。这样处理后就可以使用了。完整代码参考地址:https://github.com/nmgwddj/nvapi-example 转载自https://cloud.tencent.com/developer/article/13715644. 屏幕亮度,对比度获取和调节 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960bool set_screen_brightness(long val){ HWND hDesktopWnd = GetDesktopWindow(); HMONITOR hMonitor = MonitorFromWindow(hDesktopWnd, MONITOR_DEFAULTTOPRIMARY); DWORD cPhysicalMonitors = 0; if (!GetNumberOfPhysicalMonitorsFromHMONITOR(hMonitor, &cPhysicalMonitors)) return false; LPPHYSICAL_MONITOR pPhysicalMonitors = (LPPHYSICAL_MONITOR)malloc(cPhysicalMonitors* sizeof(PHYSICAL_MONITOR)); if (pPhysicalMonitors) { GetPhysicalMonitorsFromHMONITOR(hMonitor, cPhysicalMonitors, pPhysicalMonitors); //设置屏幕亮度 SetMonitorBrightness(pPhysicalMonitors->hPhysicalMonitor, val); //设置屏幕对比度 //SetMonitorContrast(pPhysicalMonitors->hPhysicalMonitor, val); // Close the monitor handles. DestroyPhysicalMonitors(cPhysicalMonitors, pPhysicalMonitors); // Free the array. free(pPhysicalMonitors); } return true;}long get_screen_brightness(){ long lret = -1; HWND hDesktopWnd = GetDesktopWindow(); HMONITOR hMonitor = MonitorFromWindow(hDesktopWnd, MONITOR_DEFAULTTOPRIMARY); DWORD dwMin = 0, dwMax = 0, dwCur = 0; DWORD cPhysicalMonitors = 0; if (!GetNumberOfPhysicalMonitorsFromHMONITOR(hMonitor, &cPhysicalMonitors)) return false; LPPHYSICAL_MONITOR pPhysicalMonitors = (LPPHYSICAL_MONITOR)malloc(cPhysicalMonitors* sizeof(PHYSICAL_MONITOR)); if (pPhysicalMonitors) { GetPhysicalMonitorsFromHMONITOR(hMonitor, cPhysicalMonitors, pPhysicalMonitors); //获取屏幕对比度 //if (GetMonitorContrast(pPhysicalMonitors->hPhysicalMonitor, &dwMin, &dwCur, &dwMax)) //获取屏幕亮度 if (GetMonitorBrightness(pPhysicalMonitors->hPhysicalMonitor, &dwMin, &dwCur, &dwMax)) { lret = dwCur; } //SetMonitorContrast(pPhysicalMonitors->hPhysicalMonitor, val); // Close the monitor handles. DestroyPhysicalMonitors(cPhysicalMonitors, pPhysicalMonitors); // Free the array. free(pPhysicalMonitors); } return lret;} 屏幕色彩灰度调节(Gamma调节)12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758// #pragma pack(push, 4)// typedef struct _tagD3dGammaramp_t// {// WORD red[256];// WORD green[256];// WORD blue[256];// }D3DGAMMARAMP, *LPD3DGAMMARAMP;// #pragma pack(pop)class CScreenDC{public: CScreenDC(){ m_hdc = GetDC(NULL); } ~CScreenDC(){ if (m_hdc) ReleaseDC(NULL, m_hdc); m_hdc = NULL; } operator HDC(){ return m_hdc; }private: HDC m_hdc;};bool set_screen_gray(long val){ //HDC的对比度 val = min(100, val); val = max(0, val); val = val*128.0 / 100; /* bright >=0 && bright <= 128 */ CScreenDC hScreenDc; D3DGAMMARAMP Ramp = { 0 }; BOOL bret = GetDeviceGammaRamp(hScreenDc, &Ramp); if (!bret) return false; for (int iIndex = 0; iIndex < 256; iIndex++) { //bright 为什么需要+128,因为当 bring < 128 的时候效果同bright = 0 Ramp.red[iIndex] = min(65535, iIndex * (val + 128)); Ramp.green[iIndex] = min(65535, iIndex * (val + 128)); Ramp.blue[iIndex] = min(65535, iIndex * (val + 128)); } bret = SetDeviceGammaRamp(hScreenDc, &Ramp); return bret ? true:false;}long get_screen_gray(){ CScreenDC hScreenDc; D3DGAMMARAMP Ramp = { 0 }; BOOL bret = GetDeviceGammaRamp(hScreenDc, &Ramp); if (!bret) return -1; long bright = Ramp.red[1] - 128; bright = bright * 100.0 / 128; bright = min(100, bright); bright = max(0, bright); return bright;} 鼠标移动速度调节123456789101112131415161718bool set_mousemove_speed(long val){ //其接收范围在1(最慢)和20(最快)之间的值。值为10是 val = min(20, val); val = max(1, val); BOOL bret = SystemParametersInfo(SPI_SETMOUSESPEED, 0, (LPVOID)val, SPIF_UPDATEINIFILE || SPIF_SENDCHANGE || SPIF_SENDWININICHANGE); if (!bret) return false; return true;}long get_mousemove_speed(){ int nSpeed = 0; BOOL bret = SystemParametersInfo(SPI_GETMOUSESPEED, 0, &nSpeed, 0); if (!bret) return -1; return nSpeed;} 鼠标双击速度调节1234567891011121314151617181920//方法1:SystemParametersInfo(SPI_SETDOUBLECLICKTIME....bool set_mousedbclick_speed(long val){ //最快200ms 最慢 900ms 间隔70ms //SPI_SETDOUBLECLICKTIME val = 550 - (val - 10) * 35; val = min(900, val); val = max(200, val); BOOL bret = SetDoubleClickTime(val); if (!bret) return false; return true;}UINT get_mousedbclick_speed(){ UINT ival = GetDoubleClickTime(); ival = (ival - 550) / 35 + 10; return ival;} 转自 https://blog.csdn.net/CAir2/article/details/103897288 华夏网盟的成品下载 链接:https://share.weiyun.com/GJUzRJLE 密码:6jaisr

实现QQ8.0和QQ9.0登录界面动态背景效果

QQ8.0和QQ9.0登录界面的头部动态背景非常有个性,如何实现的呢? QQ8.0的登录界面效果,使用的JS和html5实现!就是QQ登录界面的这张图片最终的效果如下:123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229<!DOCTYPE html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>html5背景</title> <style type="text/css"> *{margin:0;padding:0;list-style-type:none;} a,img{border:0;} </style> <script type="text/javascript" src="http://code.jquery.com/jquery-1.8.3.min.js"></script></head><body><div id="container" style="width:100%;height:700px;"> <div id="anitOut"></div></div><script type="text/javascript">$(function () { if (!window.ActiveXObject && !!document.createElement("canvas").getContext) { $.getScript("cav.js", function () { var t = { width: 1.5, height: 1.5, depth: 10, segments: 12, slices: 6, xRange: 0.8, yRange: 0.1, zRange: 1, ambient: "#525252", diffuse: "#FFFFFF", speed: 0.0002 }; var G = { count: 2, xyScalar: 1, zOffset: 100, ambient: "#002c4a", diffuse: "#005584", speed: 0.001, gravity: 1200, dampening: 0.95, minLimit: 10, maxLimit: null, minDistance: 20, maxDistance: 400, autopilot: false, draw: false, bounds: CAV.Vector3.create(), step: CAV.Vector3.create(Math.randomInRange(0.2, 1), Math.randomInRange(0.2, 1), Math.randomInRange(0.2, 1)) }; var m = "canvas"; var E = "svg"; var x = { renderer: m }; var i, n = Date.now(); var L = CAV.Vector3.create(); var k = CAV.Vector3.create(); var z = document.getElementById("container"); var w = document.getElementById("anitOut"); var D, I, h, q, y; var g; var r; function C() { F(); p(); s(); B(); v(); K(z.offsetWidth, z.offsetHeight); o() } function F() { g = new CAV.CanvasRenderer(); H(x.renderer) } function H(N) { if (D) { w.removeChild(D.element) } switch (N) { case m: D = g; break } D.setSize(z.offsetWidth, z.offsetHeight); w.appendChild(D.element) } function p() { I = new CAV.Scene() } function s() { I.remove(h); D.clear(); q = new CAV.Plane(t.width * D.width, t.height * D.height, t.segments, t.slices); y = new CAV.Material(t.ambient, t.diffuse); h = new CAV.Mesh(q, y); I.add(h); var N, O; for (N = q.vertices.length - 1; N >= 0; N--) { O = q.vertices[N]; O.anchor = CAV.Vector3.clone(O.position); O.step = CAV.Vector3.create(Math.randomInRange(0.2, 1), Math.randomInRange(0.2, 1), Math.randomInRange(0.2, 1)); O.time = Math.randomInRange(0, Math.PIM2) } } function B() { var O, N; for (O = I.lights.length - 1; O >= 0; O--) { N = I.lights[O]; I.remove(N) } D.clear(); for (O = 0; O < G.count; O++) { N = new CAV.Light(G.ambient, G.diffuse); N.ambientHex = N.ambient.format(); N.diffuseHex = N.diffuse.format(); I.add(N); N.mass = Math.randomInRange(0.5, 1); N.velocity = CAV.Vector3.create(); N.acceleration = CAV.Vector3.create(); N.force = CAV.Vector3.create() } } function K(O, N) { D.setSize(O, N); CAV.Vector3.set(L, D.halfWidth, D.halfHeight); s() } function o() { i = Date.now() - n; u(); M(); requestAnimationFrame(o) } function u() { var Q, P, O, R, T, V, U, S = t.depth / 2; CAV.Vector3.copy(G.bounds, L); CAV.Vector3.multiplyScalar(G.bounds, G.xyScalar); CAV.Vector3.setZ(k, G.zOffset); for (R = I.lights.length - 1; R >= 0; R--) { T = I.lights[R]; CAV.Vector3.setZ(T.position, G.zOffset); var N = Math.clamp(CAV.Vector3.distanceSquared(T.position, k), G.minDistance, G.maxDistance); var W = G.gravity * T.mass / N; CAV.Vector3.subtractVectors(T.force, k, T.position); CAV.Vector3.normalise(T.force); CAV.Vector3.multiplyScalar(T.force, W); CAV.Vector3.set(T.acceleration); CAV.Vector3.add(T.acceleration, T.force); CAV.Vector3.add(T.velocity, T.acceleration); CAV.Vector3.multiplyScalar(T.velocity, G.dampening); CAV.Vector3.limit(T.velocity, G.minLimit, G.maxLimit); CAV.Vector3.add(T.position, T.velocity) } for (V = q.vertices.length - 1; V >= 0; V--) { U = q.vertices[V]; Q = Math.sin(U.time + U.step[0] * i * t.speed); P = Math.cos(U.time + U.step[1] * i * t.speed); O = Math.sin(U.time + U.step[2] * i * t.speed); CAV.Vector3.set(U.position, t.xRange * q.segmentWidth * Q, t.yRange * q.sliceHeight * P, t.zRange * S * O - S); CAV.Vector3.add(U.position, U.anchor) } q.dirty = true } function M() { D.render(I) } function J(O) { var Q, N, S = O; var P = function (T) { for (Q = 0, l = I.lights.length; Q < l; Q++) { N = I.lights[Q]; N.ambient.set(T); N.ambientHex = N.ambient.format() } }; var R = function (T) { for (Q = 0, l = I.lights.length; Q < l; Q++) { N = I.lights[Q]; N.diffuse.set(T); N.diffuseHex = N.diffuse.format() } }; return { set: function () { P(S[0]); R(S[1]) } } } function v() { window.addEventListener("resize", j) } function A(N) { CAV.Vector3.set(k, N.x, D.height - N.y); CAV.Vector3.subtract(k, L) } function j(N) { K(z.offsetWidth, z.offsetHeight); M() } C(); }) } else { alert('调用cav.js失败'); }});</script></body></html> 其中的cav.js下载地址:链接:https://share.weiyun.com/KDUzFY4R 密码:b5gvk3就这个cav.js,以前是腾讯官方的地址,即http://im-img.qq.com/pcqq/js/200/cav.js?_=1428576021379 但现在已经失效了,百度搜索,到处是积分下载!拿着腾讯的东西赚积分!!! QQ9.0的登录界面梦幻的动画,实际为视频!QQ9.5登录界面的动态素材如下您的浏览器不支持HTML5的 video 标签,无法为您播放!

成功,从《全力以赴》开始_励志演讲

梦想不会自动实现的,厌倦了平庸的话,就全力以赴吧!“在任何时候都能牺牲自己,成为自己,成为未来。”这是埃克里·托马斯的励志演讲短片,全程激情昂扬,为忙碌迷茫的人们,注射一剂强心剂如果无法播放,复制下面的链接在浏览器中打开即可https://ks-xpc18.xpccdn.com/4a3ce671-a5ed-4287-a40e-1d88f3cf574a.mp4 var oCss = document.createElement( "link" ); oCss.rel = "stylesheet"; oCss.href = "//cdn.bootcdn.net/ajax/libs/dplayer/1.9.1/DPlayer.min.css"; document.getElementsByTagName('head').item(0).appendChild(oCss); function dynamicLoad() { var _doc=document.getElementsByTagName('head')[0]; var script=document.createElement('script'); script.setAttribute('type','text/javascript'); script.setAttribute('src','//cdn.bootcdn.net/ajax/libs/dplayer/1.9.1/DPlayer.min.js'); _doc.appendChild(script); script.onload=script.onreadystatechange=function(){ if(!this.readyState||this.readyState=='loaded'||this.readyState=='complete'){ var dplayer=new DPlayer({ element: document.getElementById('dplayer'), preload: 'auto', autoplay: false, theme: '#FADFA3', video:{ quality: [{ name: '标准', url: 'https://ks-xpc18.xpccdn.com/4a3ce671-a5ed-4287-a40e-1d88f3cf574a.mp4' }], defaultQuality: 0, pic: '', type: 'auto' } }); } script.onload=script.onreadystatechange=null; } } dynamicLoad(); 视频地址

aardio中electron怎么实现窗体透明背景?

electron中的实现方法在electron中实现窗体背景透明,只需在BrowserWindow时指定参数123456789101112mainWindow = new BrowserWindow({ height: 960, width: 1820, transparent: true, resizable: false, frame: false, webPreferences: { devTools: false, nodeIntegration: true, enablemotemodule: true }}) 然后设置网页的body背景色body{background:#ffffff00}和mainWindow.setIgnoreMouseEvents(true)并且需要开启aero主题! aardio中实现aardio中作者在electron.app的288行中,指定了backgroundColor=’#ffffff’;如果只按照electron中设置窗体背景透明是无效的(这个问题一度让我觉得aardio中的electron无法实现窗体背景透明,后来看了electron.app才发现这个设置),需要同时设置backgroundColor,在electon设置如下参数,就可以在aardio调用electron,而实现窗体背景透明,这样aardio就可以愉快地使用electron!毕竟很多html5的页面只有electron才正常显示!1234567891011121314151617181920212223242526theApp.start( //electron打开的第一个页面,必须指定应用程序目录下的aardio代码文件 indexUrl ="/res/main.html"; browserWindow = { title="electron程序标题"; transparent=true;//设置背景透明 resizable=false;//禁止改变大小 frame=false;//设置无边框窗口 backgroundColor=0;//设置背景颜色透明 icon="/wbc.ico";//指定图标 webPreferences = { //devTools = false;//禁止调试窗口 nodeIntegration=true;//允许使用nodejs enablemotemodule=true; webviewTag=true } } /* 可选用args字段指定Chrome命令行参数, 必须在main.js中创建窗口以前就导入aardio模块才会生效 */ args ={ icon="./wbc.ico" }); 最新版aardio,作者已经改进了,不用设置backgroundColor,直接设置transparent为true就可以设置背景透明了! 同时作者倡导的import electron.runtime;如果运行程序时没有electron,自动下载,但写的程序,使用者根本不想等待下载,所以正常应该在创建electron时事先指定下好的electron,打包后让使用者只下载一次。如把electron下载好后,放在程序目录,创建electron就这样 1var theApp = electron.app(,".\electron\electron.exe"); 当然你可以把electron.exe改成其他名字,如electron.dll,上面也相应的改动就行! 另一个问题,electron必须使用aardio提供的,应该改动过,不然aardio和electron无法进行交互!下面是使用aardio中的electron实现的赛博朋克的网页做为主界面的效果

dcef4允许flash直接运行 cef3 84.4.1 Chromium 84.0.4147.105(直接启用不用点击)

问题出现chrome69版本开始禁用FLASH,cef3 84.4.1 Chromium 84.0.4147.105 如果正常开启FLASH,并且不用点击一点运行插件,就象之前版本一样呢?CEF4Delphi是在Delphi 10.2 Tokyo上开发和测试的,已经在Delphi 7,Delphi XE和Delphi 10中测试过了。有关CEF4Delphi的更多信息,请访问: https://www.briskbard.com/index.php?lang=en&pageid=cef论坛:https://www.briskbard.com/forum DELPHI代码实现 找到flash的dll文件 如在360浏览器中拷出flash文件PepperFlash NativeFlash放在程序目录 添加flash文件地址 123456789101112131415161718procedure CreateGlobalCEFApp;begin GlobalCEFApp := TCefApplication.Create; GlobalCEFApp.LogFile := 'debug.log'; GlobalCEFApp.LogSeverity := LOGSEVERITY_DISABLE;// LOGSEVERITY_INFO; 禁止日志文件 GlobalCEFApp.cache := 'User Data'; //设置缓存目录 GlobalCEFApp.UserDataPath := 'User Data'; GlobalCEFApp.LocalesRequired := 'zh-CN'; //设置语言 GlobalCEFApp.Locale := 'zh-CN'; GlobalCEFApp.UserAgent := 'Mozilla/5.0 (Linux; U; Android 4.0.4; en-gb; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30'; //设置全局agent为手机 GlobalCEFApp.FlashEnabled := true; //允许系统falsh GlobalCEFApp.AddCustomCommandLine('--ppapi-flash-path', 'PepperFlash\pepflashplayer.dll'); //指定flash GlobalCEFApp.AddCustomCommandLine('enable-npapi'); GlobalCEFApp.AddCustomCommandLine('load-plugin', 'NativeFlash\NPSWF32.dll'); GlobalCEFApp.AddCustomCommandLine('ssl-version-min','ssl3'); //指定ssl GlobalCEFApp.AddCustomCommandLine('--allow-running-insecure-content'); //允许https网站调用http的js GlobalCEFApp.EnablePrintPreview := True; //允许打印预览end; chromium启动时添加如下代码 123chromium1.AlwaysAuthorizePlugins := true;chromium1.AllowOutdatedPlugins := true;chromium1.RunAllFlashInAllowMode := true; 附加说明其中flash路径也可以使用dcef4的参数CustomFlashPath, 1GlobalCEFApp.CustomFlashPath := ExtractFilePath(Application.ExeName);

CefSharp.84.4.1_支持Mp4包括X86和64

CefSharp84.4.1支持MP4,包括32位和64位_dcef4 84.4.1 cefsharp 支持mp3,mp4,H.264播放视频 版本:84.4.10 包含x64与x86 cef.redist.x64.84.4.1 cef.redist.x86.84.4.1 链接: 链接: https://pan.baidu.com/s/15lndNobZJ3mER2KVHgMTiA 提取码: ygga 使用方法 首先nuget安装cefsharp 84.4.10 安装完成后使用下载得到的文件中的【cef.redist.x64.84.4.1】、【cef.redist.x86.84.4.1】两个文件夹 替换【packages】原本的文件即可 测试站点http://html5test.com/ 百度网盘那蜗牛速度,下这200多M需要一个小时,现提供一个微云下载地址 链接:https://share.weiyun.com/Ue1izExT 密码:ecf6zi 就这东西,到处要积分下载!!!! 对应cef 84.4.1的dcef3开源地址: https://github.com/salvadordf/CEF4Delphi/tree/84.0.4147.105

爬取最新QQ音乐下载地址分析

爬取最新QQ音乐下载地址分析以下均以歌名 不要说话 分析 通过音乐名字搜索 12345678910111213'qq' => [ 'method' => 'GET', 'url' => 'http://c.y.qq.com/soso/fcgi-bin/client_search_cp', 'referer' => 'http://m.y.qq.com', 'proxy' => false, 'body' => [ 'w' => $query, 'p' => $page, 'n' => 10, 'format' => 'json' ], 'user-agent' => 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1'] 即组成 http://c.y.qq.com/soso/fcgi-bin/client_search_cp?w=不要说话&p=1&n=10&format=json 通过定义的useragent通过Get取得的内容如下: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102{ "code":0, "data":{ "keyword":"不要说话", "priority":0, "qc":[ ], "semantic":{ "curnum":0, "curpage":1, "list":[ ], "totalnum":0 }, "song":{ "curnum":10, "curpage":1, "list":[ { "albumid":35182, "albummid":"000J1pJ50cDCVE", "albumname":"不想放手", "albumname_hilight":"不想放手", "alertid":23, "belongCD":0, "cdIdx":7, "chinesesinger":0, "docid":"14691017891116423173", "grp":[ ], "interval":285, "isonly":0, "lyric":"《时尚先生》电影主题曲", "lyric_hilight":"《时尚先生》电影主题曲", "media_mid":"004cc3OU0GLJHb", "msgid":16, "newStatus":2, "nt":1413023447, "pay":{ "payalbum":0, "payalbumprice":0, "paydownload":1, "payinfo":1, "payplay":0, "paytrackmouth":1, "paytrackprice":200 }, "preview":{ "trybegin":74064, "tryend":102207, "trysize":960887 }, "pubtime":1214755200, "pure":0, "singer":[ { "id":143, "mid":"003Nz2So3XXYek", "name":"陈奕迅", "name_hilight":"陈奕迅" } ], "size128":4566820, "size320":11416753, "sizeape":0, "sizeflac":30255204, "sizeogg":6051718, "songid":9059607, "songmid":"002B2EAA3brD5b", "songname":"不要说话", "songname_hilight":"&lt;em&gt;不要说话&lt;/em&gt;", "strMediaMid":"004cc3OU0GLJHb", "stream":1, "switch":16888579, "t":1, "tag":11, "type":0, "ver":0, "vid":"e0011thbfzs" } ], "totalnum":600 }, "tab":0, "taglist":[ ], "totaltime":0, "zhida":{ "chinesesinger":0, "type":0 } }, "message":"", "notice":"", "subcode":0, "time":1632975151, "tips":""} 通过返回的json可以取得歌曲的songmid为 002B2EAA3brD5b 通过歌曲的songmid取得音频信息 1234567891011'qq' => [ 'method' => 'GET', 'url' => 'http://c.y.qq.com/v8/fcg-bin/fcg_play_single_song.fcg', 'referer' => 'http://m.y.qq.com', 'proxy' => false, 'body' => [ 'songmid' => $songid, 'format' => 'json' ], 'user-agent' => 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1'] 即通过 http://c.y.qq.com/v8/fcg-bin/fcg_play_single_song.fcg?songmid=002B2EAA3brD5b&format=json 和自定义的头,返回的json如下: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124{ "code":0, "data":[ { "action":{ "alert":21, "icons":8535932, "msgdown":0, "msgfav":0, "msgid":14, "msgpay":6, "msgshare":0, "switch":16888579 }, "aid":0, "album":{ "id":35182, "mid":"000J1pJ50cDCVE", "name":"不想放手", "pmid":"000J1pJ50cDCVE_3", "subtitle":"《时尚先生》电影主题曲", "time_public":"2008-06-30", "title":"不想放手" }, "bpm":66, "data_type":0, "es":"", "file":{ "b_30s":0, "e_30s":60000, "hires_bitdepth":0, "hires_sample":0, "media_mid":"004cc3OU0GLJHb", "size_128mp3":4566820, "size_192aac":6893143, "size_192ogg":6051718, "size_24aac":0, "size_320mp3":11416753, "size_48aac":1733017, "size_96aac":3476533, "size_96ogg":3079411, "size_ape":0, "size_dts":0, "size_flac":30255204, "size_hires":0, "size_try":960887, "try_begin":74064, "try_end":102207, "url":"" }, "fnote":4009, "genre":1, "id":9059607, "index_album":7, "index_cd":0, "interval":285, "isonly":0, "ksong":{ "id":4841, "mid":"000A57lN1qgVTQ" }, "label":"0", "language":0, "mid":"002B2EAA3brD5b", "modify_stamp":0, "mv":{ "id":173498, "name":"", "title":"", "vid":"e0011thbfzs", "vt":0 }, "name":"不要说话", "ov":0, "pay":{ "pay_down":1, "pay_month":1, "pay_play":0, "pay_status":0, "price_album":0, "price_track":200, "time_free":0 }, "sa":0, "singer":[ { "id":143, "mid":"003Nz2So3XXYek", "name":"陈奕迅", "pmid":"", "title":"陈奕迅", "type":0, "uin":0 } ], "status":0, "subtitle":"《时尚先生》电影主题曲", "tid":0, "time_public":"2008-06-30", "title":"不要说话", "trace":"", "type":0, "url":"", "version":0, "volume":{ "gain":-8.178000000000001, "lra":9.406000000000001, "peak":1 } } ], "url":{ "9059607":"ws.stream.qqmusic.qq.com/C100002B2EAA3brD5b.m4a?fromtag=38" }, "url1":{ }, "extra_data":[ ], "joox":0, "joox_login":1, "msgid":0} 通过登录QQ取得guid和uin进而取得vkeyQQ音乐的地址如下: dl.stream.qqmusic.qq.com/C400000QCwge3B6Ad1.m4a?vkey= 6FBECDE68E94D9E5B1F6731C5A8D83AE2DE961466D2CF64694D86F94590B3E27592575D38322394478AFC921DA703B6805A4278DE54344F1&GUID= 1849502645&UIN=1000&fromtag=66其实就是:dl.stream.qqmusic.qq.com/C400$songmid.m4a?vkey=$vkey的值&guid=$guid值&uin=$uin&fromtag=66 guid需要QQ登录后才能取得,uin就是你登录的QQ号,经测试guid和qq号可以任意输出,而不需要登录,仅客户端的VIP歌曲无效根据guid和uin通过https://u.y.qq.com/cgi-bin/musicu.fcg取得vkey,取得过程可以看下面的python代码 python代码1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677import requestsimport jsonclass QQmusic: def __init__(self): self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36'} self.sl = [] self.musicList = [] # 获取页面 def getPage(self,url,headers): res = requests.get(url,headers = headers) res.encoding = 'utf-8' return res # 获取音乐songmid def getSongmid(self): num = int(input('请输入获取条数:')) # num = 20 #name = input('请输入歌名或歌手:') name = '张学友' url = 'http://c.y.qq.com/soso/fcgi-bin/client_search_cp?p=1&n=%d&w=%s'%(num,name) # 搜索音乐 res = self.getPage(url,headers=self.headers) print(res.text) html = res.text html = html[9:] html = html[:-1] # 获取songmid js = json.loads(html) songlist = js['data']['song']['list'] for song in songlist: print(song) songmid = song['songmid'] name = song['songname'] self.sl.append((name,songmid)) print('获取成功songmid') # 获取音乐资源,guid是登录后才能获取,nin也是 def getVkey(self): guid = 7347620869 #guid = input('请输入guid:') #经过测试不用登录也能获取vkey,但限制仅能客户端播放的除外 uin = 0 #input('请输入uin:') for s in self.sl: print('开始获取资源') # 获取vkey,purl name = s[0] songmid = s[1] keyUrl = 'http://u.y.qq.com/cgi-bin/musicu.fcg?&data={"req":{"param":{"guid":"%s"}},"req_0":{"module":"vkey.GetVkeyServer","method":"CgiGetVkey","param":{"guid":"%s","songmid":["%s"],"uin":"%s"}},"comm":{"uin":%s}}'%(guid,guid,songmid,uin,uin) res = self.getPage(keyUrl,headers=self.headers) print(res.text) html = res.text keyjs = json.loads(html) purl = keyjs['req_0']['data']['midurlinfo'][0]['purl'] if len(purl)==0 : #仅限客户端播放的音乐purl会为空 continue # 拼凑资源url url = 'http://dl.stream.qqmusic.qq.com/' + purl self.musicList.append((name,url)) print('资源地址获取成功') # 下载音乐 def downloadMusic(self): for m in self.musicList: url = m[1] res = self.getPage(url,headers=self.headers) music = res.content name = m[0] + '.mp3' with open(name, 'wb') as f: f.write(music) print('下载OK') f.closedQQ = QQmusic()QQ.getSongmid()QQ.getVkey()QQ.downloadMusic()

中国式婚姻真相_静音

无数个婚姻细节曝光,生活实苦,劝你多体谅! 我懂你的不易,你理解我的辛苦,这才是婚姻幸福的真相。 生活中,很多女人都梦想着嫁个有钱人,她们单纯的憧憬有钱男人会想宠着自己。于是,她们纷纷把赌注压在一个个有钱的。男人一种骨子里的骄傲和对别人的蔑视,他们以为对别人的一点好就是全部,因此常常抱着施舍的态度对待所有的人,即使妻子也不例外。可爱情不是施舍,是爱人灵魂之间的沟通和认同,一个女人如果从丈夫那里得到的是带有施舍的爱。那么,她在他面前就永远跪着,总有一天,她会累的撑不住。婚姻里,当你选择了金钱,那就意味着在未来的日子里,你可能锦衣玉食,不用吃钱方面的苦,却活得寂寞。 婚姻是夫妻一辈子的事业,要付出努力去经营,婚姻正是在夫妻携手跨越一次又一次的难坎之后才越发丰富有内涵,才越发显现白头到老的弥足珍贵,婚姻也才散发出她真正的魅力。

坚不可摧-励志激情演讲视频

坚不可摧-励志激情演讲视频 中文翻译: 你无法把点滴与未来联系,只能通过回顾才能看见。所以你必须相信过的点击能串联未来。你必须有信念,不管那是你的胆识、命运、人生还是因果报应,因为把过去点滴串联起来,才能有信念忠于自我。即使你的选择和别人不一样,这会使你与众不同。你的时间是有限的,不要浪费在其他人的生命当中,别受教条约束,别活在其他人对你的期望之中,别让批评抹去了你内心的声音。你得找到你所爱的东西,包括你热爱的事业和你的伴侣。你的工作将会占据你生命的大部分,相信你做的工作是对的,你才能发自内心得到满足。而只有爱你所有的事,才能成就不凡。如果你还没找到,那继续找,别安逸下来。有勇气顺从自己的内心和直觉,你的内心早就知道你未来的梦想。但是你不可能一帆风顺,大多数人轻易放弃,但你知道人的意志有多强大吗?意志是无可比拟的坚强又富有任性的!任何人在财务、感情生活、健康良好的环境中都能感到幸福,任何人都能自得其满,任何人都能有伟大的理想,任何人在任何的环境下都能有信念。真正试验你的信念、信仰和意志,是当你被击倒的时候。起身而行需要勇气,被击倒仍能谦虚,需要有勇气放下并重新开始。恐惧,扼杀梦想,恐惧,扼杀希望,恐惧,使人一蹶不振,恐惧使你苍老,阻止你去做能做到的事。但是,它也会使你麻木不仁。每个情绪起伏,仍然一无所成。但是每个原则,是自我的承诺。你的喜怒哀乐,最后也许什么都没有。但是每次下决心,都是一种承诺。你们有些人,至今尚未成功,那是因为你们过于情绪化。你被情绪所主导,像是早上心情不好,不想起床?谁想?每天你不面对自己的梦想,你也许会把目标延后整整六个月,或是一年!就是没有起身鞭策自己的那一瞬间。你不晓得自己退后了多少!别让你的情感控制你!我们是情感的动物,但是你必须管理你自己的情感!你要是不能管理情感,你将会被吞噬!你想要全力以赴,毫不保留。当你想改变的时候,不会很容易,如果很容易的话,每个人都做到啦!但是你认真,全力以赴!我是主导者,主宰着自我。我不会被外在事物打击我,摧毁我,我重新站起来,而我会变得更好、更加坚强。你必须下定决心,这是你的意义。如果这时你想要的梦,不论那是健康或是功成名就,对你的人生负完全的责任。接受现在的自己,并且相信自己能做的更好。你可以把每一天当做最后一天在过!活出你的激情来!拿出魄力来!每天不断鞭策自己做的更好!人生的最后一章尚未写下,昨日种种的事情并不重要,你发生了什么也没关系。重要的是,你要怎么做?今年我要使梦想成为现实!我甚至不想再讲了。我可以的!我可以的!我可以的!我觉得坚持对每个人都重要,不要放弃,不要妥协,每件事都有方法。 英文稿:You can’t connect the dots lookingforward; you can only connect them lookingbackwards. So you have to trust that the dots will somehow connect in your future. Youhave to trust in something: your gut, destiny, life, karma, whatever. Because believing thatthe dots will connect down the road, will give you the confidence to follow your heart, even when it lead you off the well worn path. And that will make all the difference. Your time is limited, so don’t waste it living someone else’s life. Don’t be trapped by dogma, which is living with the results of other people’s thinking. Don’tlet the noise of others’ opinions drown out your own inner voice. You’ve got to find what you love. And that is as true for your work as it is for your lovers. Your work is going to fill a large part of your life and the only way to be truly satisfied is todo what you believe is great work. And the only way to do great work is to love what you do. If you haven’t found it yet, keep looking, and don’tsettle. Have the courage to follow your heart and intuition, they somehow already know what you truly want to become. You’re going to have some ups and you’re goning to have some downs. Most people giveup on themselves easily. You know the human spirit is powerful?! There is nothing aspowerful. It’s hard to kill the human spirit! Anybody can feel good when they have theirhealth, their bills are paid, they have happy relationships. Anybody can be positive then,anybody can have a larger vision then, anybody can have faith under those kinds ofcircumstances. The real challenge of growth, mentally, emotionally and spiritually comeswhen you get knocked down. It takes courage to act. Part of being hungry when you been defeated. It takes courage to start over again. Fear kills dreams. Fear kills hope. Fear, put people in the hospital. Fear can age you, canhold you back from doing something that you know within yourself that you are capable of doing, but it will paralyze you. At the end of your feelings is nothing, but at the end of every principle is a promise. Behindyour little feelings, it might not be absolutely not at the end of your little feelings. Butbehind every principle is a promise. And some of you in your life, the reason why you notat your goal right now, because of your just all about you feelings. All on your feelings, you don’t feel like waking up, so who does? Everydayyou say “no” to your dreams, you mightbe pushing your dreams back a whole six months, a whole year! That one single day, that one day you didn’t get up could have pushed your stuff back, I don’t know how long. Don’t allow your emotions to controlyou. We are emotional, but what you want to begin to discipline your emotion. If you don’tdiscipline and contain your emotion, they will use you. You want it, and you are going to go all out to have it. It’s not going to be easy, when you want to change. It’s not easy. If it were in fact easy, everybody would do it. But ifyou’re serious, you’ll go all out. I’m in control here. I’m not going to let this get me down;I’m not going to let this destroy me. I’m coming back! And I’ll be stronger and better because ofit! You have got to make a declaration, that this is what you stand for! You’re standing up for your dreams;you’restanding up for peace of mind, you standing up for health. Take full responsibility for your life! Acceptwhere you are and the responsibility that you’re going to take yourself where you want to go. You can decide that I am going to live each day as if it were my last! Live your life withpassion! With some drive! Decided that your change to push yourself. The last chapter to your life has not been written yet, and it doesn’t matter about what happened yesterday. Itdoesn’t matter about what happened to you, what matter is: what are you going to do about it? This year I would make before this goal become a real. I won’t talk about itanymore. I can, I can, I can! To persevere I think is important for everybody, don’t give up, don’t give in. There’s always an answer to everything.

纯js美化alert弹出窗口

纯js实现自定义弹窗,美化alert窗口众所周知,浏览器自带的原生弹窗很不美观,而且功能比较单一,绝大部分时候我们都会按照设计图自定义弹窗或者直接使用注入layer的弹窗等等。前段时间在慕课网上看到了一个自定义弹窗的实现,自己顺便就学习尝试写了下,下面是主要的实现代码并添加了比较详细的注释,分享出来供大家参考。(代码用了ES6部分写法如需兼容低版本浏览器请把相关代码转成es5写法,后面有时间更新为一个兼容性较好的es5版本) HTML部分:(没什么内容 放置一个按钮调用函数,js中调用实例即可供参考) 1234567891011121314151617181920212223242526272829303132<!DOCTYPE html><html><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>自定义弹窗</title> <link rel="stylesheet" href="alert.css"></head><body> <button>Click me</button> <script src="index.js"></script> <script> document.querySelector("button").addEventListener("click",()=>{ new $Msg({ content:"我的自定义弹窗好了", type:"success", cancle:function(){ let cancle = new $Msg({ content:"我是取消后的回调" }) }, confirm:function(){ new $Msg({content:"我是确定后的回调"}) } }) }) </script></body></html> 样式部分:也放出来供参考,样式可以根据自己的设计图自行更改即可 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132/* 弹出框最外层 */.msg__wrap { position: fixed; top: 50%; left: 50%; z-index: 10; transition: all .3s; transform: translate(-50%, -50%) scale(0, 0); max-width: 50%; background: #fff; box-shadow: 0 0 10px #eee; font-size: 10px; } /* 弹出框头部 */ .msg__wrap .msg-header { padding: 10px 10px 0 10px; font-size: 1.8em; } .msg__wrap .msg-header .msg-header-close-button { float: right; cursor: pointer; } /* 弹出框中部 */ .msg__wrap .msg-body { padding: 10px 10px 10px 10px; display: flex; } /* 图标 */ .msg__wrap .msg-body .msg-body-icon{ width: 80px; } .msg__wrap .msg-body .msg-body-icon div{ width: 45px; height: 45px; margin: 0 auto; line-height: 45px; color: #fff; border-radius: 50% 50%; font-size: 2em; } .msg__wrap .msg-body .msg-body-icon .msg-body-icon-success{ background: #32a323; text-align: center; } .msg__wrap .msg-body .msg-body-icon .msg-body-icon-success::after{ content: "成"; } .msg__wrap .msg-body .msg-body-icon .msg-body-icon-wrong{ background: #ff8080; text-align: center; } .msg__wrap .msg-body .msg-body-icon .msg-body-icon-wrong::after{ content: "误"; } .msg__wrap .msg-body .msg-body-icon .msg-body-icon-info{ background: #80b7ff; text-align: center; } .msg__wrap .msg-body .msg-body-icon .msg-body-icon-info::after{ content: "注"; } /* 内容 */ .msg__wrap .msg-body .msg-body-content{ min-width: 200px; font-size: 1.5em; word-break: break-all; display: flex; align-items: center; padding-left: 10px; box-sizing: border-box; } /* 弹出框底部 */ .msg__wrap .msg-footer { padding: 0 10px 10px 10px; display: flex; flex-direction: row-reverse; } .msg__wrap .msg-footer .msg-footer-btn { width: 50px; height: 30px; border: 0 none; color: #fff; outline: none; font-size: 1em; border-radius: 2px; margin-left: 5px; cursor: pointer; } .msg__wrap .msg-footer .msg-footer-cancel-button{ background-color: #ff3b3b; } .msg__wrap .msg-footer .msg-footer-cancel-button:active{ background-color: #ff6f6f; } .msg__wrap .msg-footer .msg-footer-confirm-button{ background-color: #4896f0; } .msg__wrap .msg-footer .msg-footer-confirm-button:active{ background-color: #1d5fac; } /* 遮罩层 */ .msg__overlay { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 5; background-color: rgba(0, 0, 0, .4); transition: all .3s; opacity: 0; } JS部分:下面是最主要的部分,js方法及交互。自己封装自定义组件均可以此为参考,封装自己的组件。 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208/* *自定义弹窗 *///自执行函数 形成封闭的作用域 避免全局污染 //传入windwo和document对象 相当于将window和document作为了作用域中的局部变量,//就不需要内部函数沿着作用域链再查找到最顶层的window 提高运行效率。(function (window, document) { //定义一个构造函数Msg 作为弹窗实例的构造函数。 let Msg = function (options) { //执行初始化操作 this._init(options); } //定义初始化方法 并对方法传递的参数进行初始化 Msg.prototype = { _init({ content = "", //文本内容 type = "info", //信息类型 useHTML = false, //是否解析html字符串 showIcon = true, //是否展示弹窗图标 confirm = null, //确认后得回调 cancle = null, //取消后得回调 footer = true, //是否显示底部的确认按钮 header = true, //是否显示头部信息及关闭按钮 title = "提示", //弹窗标题 contentStyle = {}, //内容样式 contentFontSize = "1.5em", //内容字体大小 btnName = ["确定", "取消"] //按钮文字内容 }) { //将传入的值绑定到this上 this.content = content; this.type = type; this.useHTML = useHTML; this.showIcon = showIcon; this.confirm = confirm; this.cancle = cancle; this.footer = footer; this.header = header; this.title = title; this.contentStyle = contentStyle; this.contentFontSize = contentFontSize; this.btnName = btnName; //执行创建元素方法 this._creatElement(); //显示弹窗及遮罩 this._show({ el: this._el, overlay: this._overlay }); //绑定事件处理函数 this._bind({ el: this._el, overlay: this._overlay }); }, //创建弹窗元素方法 _creatElement() { //创建最外层得包裹元素 let wrap = document.createElement("div"); wrap.className = "msg__wrap"; //定义弹窗得两个按钮 const [confirmBtnName, cancelBtnName] = this.btnName; //判断是否显示弹窗标题 const headerHTML = this.header ? `<div class="msg-header"> <span>${this.title}</span> <span class="msg-header-close-button">×</span> </div>` : ""; //判断是否显示图标 const iconHTML = this.showIcon ? `<div class="msg-body-icon"> <div class="msg-body-icon-${this.type}"></div> </div>` : ""; //判断是否显示弹窗底部按钮 const footerHTML = this.footer ? `<div class="msg-footer"> <button class="msg-footer-btn msg-footer-cancel-button">${cancelBtnName}</button> <button class="msg-footer-btn msg-footer-confirm-button">${confirmBtnName}</button> </div>` : ""; //拼接完整html const innerHTML = `${headerHTML} <div class="msg-body"> ${iconHTML} <div class="msg-body-content"></div> </div> ${footerHTML}`; //将拼接的html赋值到wrap中 wrap.innerHTML = innerHTML; //把自定义的样式进行合并 const contentStyle = { fontSize: this.contentFontSize, ...this.contentStyle } //获取内容所属DOM let content = wrap.querySelector(".msg-body .msg-body-content"); //将传过来的样式添加到contentDOM for (const key in contentStyle) { if (contentStyle.hasOwnProperty(key)) { content.style[key] = contentStyle[key]; } } //给弹窗的conntent赋值 if (this.useHTML) { content.innerHTML = this.content; } else { content.innerText = this.content; } //创建遮罩层 let overlay = document.createElement("div"); overlay.className = "msg__overlay"; //把dom挂载到当前实例上 this._overlay = overlay; this._el = wrap; }, //弹窗展现方法 _show({ el, overlay }) { //把弹窗的dom和遮罩插入到页面中 document.body.appendChild(el); document.body.appendChild(overlay); //将弹窗显示出来 timeout进行异步处理显示动画 setTimeout(() => { el.style.transform = "translate(-50%,-50%) scale(1,1)"; overlay.style.opacity = "1"; }) }, //关闭弹窗方法 _close({ el, overlay }) { //隐藏dom el.style.transform = "translate(-50%,-50%) scale(0,0)"; overlay.style.opcity = "0"; //根据动画时间 动画完成再移除 setTimeout(() => { //把弹窗的dom和遮罩移除 document.body.removeChild(el) document.body.removeChild(overlay); }, 300); }, //事件处理函数,为DOM绑定事件 _bind({ el, overlay }) { //保存当前this //const _this = this; const cancle = (e) => { this.cancle && this.cancle.call(this, e); //隐藏弹窗 //hideMsg(); this._close({ el, overlay }); } //确认弹窗 const confirm = (e) => { this.confirm && this.confirm.call(this, e); this._close({ el, overlay }); } //顶部关闭按钮绑定事件 if (this.header) { el.querySelector(".msg-header-close-button").addEventListener("click", cancle); } //弹窗底部两个按钮事件监听 if (this.footer) { el.querySelector(".msg-footer-cancel-button").addEventListener("click", cancle); el.querySelector(".msg-footer-confirm-button").addEventListener("click", confirm) } } } //将构造函数暴露到window 可直接在全局作用域中访问构造函数 window.$Msg = Msg;})(window, document); 到此,一个完整的自定义弹窗组件已完成,只需要引入该js以及css或者直接把相关代码加到自己的公共js中即可直接调用,注意,构造函数调用要用new. 转自https://www.cnblogs.com/websharehome/p/9438741.html