【问题标题】:Google Event Listener: Uncaught TypeError: Cannot read property 'addEventListener' of nullGoogle 事件侦听器:未捕获的 TypeError:无法读取 null 的属性“addEventListener”
【发布时间】:2016-04-16 07:26:52
【问题描述】:

我之前问过这个问题,关于 addListenerOnce 中的 addListener 不起作用,答案是我尝试在我正在寻找的元素呈现之前添加点击侦听器。问题是我不明白为什么它对前两个事件有效。该事件来自图例的点击事件。前两个事件将一起出现。这就像听众只工作了1次。我尝试使用 addListenerOnce 并且事件也空闲(如第一个图例)来调用第二个图例级别的事件,但它根本不起作用。

例如,我单击 Faculty 图例,然后单击 fpa 和 fskm,效果非常好,但是当我单击 Sex 或 Level of Education 然后单击它们各自的第二个图例时,出现 Uncaught TypeError 错误:无法读取属性 'addEventListener'空出来。我什至尝试了 DOMContentLoaded,但仍然无法正常工作。我到底该怎么做?下面是代码,alert只是为了测试。

var legend = document.createElement('div');
    legend.id = 'legend';
    var content = [];
    content.push('<h3><b>View option</b></h3>');
    content.push('<div id="general"><svg height="20" width="200"><g><rect width="15" height="12"class="general" ></g><g><text x="26" y="10">General</text></g></svg></div>');
    content.push('<div id="faculty"><svg height="20" width="200"><g><rect width="15" height="12"class="nothing"></g><g><text x="26" y="10">Faculty</text></g></svg></div>');
    content.push('<div id="sex"><svg height="20" width="200"><g><rect width="15" height="12"class="nothing"></g><g><text x="26" y="10">Sex</text></g></svg></div>');
    content.push('<div id="level"><svg height="20" width="200"><g><rect width="15" height="12"class="nothing"></g><g><text x="26" y="10">Level of education</text></g></svg></div>');
    legend.innerHTML = content.join('');
    legend.index = 1;
    map.controls[google.maps.ControlPosition.RIGHT_TOP].push(legend);
    var legendSpec = document.createElement('div');
    legendSpec.id = 'legend';
    var contentNew = [];

    google.maps.event.addListenerOnce(map, 'idle', function() {

        var genOpt = document.getElementById("general");
        google.maps.event.addDomListener(genOpt, 'click', function() {
            alert("ok"); 
        });

        var sexOpt = document.getElementById("sex");
        google.maps.event.addDomListener(sexOpt, 'click', function() {
            contentNew = [];
            contentNew.push('<h3><b>Sex</b></h3>');
            contentNew.push('<div id="maleD"><svg height="20" width="200"><g><rect width="15" height="12"class="male" ></g><g><text x="26" y="10">Male</text></g></svg></div>');
            contentNew.push('<div id="femaleD"><svg height="20" width="200"><g><rect width="15" height="12"class="female"></g><g><text x="26" y="10">Female</text></g></svg></div>');
            legendSpec.innerHTML = contentNew.join('');
            legendSpec.index = 1;
            alert("ok"); 
        });

        var facultyOpt = document.getElementById("faculty");
        google.maps.event.addDomListener(facultyOpt, 'click', function() {
            contentNew = [];
            contentNew.push('<h3><b>Faculty</b></h3>');
            contentNew.push('<div id="FSKMd"><svg height="20" width="200"><g><rect width="15" height="12"class="FSKM" ></g><g><text x="26" y="10">FSKM</text></g></svg></div>');
            contentNew.push('<div id="FPAd"><svg height="20" width="200"><g><rect width="15" height="12"class="FPA"></g><g><text x="26" y="10">FPA</text></g></svg></div>');
            legendSpec.innerHTML = contentNew.join('');
            legendSpec.index = 1;
            alert("ok"); 
        });

        var levelOpt = document.getElementById("level");
        google.maps.event.addDomListener(levelOpt, 'click', function() {
            contentNew = [];
            contentNew.push('<h3><b>Level of Education</b></h3>');
            contentNew.push('<div id="degreeD"><svg height="20" width="200"><g><rect width="15" height="12"class="degree" ></g><g><text x="26" y="10">Degree</text></g></svg></div>');
            contentNew.push('<div id="diplomaD"><svg height="20" width="200"><g><rect width="15" height="12"class="diploma"></g><g><text x="26" y="10">Diploma</text></g></svg></div>');
            legendSpec.innerHTML = contentNew.join('');
            legendSpec.index = 1;
            alert("ok"); 
        });

        map.controls[google.maps.ControlPosition.RIGHT_CENTER].push(legendSpec);
        calling();
    });

    function calling() {
        google.maps.event.addListener(map, 'mouseover', function () {

            var fskm = document.getElementById("FSKMd");
            google.maps.event.addDomListener(fskm, 'click', function () {
                alert("ok"); 
            });

            var fpa = document.getElementById("FPAd");
            google.maps.event.addDomListener(fpa, 'click', function () {
                alert("ok"); 
            });
//fskm and fpa legend come together in 1 legend

                var degree = document.getElementById("degreeD");
                google.maps.event.addDomListener(degree, 'click', function () {
                    alert("ok"); 
                });

                var diploma = document.getElementById("diplomaD");
                google.maps.event.addDomListener(diploma, 'click', function () {
                    alert("ok"); 
                });

var male= document.getElementById("maleD");
                google.maps.event.addDomListener(male, 'click', function () {
                    alert("ok"); 
                });

                var female= document.getElementById("femaleD");
                google.maps.event.addDomListener(female, 'click', function () {
                    alert("ok"); 
                });

        });

    }

【问题讨论】:

    标签: javascript jquery google-maps google-maps-api-3


    【解决方案1】:

    这意味着您的值为 null - 您没有正确引用要添加事件侦听器的任何内容。

    我假设当您提到教育水平时,您指的是:

    var degree = document.getElementById("degreeD");
    

    如果是这样,degreeD 不存在。也许您在 HTML 中使用了错误的名称。

    ** 根据 cmets 更新答案 **

    由于该元素是动态添加的——当代码运行时,该元素不存在,这意味着对它的引用,正如您所发现的,null

    有两种处理方法。

    1) 将您的 degreeD 事件侦听器移动到

    google.maps.event.addDomListener(levelOpt, 'click', function() {
    

    阻止,以便degreeD 存在。

    另一种选择是使用事件委托为可能尚不存在的元素注册事件。我不太了解 google.maps API,不知道它们是否支持事件委托,或者您是否必须手动处理。

    【讨论】:

    • degreeD会在用户点击levelOpt时加载
    • 很抱歉——没看到它藏在那里。我相应地更新了我的答案。
    • 它可以工作,但它就像它只循环一次。我怎么说?例如,我单击级别和特定级别进行过滤,它可以工作,但是当我单击性别等其他视图选项时,特定性别过滤器不起作用。
    • 要么 a) 设置一个函数来根据需要销毁和重新创建事件侦听器,然后在每次发生变化时调用该函数,或者 b) 查看设置事件委托。 StackOverflow 上有很多这样的例子,但它们可能不会直接处理 google.maps API。
    • 会试一试。谢谢:)
    猜你喜欢
    • 1970-01-01
    • 2021-04-02
    • 2018-11-04
    • 1970-01-01
    • 2021-12-17
    • 2015-02-18
    • 1970-01-01
    • 2022-11-20
    • 2022-11-24
    相关资源
    最近更新 更多