【问题标题】:Button on click not working but leaflet marker on click works just fine?单击时的按钮不起作用,但单击时的传单标记可以正常工作?
【发布时间】:2015-06-19 15:07:26
【问题描述】:

我正在开发一个应用程序,我从数据库中获取所有用户,然后使用 Leaflet 标记将它们绘制在 Mapbox 地图上。

当用户点击标记时,该特定的聊天框会打开,他可以与他们聊天。

但现在我想稍微改变一下这个功能。我希望在 Leaflet 中使用 bindPopup 方法弹出一个弹出窗口,以显示一个有关用户的小信息框,该用户将具有聊天按钮,单击它将显示聊天框,但我以某种方式失败了。

我在正文中设置了一个隐藏的 div,它是弹出内容的占位符,如下所示:

    <div class="container-fluid">
        <div class="row">
            <div class="col-xs-6 text-left">
                <h3 id="statusHolder">Status</h3>
            </div>
            <div class="col-xs-6 text-right">
                <button id="chatWithUser" class="btn btn-primary" href="">Chat</button>
            </div>
        </div>
    </div>

现在这是放置标记并操作弹出窗口内容的 JS 代码。它定义了点击事件标记以及点击按钮。点击标记工作正常。点击按钮没有。什么都没发生。没有控制台错误。事实上,我什至无法通过它在控制台中记录任何内容。

$.getJSON('/users', function(response){

    $.each(response, function(i, user){

        // Parsing lat, lng values
        var lat = parseFloat(user.farmer_profile.lat);
        var lng = parseFloat(user.farmer_profile.lng);

        // Setting marker color based on status
        switch(user.status){
            case 'Available':
            var color = '#659265';
            break;
            case 'Busy':
            var color = '#C46A69';
            break;
            case 'Idle':
            var color = '#C79121';
            break;
        }

        // Setting icon of marker to differentiate between 
        // current user and everyone else
        var icon;
        var size;

        if(user.id == currentUser.id){
            icon = 'star';
            size = 'large';
        }else{
            icon = 'pitch'
        }

        // Plotting marker on the map for the farmer
        var marker = L.marker([lat, lng], {
            icon: L.mapbox.marker.icon({
                'marker-size': size,
                'marker-symbol': icon,
                'marker-color': color
            }),
        }).addTo(map);

        // Don't bind the existing user with the chat function.
        if(user.id == currentUser.id){

            return true;
        }

        // Binding the marker on click event to bring up the chat
        // This was working fine
        /*marker.on('click', function(){
            var chatboxId = 'chat-' + currentUser.id + '-' + user.id;
            chatboxManager.addBox(chatboxId, {
                first_name: user.first_name,
                last_name: user.last_name,
            });

            $('#' + chatboxId).chatbox({
                messageSent: function(id, user, message){
                    this.boxManager.addMsg('Me', message);

                    splittedId = id.split('-');

                    $.ajax({
                        url: '/messages',
                        method: 'post',
                        type: 'json',
                        data: {
                            receiver_id: splittedId[2],
                            body: message
                        }
                    });
                }
            });
        });*/

        $('span#firstNameHolder').text(user.first_name);
        $('span#lastNameHolder').text(user.last_name);

        $('b#farmNameHolder').text(user.farmer_profile.farm_name);

        $('b#latHolder').text(user.farmer_profile.lat);
        $('b#lngHolder').text(user.farmer_profile.lat);

        $('h3#statusHolder').text(user.status);

        // This is not yeilding any results.
        // Not event the console.log('hello');
        $('#chatWithUser').on('click', function(e){
            console.log('hello');
            var chatboxId = 'chat-' + currentUser.id + '-' + user.id;
            chatboxManager.addBox(chatboxId, {
                first_name: user.first_name,
                last_name: user.last_name,
            });

            $('#' + chatboxId).chatbox({
                messageSent: function(id, user, message){
                    this.boxManager.addMsg('Me', message);

                    splittedId = id.split('-');

                    $.ajax({
                        url: '/messages',
                        method: 'post',
                        type: 'json',
                        data: {
                            receiver_id: splittedId[2],
                            body: message
                        }
                    });
                }
            });
        });

        var popupContent = $('#popupContent').html();
        marker.bindPopup(popupContent);
    });
});

