Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 代理通过画布单击到图像映射 JSFiddle:_Javascript_Jquery_Html_Html5 Canvas_Dom Events - Fatal编程技术网

Javascript 代理通过画布单击到图像映射 JSFiddle:

Javascript 代理通过画布单击到图像映射 JSFiddle:,javascript,jquery,html,html5-canvas,dom-events,Javascript,Jquery,Html,Html5 Canvas,Dom Events,我有一个覆盖在网页上的雪白效果的画布,我想通过画布将单击委派给下面要单击的元素 此脚本适用于其他对象,但在某些浏览器中的图像映射(带有区域标记)上失败 作品:IE10,铬 失败:FF,Safari // delegate click through canvas to page canvas.addEventListener('click', function(event) { event = event || window.event; canv

我有一个覆盖在网页上的雪白效果的画布,我想通过画布将单击委派给下面要单击的元素

此脚本适用于其他对象,但在某些浏览器中的图像映射(带有区域标记)上失败

作品:IE10,铬
失败:FF,Safari

    // delegate click through canvas to page
    canvas.addEventListener('click', function(event) {
        event = event || window.event;
        canvas.style.zIndex = "0";
        target = document.elementFromPoint(event.clientX, event.clientY);
        if (target.click) {
            target.click();
        } else {
            target.onclick();
        }
        canvas.style.zIndex = "1000000";
    }, false);
请参阅JSFIDLE以了解问题的演示。单击画布未重叠的贴图时,区域元素的onclick函数将启动。但是,当您单击画布覆盖的地图部分时,它不会在指定的浏览器中启动onclick函数。用IE10/Chrome试试JSFIDLE:没有问题,用FireFox/Safari试试看问题


出了什么问题?

您只触发实际的click或onclick处理程序,而不是由侦听器添加的任何处理程序。为此,您需要使用
dispatchEvent
触发事件


此外,处理光标位置的事件属性在不同浏览器之间并不总是正确匹配,因此您可能希望使用诸如jQuery之类的库来规范它们的值。

好的,因此我以一种非常糟糕的手动方式使其工作

首先,我意识到目标元素正在查找
而不是
映射>
元素。因此,我必须手动执行此操作。我查看
属性,按id定位
,然后我必须使用
event.clientX
event.clientY
从单击的位置计算要单击的地图的哪个子级

在我的例子中,它甚至更可怕,因为我使用了
元素,所以为了绕过它,如果其他元素不正确,我只是默认为多边形区域

    // delegate click through canvas to page
    var bindEvent = function(element, type, handler)
    {
           if(element.addEventListener) {
              element.addEventListener(type, handler, false);
           } else {
              element.attachEvent('on'+type, handler);
           }
    };
    bindEvent(canvas, 'click', function(event) {
        event = event || window.event;
        canvas.style.zIndex = "0";
        target = document.elementFromPoint(event.clientX, event.clientY);
        if (target.useMap) {
            var evt = document.createEvent("MouseEvents");
            evt.initMouseEvent("click", true, true, window, 1, 0, 0, 0, 0,
                false, false, false, false, 0, null);
            var mapid = target.useMap.replace("#","");
            var map = document.getElementById(mapid);
            var x = event.clientX - target.offsetParent.offsetLeft;
            var y = event.clientY - target.offsetParent.offsetTop;
            console.log("("+x+","+y+")");
            var areas = map.getElementsByTagName("area");
            var clickarea = areas[0];
            for (var i=0; i<areas.length; i++) {
                var area = areas[i];
                var coords = area.coords.split(",");
                if (area.shape == "rect"
                    && x > parseInt(coords[0])
                    && x < parseInt(coords[2])
                    && y > parseInt(coords[1])
                    && y < parseInt(coords[3])) {
                    console.log(x+">"+coords[0]
                        +" && "+x+"<"+coords[2]);
                    console.log(y+">"+coords[1]
                        +" && "+y+"<"+coords[3]);
                    clickarea = area;
                    break;
                }
            }
            clickarea.dispatchEvent(evt);
        } else if (target.click) {
            target.click();
        } else {
            target.onclick();
        }
        canvas.style.zIndex = "1000000";
    }, false);
//委托人在画布中单击以进入页面
var bindEvent=函数(元素、类型、处理程序)
{
if(element.addEventListener){
元素。addEventListener(类型、处理程序、false);
}否则{
元素.attachEvent('on'+类型,处理程序);
}
};
bindEvent(画布,'单击',函数(事件){
event=event | | window.event;
canvas.style.zIndex=“0”;
target=document.elementFromPoint(event.clientX,event.clientY);
if(target.useMap){
var evt=document.createEvent(“MouseEvents”);
evt.initMouseEvent(“单击”,真,真,窗口,1,0,0,0,
false,false,false,false,0,null);
var mapid=target.useMap.replace(“#”);
var map=document.getElementById(mapid);
var x=event.clientX-target.offsetParent.offsetLeft;
var y=event.clientY-target.offsetParent.offsetop;
控制台日志(“+x+”,“+y+”);
var areas=map.getElementsByTagName(“区域”);
var clickarea=区域[0];
for(var i=0;i parseInt(coords[0])
&&xparseInt(坐标[1])
&&y”+coords[0]
+“&&+x+”+coords[1]

+&&“+y+”您可以使用CSS指针事件停止侦听鼠标事件:无

// CSS

#canvasObj {
    pointer-events: none;
}

我不认为(1)你可以发布一个JSFIDLE,或者(2)可能对你有用?@gibberish我已经在使用一个地图插件来调整地图的大小。如果没有必要,我不想只为这个点击事件添加另一个。@gibberish Fiddle:听起来不错,但不确定我是否做对了?
var clickEvent=new MouseEvent('click'),{'view':窗口,'bubbles':true,'cancelable':true});
然后使用
target.dispatchEvent(clickEvent)
但问题没有区别。哦,有区别,MouseeEvent声明导致IE中出现错误:Object不支持此操作。@Ozy您正在传输事件,因此您不需要创建新的事件对象,您已经有了从画布上单击得到的事件对象,只需将其传输到tar中即可获取使用dispatchEvent您可以发布一个示例吗?因为我尝试的每件事都会给我带来另一个错误。使用传递的“event”对象会导致InvalidStateError:尝试使用不可用或不再可用的对象。此外,dispatchEvent在IE中不起作用。@Ozzy您需要在传递事件对象之前复制它关于IE,我不明白你怎么能有画布而不是dispatchEvent,除非你正在填充画布??说真的,这就是我要做的一切(