复杂的JS onclick来自多个元素的事件

时间:2011-05-16 21:21:12

标签: javascript

好的(标题可能会误导)但是我能想出的最好。

我们想要实现的目标?

好的,我们有一张澳大利亚的svg地图。

单击该地图上的状态时,地图状态会将颜色更改为所选颜色。 (在我们的例子中粉红色) 在页面加载空白的同时(无用的按钮),将其值更改为状态的值。 同时一个下拉菜单,其中包含状态名称,在页面加载时具有值,请选择,将其值更改为状态值。

所以:这就是发生的事情。

用户访问页面并查看地图。他们还会看到下拉选择框。

他们可以选择单击选择下拉列表,也可以单击地图。

情景1。 他们点击地图,然后点击状态QUEENSLAND,其值为QLD。

点击状态后,状态从灰色变为粉红色。 选择下拉菜单会从请选择更改为昆士兰 灰色按钮从空白变为 QLD

这是一张图片: enter image description here

好的,我们的工作是。

地图点击事件有效,并传播灰色按钮值,这样就可以了。 select元素可以工作,只要我们在地图上选择一个状态就会改变选择框值。

我们没有工作的是。

  1. 点击地图,我们无法传播 BOTH 选择下拉列表和灰色按钮值。
  2. 我们无法使用选择下拉框,更改地图的“选择”状态,即不会从灰色变为粉红色。此外,它不会从当前值更改按钮的值。
  3. 所以这里有一些代码:

    它的SVG所以这里是地图的包装元素。

    <a xlink:href="javascript:void goToOption(document.australia.state,'WA')" target="_top">
        <path
            id="WA"
            class="territory"
            fill="#a9a9a9"
            onmouseup="clickTerritory(evt)"
            d="m 38.318056,168.24244 c -4.79245,0.99662 -8.64245,1.61598 l -7,1.12612 -8.18526,4.91727 -8.18526,4.91727 -5.31474,-0.0902 c -2.92311,-0.0496 -6.88974,-0.54005 -8.81474,-1.08988 z"/></a>
    

    以下是控制地图点击事件的JS:

    function prepare(){}
    function ready(){
        svgdoc = document.sv.getSVGDocument();
        svgRoot = svgdoc.documentElement;
    }
    function onTerritoryClick(territory){
        document.getElementById("territory-name").innerHTML=territory;
    }
    
    var selected_territory = "None";
    
      function init(evt) {
        if (window.svgDocument == null)
        {
            svgDocument = evt.target.ownerDocument;
        }
      }
    
      function clickTerritory(evt) {
        var clicked_territory;
    
        if (evt.target.parentNode.getAttributeNS(null, "id") != "australia-map")
        {
            // Hack to deal with groups
            clicked_territory = evt.target.parentNode;
        } else {
            clicked_territory = evt.target;
        }
    
        if (selected_territory != clicked_territory) {
            if (selected_territory != "None") {
                // Unselect previous territory
                selected_territory.setAttributeNS(null, "fill", "#a9a9a9");
            }
            selected_territory = clicked_territory;
            selected_territory.setAttributeNS(null, "fill", "#ec008c");
            top.onTerritoryClick(selected_territory.getAttributeNS(null, "id"));
        } 
      }
    

    这是处理选择框的JS,它会激活href。

    function goToOption(sel, val) {
      var opt, o = 0;
      while (opt = sel[o++]) if (opt.value == val) sel.selectedIndex = o - 1;
    }
    

    这是按钮html:

    <div class="selected-state left">
        <button id="territory-name" class="mystate grayNohover button" style="position:absolute;top:250px;left:50px">ALL</button> 
    </div>
    

    这是选择菜单html:

    <select name="state" id="speedF" style="width:180px;">
    <option value="">Please Select</option>
    <option value="QLD">Queensland</option>
    <option value="NT">Northern Territory</option>
    <option value="WA">Western Australia</option>                           
    <option value="SA">South Australia</option>
    <option value="NSW">New South Wales</option>
    <option value="VIC">Victoria</option>
    <option value="ACT">A.C.T.</option>
    <option value="TAS">Tasmania</option>
    </select>
    

    示例:http://sitehelp.com.au/demos/svgmap2/

    版本2:http://dev.30.com.au/422-svg/

3 个答案:

答案 0 :(得分:1)

对于问题2:在下拉列表中添加onchange事件。

<select onchange="handlechange()">

handlechange函数可以获取值并使用它来调用clickterritory()

我没有看到问题1,因为它似乎在你的演示中为我工作。

答案 1 :(得分:1)

我不是处理事件的专家,但这听起来需要有关事件冒泡和捕获的专业知识。

所以这是一个可能引导您朝着正确方向前进的页面:http://www.quirksmode.org/js/events_order.html

我也碰巧知道Nicholas Zakas的书中有一整章(12) Professional Javascript for Web Developers致力于解释事件。

答案 2 :(得分:1)

好吧,通过添加此函数并在选择框值更改时调用此函数,我可以通过hackily工作,

<select onchange="selectChanged(this)">

这是函数,

function selectChanged(el) {
    var selectedState = el.value;

    var event = document.createEvent('MouseEvents');
    event.initMouseEvent("mouseup", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);

    var groups = document.getElementsByTagName('g');
    for (var i = 0; i < groups.length; i++) {
        if (groups[i].id == selectedState) {
            var path = groups[i].getElementsByTagName('path')[0];
            path.dispatchEvent(event);
            return;
        }
    }
}

它以编程方式创建一个mouseup事件,并针对代表该状态的<path>元素触发它。

但是,这是保持同步的非常糟糕的方法。您可能想要查看自定义事件。使用自定义事件,将DOM项目视为响应事件的自包含组件。这里唯一感兴趣的事件是改变国家。因此,高级别的互动将是,

  • 当选择框更改时,使用所选状态的值
  • 触发stateChanged事件
  • 当用户点击地图时,使用所选状态的值
  • 触发stateChanged事件

现在地图,灰色按钮和选择框都会收听stateChanged事件。每当状态改变时,它们就会以所选状态更新自己。您还可以为自己提供编程访问权限,以便轻松更改状态。

function changeState(newState) {
    // update map
    // update button
    // update select list
}

// add an app level event handler to listen for change of a state
app.handleEvent('stateChanged', changeState);

然后勾选地图点击,然后选择更改操作回到此changeState功能。

map.onclick = function(event) {
    var stateId = // get state-code of clicked portion
    app.triggerEvent('stateChanged', stateId);
}

selectList.onchange = function(event) {
    var stateId = this.value;
    app.triggerEvent('stateChanged', stateId);
}