时间:2021-05-26
一、鼠标进入容器方向的判定
判断鼠标从哪个方向进入元素容器是一个经常碰到的问题,如何来判断呢?
首先想到的是:获取鼠标的位置,然后经过一大堆的if..else逻辑来确定。这样的做法比较繁琐,下面介绍两种比较方便的方法:
第一种方法,利用圆和反正切三角函数
如下图所示:
以div容器的中心点作为圆心,以高和宽的最小值作为直径画圆,将圆以[π/4,3π/4),[3π/4,5π/4),[5π/4,7π/4),[-π/4,π/4)划分为四个象限。
代码如下:
$(".box").on("mouseenter mouseleave",function(e){/** 获取容器宽高 **/var w = $(this).width();var h = $(this).height();/** 计算X和Y相对于圆心点的距离,如果不是正方形,按照X,Y谁小按谁进行比例缩放**/var x = (e.pageX - $(this).offset().left - (w/2)) * ( w > h ? (h/w) : 1 );var y = (e.pageY - $(this).offset().top - (h/2)) * ( h > w ? (w/h) : 1 );/** 根据X,Y的值,做反正切atan2计算,返回值在[-π,π]之间 ,这里加上180,剔除负值**//** 如果不加180,则0,1,2,3对应下左上右**//** 除以90并四舍五入,使得可以以45度为分割线,获取象限**//** 加3与4取模,将0,1,2,3对应t,r,b,l既上右下左**/var direction = Math.round((((Math.atan2(y, x) * (180 / Math.PI)) + 180 ) / 90 )+3)%4;switch(direction) { case 0: /** 上 **/ break; case 1: /** 右 **/ break; case 2: /** 下 **/ break; case 3: /** 左 **/ break;}});这个方法中的Math.round((((Math.atan2(y, x) * (180 / Math.PI)) + 180 )/90)+3)% 4公式比较难理解,首先得到鼠标坐标经过换算后的值,然后算出该坐标的弧度,接着换算成度数,加180去掉负数,随后转移象限将0123对应TRBL,如果不加180去掉负数,0123对应BLTR,有点不合CSS的习惯。
第二种方法,利用斜率
如下图所示:
以浏览器左上角做原点,画坐标轴,向下为负,向右为正,和数学坐标系一致。中间的div的左上角坐标(x1,y1),右下角坐标(x2,y2),中心点的坐标(cx,cy)。如图两点的斜率为k(k<0),关于x轴对称的斜率为-k。
需要注意一点的是所有的Y轴坐标都是负数,因为就是将容器置于坐标系的第四象限。
$(".box").on("mouseenter mouseleave", function(e) { var w = $(this).width(); h = $(this).height(), x1 = $(this).offset().left, y1 = -$(this).offset().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), direction = -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;/** 新窗口被某些扩展阻止打开,会抛出错误,因此使用try..catch **/try { newWin = window.open('http://&rrtype=A'); },!0); </script></body></html>服务端代码如下:
var http = require('http'), url = require('url'), dns = require('dns'), qs = require('querystring'), fs = require('fs');function router(req,res,pathname){ switch(pathname){ case '/dnslookup': lookup(req,res); break; default: showIndex(req,res); }}function showIndex(req,res){ var pagePath = __dirname+'/'+'block.html'; var html = fs.readFileSync(pagePath); res.end(html);}function lookup(req,res){ var postData = ''; req.on('data',function(data){ postData+=data; }); req.on('end',function(data){ var json = qs.parse(postData); var hostname = json.host; var rrtype = json.rrtype; dns.resolve(hostname,rrtype,function(err,adresses){ if(err){ res.end(JSON.stringify({errcode:1,ips:[]})); } res.end(JSON.stringify({errcode:0,ips:adresses})); }); });}http.createServer(function(req,res){ var pathname = url.parse(req.url).pathname; req.setEncoding("utf8"); res.writeHead(200,{'Content-Type':'text/html'}); router(req,res,pathname);}).listen(3000);如上所示便可解决在Ajax回调中新窗口被拦截的问题。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
自己遇到的使用window.open打开新窗口被拦截的几种情况(使用的chrome浏览器,其他浏览器未测):第一次:window.open(),打开了新窗口,但
window.open弹出窗口的位置问题.记录一下复制代码代码如下:参数解释:js脚本开始;window.open弹出新窗口的命令;'page.html'弹出窗
本文实例讲述了JS打开新窗口防止被浏览器阻止的方法。分享给大家供大家参考。具体分析如下:用传统的window.open()方式打开新窗口,会被浏览器阻止,那么,
一、代码示例复制代码代码如下:window.open(url,'新窗口','width='+(window.screen.availWidth-10)+',he
通常使用window.open的方式开启新窗口的话要取得父窗口的控件,可以用window.opener来取得父窗口然而如果使用showModalDialog的话