谁能指出我遗漏了什么?

【问题讨论】:

  • 您是否尝试使用委托事件? $(document).on('click', '#chatWithUser', function(e){ /*...*/ });
  • 恐怕我不确定这是如何工作的。我将首先研究委托事件。无论如何,感谢您的快速回复。
  • 不客气。如果您知道已弃用的 .live() 方法,这是在 DOM 中删除事件的新方法。 Check docs????
  • 我试过你的代码$(document).on('click', '#chatWithUser', function(e){ /*...*/ });。它有效,但不幸的是不是我需要的。它一次打开所有的聊天框。你能帮我一个类似的解决方案,但只针对点击的聊天按钮吗? :)
  • 可能是因为您对所有聊天框使用相同的 ID,请记住 ID 必须是唯一标识符。如果是这种情况,您应该考虑将其更改为一个类。我会发布一个答案来解释它。

标签: javascript jquery leaflet


【解决方案1】:

好吧,我终于弄清楚出了什么问题。实际上有几件事。

首先,所有聊天按钮都有相同的 ID chatWithUser,因此会发生冲突。

所以我继续编辑了一些代码:

var popupContent = $('div#popupContent').clone();

popupContent.find('span#firstNameHolder').text(user.first_name);
popupContent.find('span#lastNameHolder').text(user.last_name);

popupContent.find('b#farmNameHolder').text(user.farmer_profile.farm_name);

popupContent.find('b#latHolder').text(user.farmer_profile.lat);
popupContent.find('b#lngHolder').text(user.farmer_profile.lat);

popupContent.find('h3#statusHolder').text(user.status);

popupContent.find('#chatWithUser').attr('id', 'chatWithUser' + i);

$(document).on('click', '#chatWithUser' + i, function(e){
    console.log('hello');
    var chatboxId = 'chat-' + currentUser.id + '-' + user.id;
    chatboxManager.addBox(chatboxId, {
        first_name: user.first_name,
        last_name: user.last_name,
    });

    $('#' + chatboxId).chatbox({
        messageSent: function(id, user, message){
            this.boxManager.addMsg('Me', message);

            splittedId = id.split('-');

            $.ajax({
                url: '/messages',
                method: 'post',
                type: 'json',
                data: {
                    receiver_id: splittedId[2],
                    body: message
                }
            });
        }
    });
});

console.log(popupContent.html());

marker.bindPopup(popupContent.html());

我没有采用原始 div,而是每次在循环中克隆它,并提供聊天按钮和 '#chatWithUser' + i 的 ID,从而解决了冲突问题。

但即使在这一点上,点击事件也不起作用。所以我接受了@kmsdev 的建议,并像这样使用了委托事件:

$(document).on('click', '#chatWithUser' + i, function(e){
// my code here
});

虽然我仍然不完全清楚为什么这样有效,为什么不是简单的$(ele).on('click', callback);,但这个解决方案对我有用。

【讨论】:

  • 我很高兴你实现了它。我可以向你解释最后一点。设置事件处理程序时,要处理的元素必须在 dom 中。 $(elem).on('click', ...); // but elem does not exist yet!。委托事件可以委托,我的意思是:$(document).on('click', elem, ...); 将事件绑定到文档(始终保留在那里的元素),并代表其子元素通知点击。
  • 总结:“事件委托是指使用事件传播(冒泡)来处理DOM中比事件起源的元素更高级别的事件的过程。它允许我们为现在或将来存在的元素附加一个事件侦听器。” - 摘自jQuery Docs
  • 这是有道理的。太感谢了。 :)
猜你喜欢
  • 2014-03-24
  • 1970-01-01
  • 2017-03-09
  • 2016-09-05
  • 1970-01-01
  • 2020-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多