jQuery适用于FF但不适用于Safari

时间:2010-06-17 20:59:31

标签: jquery firefox safari

我有一些在FF中工作的事件处理程序,而不在Safari中。简单地说,我有一个朋友列表,一些硬编码,一些从数据库中提取。点击一个好友打开一个聊天窗口......这很像Facebook聊天系统。

所以在Firefox中,一切正常并且符合预期。在Safari中,单击硬编码的好友可以正常工作,但点击从数据库中拉入的好友不会拉起聊天窗口。

<script type="text/javascript" src="js/jQuery.js"></script>
<script type="text/javascript" src="js/chat.js"></script>
<script type="text/javascript" src="js/ChatBar.js"></script>
<script type="text/javascript" src="js/settings.js"></script>
<script type="text/javascript">
    var chat = new Chat();
    var from = <?php echo "'" .$_SESSION['userid'] . "'"; ?>;
    chat.getUsers(<?php echo "'" .$_SESSION['userid'] . "'"; ?>);
</script>

所以我用chat.getUsers加载所有好友。该功能是:

// get list of friends 
function getBuddyList(userName) {
    userNameID = userName;

    $.ajax({
        type: "GET",
        url: "buddyList.php",
        data: {
            'userName': userName,
            'current': numOfUsers
        },
        dataType: "json",
        cache: false,
        success: function(data) {
            if (numOfUsers != data.numOfUsers) {
                numOfUsers = data.numOfUsers;
                var list = "<li><span>Agents</span></li>";
                for (var i = 0; i < data.friendlist.length; i++) {  
                    list += "<li><a class=\"buddy\" href=\"#\"><img alt=\"\" src=\"images/chat-thumb.gif\">"+ data.friendlist[i] +"</a></li>";
                }
                $('#friend-list ul').append($(list));
            }
            setTimeout('getBuddyList(userNameID)', 1000);
        }
    });
}

buddyList.php只是从数据库中提取用户并返回一个包含用户名的数组。所以用于点击好友的jQuery是:

// click on buddy in #friends-panel
$('#friends-panel a.buddy').click(function() {
    alert("Loaded");    
    // close #friends-panel
    $('.subpanel').hide();
    $('#friends-panel a.chat').removeClass('active');

    // if a chat window is already active, close it and deactivate
    $('#mainpanel li[class="active-buddy-tab"] div').not('#chat-box').removeAttr('id');
    $('#mainpanel li[class="active-buddy-tab"]').removeClass('active-buddy-tab').addClass('buddy-tab');

    // create active buddy chat window
    $('#mainpanel').append('<li class="active-buddy-tab"><a class="buddy-tab" href="#"></a><div id="chat-window"><h3><p id="to"></p></h3></div></li>');

    // create name and close/minimize buttons
    $('.active-buddy-tab div h3 p#to').text($(this).text());
    $('.active-buddy-tab div h3').append('<span class="close"> X </span><span class="minimize"> &ndash; </span>');
    $('.active-buddy-tab').append('<span class="close"> X </span>');

    // create chat area
    $('.active-buddy-tab div').append('<div id="chat-box"></div><form id="chat-message"><textarea id="message" maxlength="100"></textarea></form>');

    // put curser in chat window
    $('.active-buddy-tab #message').focus();

    // create a chat relationship
    return false;
});

... HTML的基本结构是:

<div id="footpanel">
  <ul id="mainpanel">
    <li id="friends-panel">
      <a href="#" class="chat">Friends (<strong>18</strong>) </a>
      <div id="friend-list" class="subpanel">
        <h3><span> &ndash; </span>Friends Online</h3>
        <ul>
          <li><span>Family Members</span></li>
          <!-- Hard coded buddies -->
          <li><a href="#" class="buddy"><img src="images/chat-thumb.gif" alt="" /> Your Friend 1</a></li>
          <li><a href="#" class="buddy"><img src="images/chat-thumb.gif" alt="" /> Your Friend </a></li>
          <!-- buddies will be added in dynamically here -->
        </ul>
      </div>
    </li>
  </ul>
</div>

我不太确定从哪里开始解决这个问题。我认为它可能是一个渲染错误或DOM的东西,但我一直盯着这些代码而且我被卡住了。有关为什么它在FF中工作而不在Safari中的任何想法?顺便说一句......我正在测试Snow Leopard。

谢谢, 赫里斯托斯

编辑:我尝试用.live()和.delegate()创建jQuery事件,同样的事情发生...... FF中断和Safari仍然破坏。所以功能现在是相同的,这很好,但是click事件不起作用。还有其他想法吗?

2 个答案:

答案 0 :(得分:3)

试试这个:

$('#friends-panel').delegate( 'a.buddy', 'click', function() {
    alert("Loaded");    
    // ...your code
});

