JQuery работает в FF, но не в Safari - PullRequest
1 голос
/ 18 июня 2010

У меня есть некоторые обработчики событий, которые работают в 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.

Спасибо, Христо

EDIT: я пытался создать событие jQuery с .live () и .delegate (), и происходит то же самое... FF ломается и Safari остается сломанным.Таким образом, функциональность теперь та же, что хорошо, но событие click не работает.Есть еще идеи?

Ответы [ 2 ]

3 голосов
/ 18 июня 2010

Попробуйте:

$('#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, и он вернет функцию, которая принимает параметры, используемые для Hander.

Немного более запутаннымвозможно, но правильный подход.Сделайте ваш выбор.: О)

0 голосов
/ 18 июня 2010

, как я обычно это делаю, это:

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

вместо:

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

.live позволяет привязывать обработчики событий к элементам, загруженным AJAX (после готовности DOM).


EDIT:

пример использования 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 a.buddy'). click (function () { предупреждение ( "Loaded");
// закрыть # друзья-панель $ ( 'Подпанель') скрыть (). $ ('# 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 () в функцию события клика.

...