我有一些事件处理程序可以在 FF 中工作,但不能在 Safari 中工作。简而言之,我有一个 friend 列表,其中一些是硬编码的,一些是从数据库中提取的。点击好友会打开一个聊天窗口...这很像 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"> – </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> – </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 仍然中断。所以现在功能是一样的,这很好,但是点击事件不起作用。还有其他想法吗?
最佳答案
试试这个:
$('#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
,如果是,则触发处理程序。
另一种选择是在附加到 #friends-panel
之前(或之后)简单地在 success
回调中绑定(bind) click()
>.
要在 success
回调中绑定(bind)点击处理程序,请首先将该函数移至变量中:
var myfunc = function() {
alert("Loaded");
// close #friends-panel
$('.subpanel').hide();
$('#friends-panel a.chat').removeClass('active');
// ...and so on
}
...然后代替当前的点击
,执行以下操作:
$('#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)
关于jQuery 在 FF 中有效,但在 Safari 中无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3065602/