一、鼠标进入容器方向的判定
判断鼠标从哪个方向进入元素容器是一个经常碰到的问题,如何来判断呢?
首先想到的是:获取鼠标的位置,然后经过一大堆的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 "text-align: center">
以浏览器左上角做原点,画坐标轴,向下为负,向右为正,和数学坐标系一致。中间的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"color: #ff0000">二、window.open新窗口被拦截的问题当我们使用
window.open()
方法打开一个窗口时,部分浏览器会检测是否是用户主动行为,若不是,则会阻止窗口的打开,例如在异步Ajax的回调函数中调用。
新窗口被拦截检测
窗口被阻止打开,如不给出提示,用户体验将会很不好,那如何检测窗口被阻止?
如下代码所示:
var newWin = null, isBlock = !1; /** 新窗口被某些扩展阻止打开,会抛出错误,因此使用try..catch **/ try { newWin = window.open('http://www.baidu.com', '_blank'); /** 新窗口被阻止时,返回值是undefined或null**/ (!newWin) && (isBlock = !0); } catch (ex) { isBlock = !0; } if (isBlock) alert('您阻止了窗口的打开。');为何新窗口被拦截
浏览器设计者出于安全的考虑,
window.open
命令在用户操作(trusted events)时, 才会正常的打开应该页面而不会被浏览器拦截。什么是trusted events"http://www.baidu.com","_self") 。如何Ajax回调中避免被拦截
很多人的需求是点击按钮发送Ajax请求,请求数据回来后,再使用window.open来打开新的窗口,由于是异步操作,直接
window.open
,肯定会被拦截。这时我们可以变通以下,先打开一个空窗口,然后等数据回来后替换为需要的地址如下所示:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>弹窗拦截测试</title> <style type="text/css"> #btn{ width:100px; height: 30px; line-height: 30px; text-align:center; background-color:#0087dc; transition:all .2s; color:#fff; border-radius:3px;cursor:pointer; } #btn:hover{ background-color:#0060b2; } </style> </head> <body> <div id="btn">打开新窗口</div> <script type="text/javascript"> btn.addEventListener('click',(e)=>{ var xhr = new XMLHttpRequest(); var newWin = window.open('about:blank'); xhr.onreadystatechange = ()=>{ if(xhr.readyState == 4){ if(xhr.status == 200){ newWin.location.href="http://www.baidu.com"; } } }; xhr.open('post','/dnslookup',!1);//异步方式 xhr.setRequestHeader('content-type','application/x-www-form-urlencoded'); xhr.send('host=www.baidu.com&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回调中新窗口被拦截的问题。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。