以下renderChat函数用于将消息和图像呈现到聊天板上。在函数内部还有另一个函数
var onComplete = function () {
执行创建列表元素并将其附加到聊天列表的所有工作。在onComplete函数之后,只有这三行代码
img.onload = onComplete;
img.onerror = onComplete;
img.src = c.chat.value.media;
因为var onComplete
是分配给变量的函数,所以我认为必须用括号调用它。因此,当我看到这个
img.onload = onComplete;
我知道该函数已分配给一个新变量,但从未被调用过。然而,当我使用该应用程序时,聊天已在我们到达img.src = c.chat.value.media;
你能解释一下我对JavaScript的理解是怎么回事以及这个函数是如何工作的吗?
var renderChat = function (c) {
debug("Rendering chat: key='%s' fingerprint='%s' message='%s' created='%s' imageMd5='%s'",
c.chat.key,
c.chat.value.fingerprint,
c.chat.value.message,
c.chat.value.created,
md5(c.chat.value.media));
var renderFP = c.chat.value.fingerprint;
if (!isMuted(renderFP)) {
var img = new Image();
var onComplete = function () {
// Don't want duplicates and don't want muted messages
if (body.find('li[data-key="' + c.chat.key + '"]').length === 0 &&
!isMuted(renderFP)) {
var li = document.createElement('li');
li.dataset.action = 'chat-message';
li.dataset.key = c.chat.key;
li.dataset.fingerprint = renderFP;
li.appendChild(img);
// This is likely your own fingerprint so you don't mute yourself. Unless you're weird.
if (userId.val() !== renderFP) {
updateNotificationCount();
var btn = document.createElement('button');
btn.textContent = 'mute';
btn.className = 'mute';
li.appendChild(btn);
}
var message = document.createElement('p');
message.textContent = c.chat.value.message;
message.innerHTML = transform(message.innerHTML);
li.appendChild(message);
var createdDate = moment(new Date(c.chat.value.created));
var timestamp = document.createElement('time');
timestamp.setAttribute('datetime', createdDate.toISOString());
timestamp.textContent = createdDate.format('LT');
timestamp.className = 'timestamp';
li.appendChild(timestamp);
var size = addChat.is(":visible") ? addChat[0].getBoundingClientRect().bottom : $(window).innerHeight();
var last = chatList[0].lastChild;
var bottom = last ? last.getBoundingClientRect().bottom : 0;
var follow = bottom < size + 50;
chatList.append(li);
setupWaypoints(li);
debug('Appended chat %s', c.chat.key);
// if scrolled to bottom of window then scroll the new thing into view
// otherwise, you are reading the history... allow user to scroll up.
if (follow) {
var children = chatList.children();
if (children.length > CHAT_LIMIT) {
children.first().remove().waypoint('destroy');
}
li.scrollIntoView();
}
}
};
img.onload = onComplete;
img.onerror = onComplete;
img.src = c.chat.value.media;
}
};
答案 0 :(得分:1)
HTMLImageElement
对象将导致在适当的时间调用分配给其onload
和onerror
属性的函数(即,当收到HTTP响应或等待它超时时) )。
执行此操作的代码内置于浏览器中。属性(或更现代代码中的addEventListener
函数)是您与该代码交互的唯一方式。
答案 1 :(得分:1)
在Javascript中,您可以将函数存储在变量中,这是您使用onComplete()
所做的。
img对象将在成功加载图像(onload)之后执行一个函数(所谓的回调),或者如果它无法加载图像(onerror)。
要告诉img对象在这些事件之后调用哪个方法,你需要给它一个方法名称,如不带括号:
img.onload = onComplete;
img.onerror = onComplete;
如果你使用括号,函数将立即执行 ,img.onload
将不包含对函数的引用,但是包含onCompleted的结果。
答案 2 :(得分:0)
img.onload = onComplete;
会将函数 onComplete
分配给onload
处理程序。这意味着,当通风口发生时,该功能被调用。
img.onload = onComplete();
会将调用函数 onComplete
的结果分配给onload
处理程序。这意味着,函数被立即调用,期望返回另一个函数(或包含有效JS的字符串),而事件发生时将调用该函数。