...而不是$('#friends-panel a.buddy').click(function() {...

http://api.jquery.com/delegate/

当您致电.click(function...)时,您实际上正在呼叫.bind('click', function...)

如果设置为在DOM加载后运行,它会将点击处理程序分配给现有元素。

加载DOM后动态添加的元素不会从中受益。

使用.delegate()将点击处理程序放在#friends-panel上,并侦听在其旁边发生的点击。当一个发生时,它会检查它是否是a.buddy,如果是,则触发处理程序。

另一种选择是在追加到click()之前(或之后)绑定success回调中的#friends-panel


要绑定success回调中的点击处理程序,请先将该函数移动到变量中:

var myfunc = function() {
    alert("Loaded");    
    // close #friends-panel
    $('.subpanel').hide();
    $('#friends-panel a.chat').removeClass('active');

    // ...and so on
}

...然后代替您当前的click,请改为:

$('#friends-panel a.buddy').click( myfunc );

...然后在success回调中,执行此操作:

success: function(data) {
            if (numOfUsers != data.numOfUsers) {
                numOfUsers = data.numOfUsers;
                var list = "<li><span>Agents</span></li>";
                for (var i = 0; i < data.friendlist.length; i++) {  
                    list += "<li><a class=\"buddy\" href=\"#\"><img alt=\"\" src=\"images/chat-thumb.gif\">"+ data.friendlist[i] +"</a></li>";
                }

                   // new version
                $(list).click( myfunc ).appendTo('#friend-list ul'); 

                // old version
// off-topic, no need to create jQuery object-----v
                // $('#friend-list ul').append($(list)); 

            }
            setTimeout('getBuddyList(userNameID)', 1000);
        }

编辑:要将需要参数的函数分配给单击处理程序,一种方法是将函数调用放在回调函数中。

所以不要这样:

$('#friends-panel a.buddy').click( buddyClick );

你会这样做:

// Set up a handler that calls your function------v
$('#friends-panel a.buddy').click( function() { buddyClick(parameters) } );

另一种方法是让你的buddyClick返回一个使用传入参数的函数,如:

// Calling buddyClick actually returns a function
//   that can use the parameters you passed in
var buddyClick = function(parameters) {
    return function() {
       alert("Loaded");
       // do something with the parameters  
       // ...and so on
    };
};

// Calling buddyClick returns the function
$('#friends-panel a.buddy').click( buddyClick('some_parameter') );

这样,您可以调用buddyClick,它将返回接受用于操作的参数的函数。

或许更令人困惑,但这是一种有效的方法。随便挑选。 :O)

答案 1 :(得分:0)

我通常这样做的方式是:

$('#friends-panel a.buddy').live('click',function() { ... });

而不是:

$('#friends-panel a.buddy').click(function() { ... });

.live允许您将事件处理程序绑定到加载了AJAX的元素(在DOM准备好之后)。


修改

使用console.log()调试问题的示例:

// get list of friends 
function getBuddyList(userName) {
    userNameID = userName;
    console.log('userNameID: '+ userNameID); //make sure a userNameID is being passed.

    $.ajax({
        type: "GET",
        url: "buddyList.php",
        data: {
            'userName': userName,
            'current': numOfUsers
        },
        dataType: "json",
        cache: false,
        success: function(data) {
            console.log(data); //dump the returned data into the console.log
            if (numOfUsers != data.numOfUsers) {
                numOfUsers = data.numOfUsers;
                var list = "<li><span>Agents</span></li>";
                for (var i = 0; i < data.friendlist.length; i++) {  
                    list += "<li><a class=\"buddy\" href=\"#\"><img alt=\"\" src=\"images/chat-thumb.gif\">"+ data.friendlist[i] +"</a></li>";
                    console.log(list); //dump each iteration to the console but also show each addition on each iteration.
                }
                $('#friend-list ul').append($(list));
            }
            setTimeout('getBuddyList(userNameID)', 1000);
        }
    });
}

和 //点击#friends-panel中的好友 $('#friends-panel a.buddy')。click(function(){     警报( “装”);
    //关闭#friends-panel     $( '子面板')隐藏()。     $('#friends-panel a.chat')。removeClass('active');

// if a chat window is already active, close it and deactivate
$('#mainpanel li[class="active-buddy-tab"] div').not('#chat-box').removeAttr('id');
$('#mainpanel li[class="active-buddy-tab"]').removeClass('active-buddy-tab').addClass('buddy-tab');

// create active buddy chat window
$('#mainpanel').append('<li class="active-buddy-tab"><a class="buddy-tab" href="#"></a><div id="chat-window"><h3><p id="to"></p></h3></div></li>');

// create name and close/minimize buttons
$('.active-buddy-tab div h3 p#to').text($(this).text());
$('.active-buddy-tab div h3').append('<span class="close"> X </span><span class="minimize"> &ndash; </span>');
$('.active-buddy-tab').append('<span class="close"> X </span>');

// create chat area
$('.active-buddy-tab div').append('<div id="chat-box"></div><form id="chat-message"><textarea id="message" maxlength="100"></textarea></form>');

// put curser in chat window
$('.active-buddy-tab #message').focus();

// create a chat relationship
return false;

});

这可能会给你一些关于它破裂的原因和原因的想法。您还应该在整个点击事件功能中添加console.log()。