宝哥软件园

JS判断鼠标进入容器的方向和window.open新窗口被拦截的问题

编辑:宝哥软件园 来源:互联网 时间:2021-09-06

首先,确定鼠标进入容器的方向

判断鼠标从哪个方向进入元素容器是一个常见的问题。如何判断?

首先想到的是得到鼠标的位置,然后通过大量的if来确定它.否则逻辑。这种做法很麻烦。这里有两个方便的方法:

第一种方法使用圆和反正切三角函数

如下图所示:

画一个以div容器的中心为中心,高度和宽度的最小值为直径的圆,用[/4,3/4],[3/4,5/4],[5/4,7/4],[-/4,/4]将圆分成四个象限。

代码如下:

$ ('.方框')。on('鼠标输入mouseleave ',函数(e) {/* *获取容器宽度和高度**/var w=$(this)。宽度();var h=$(这个)。高度();/* *计算X和Y相对于中心点的距离。如果不是正方形,按照X和Y * */var x=(e.pagex-$ (this)中较小的一个进行缩放。偏移量()。左-(w/2)) * (w h?(h/w): 1);var y=(e.pageY - $(this)。偏移量()。top - (h/2)) * (h w?(w/h): 1);/* *根据x和y的值,做反正切atan2计算,返回值在[-,]之间,这里加180,去掉负值* *//* *如果不加180,0,1,2,3对应左下右* */* *除以90四舍五入,这样45度可以作为分界线。l * */var direction=math . round(((math . atan 2(y,x)*(180/math . pi))180)/90)3)% 4;**/打开开关(方向){ case 0:/* *;案例1: /**右* */break;在案例2:/* * */break下;案例3: /**左**/断;}});数学。圆((((数学。atan2 (y,x)*(180/数学。pi)) 180)/90) 3)% 4这个方法中的公式很难理解。首先得到鼠标坐标的转换值,然后计算坐标的弧度,再转换成度数,加上180去掉负数,然后,

第二种方法,利用斜率

如下图所示:

以浏览器左上角为原点,画出坐标轴,为负向下,正向右,与数学坐标系一致。中间div的左上角坐标(x1,y1)、右下角坐标(x2,y2)和中心点坐标(cx,cy)。如图,两点的斜率为k(k0),绕x轴对称的斜率为-k。

需要注意的是,所有的Y轴坐标都是负的,因为容器放置在坐标系的第四象限。

$('.方框')。on('mouseenter mouseleave ',函数(e) { var w=$(this)。宽度();h=$(这个)。高度(),x1=$(这个)。偏移量()。左,y1=-$(这个)。偏移量()。top,x2=x1 w,y2=y1 - h,cx=(x1 x2)/2,cy=(y1 y2)/2,k=(y2 - y1)/(x2 - x1),k1=(-e.pageY - cy)/(e.pageX - cx),方向=-1;if((k1-k)(k k1)){ direction=e . Pagex CX?1:3;} else { direction=-e.pageY cy?0:2;//理解代码的时候一定要记住Y坐标都是负的} //0123对应TRBL });如上面的代码所示,当鼠标的位置和容器的中心点形成的斜率在(K,-K)之间时,它必须左右进出。如果鼠标的X坐标大于中心点CX,则在右边输入,否则在左边输入;如果斜率不在(k,-k)之间,则上下进出。只需判断鼠标Y坐标与中心点CY的大小关系即可。如果大于,则为下侧,反之则为上侧。

二、window.open新窗口被拦截的问题

当我们使用window.open()方法打开一个窗口时,有些浏览器会检测是否是用户的活动行为,如果不是,就会阻止窗口打开,比如在异步Ajax的回调函数中调用。

拦截并检测新窗口

窗户被挡住打不开。如果不给提示,用户体验会很差。如何检测窗户被遮挡?

如以下代码所示:

var newWin=null,isBlock=!1;/** 新窗口被某些扩展阻止打开,会抛出错误,因此使用尝试.接住* */尝试{ newWin=window。open(' http://www .百度。com ',' _ blank ');/** 新窗口被阻止时,返回值是不明确的或null**/(!newWin) (isBlock=!0);} catch (ex) { isBlock=!0;}if (isBlock)警报('您阻止了窗口的打开。');为何新窗口被拦截

浏览器设计者出于安全的考虑,窗口。打开命令在用户操作(可信事件)时,才会正常的打开应该页面而不会被浏览器拦截。什么是可信事件?

事件接口的受信任只读属性是一个布尔值,当事件由用户操作生成时为真,当事件由脚本创建或修改或通过调度事件调度时为假。

当前事件是由用户行为触发(例如鼠标点击按钮触发操作),便是可信事件,而用自定义事件dispatchEvent触发的事件则不是可信事件。

因此使用射流研究…代码自动触发window.open(),第二个参数不为_self,打开新窗口在大部分浏览器中会被拦截。如果第二个参数为_self,则不会被拦截,如窗户。open(' http://www .百度。com ',' _self ')。

如何埃阿斯回调中避免被拦截

很多人的需求是点击按钮发送埃阿斯请求,请求数据回来后,再使用窗户。打开来打开新的窗口,由于是异步操作,直接窗户。打开,肯定会被拦截。这时我们可以变通以下,先打开一个空窗口,然后等数据回来后替换为需要的地址

如下所示:

!DOCTYPE html html lang=' en ' head meta charset=' UTF-8 '标题弹窗拦截测试/title style type=' text/CSS ' # BTN { width :100 px;高度: 30px线高: 30px文本对齐:居中;背景色: # 0087 DC;transit : all . 2s color : # fff边界半径:3 px光标:指针指针;} # BTN :悬停{底色: # 0060 B2;} /style/headbody div id='btn '打开新窗口/div脚本类型=' text/JavaScript ' BTN。addeventlistener(' click ',(e)={ var xhr=new XMLHttpRequest();var NewWin=window。打开('约:空白');xhr。onreadystatechange=()={ if(xhr。readystate==4){ if(xhr。status==200){ newwin。位置。http://。百度。com ';} } };xhr.open('post ','/dnslookup ',1);//异步方式xhr。setrequestheader('内容类型',' application/x-www-form-URL编码');xhr。send(' host=www。百度。comrrtype=A ');},0);/脚本/正文/html服务端代码如下:

var http=require('http ')、url=require('url ')、dns=require('dns ')、qs=require('querystring ')、fs=require(' fs ');功能路由器(req,res,pathname){ switch(pathname){ case '/dnslookup ' : lookup(req,RES);打破;default: showIndex(req,RES);} }函数showIndex(req,RES){ var page path=_ _ dir name/'块。html ';var html=fs。readfilesync(页面路径);RES . end(html);}函数查找(req,RES){ var PostDATa=' ';req.on('data ',function(data){ PostDATa=data;});req.on('end ',function(data){ var JSON=QS。解析(PostDATa);var hostname=JSON . hostvar rrtype=JSON . rrtypedns . resolve(主机名、rrtype、函数如果,结束。stringify({ errcode :1,IPS :[]});} RES . end(JSON。stringify({ errcode :0,IPS :地址});});});}http.createServer(函数{ var pathname=URL。解析(请求。网址).路径名;请求。setencoding(' utf8 ');res.writeHead(200,{ ' Content-Type ' : ' text/html ' });路由器(请求、资源、路径名);}).听(3000);如上所示便可解决在埃阿斯回调中新窗口被拦截的问题。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

更多资讯
游戏推荐
更多+