2014-01-05 79 views
0

以下renderChat函数用于将消息和图像呈现到聊天板上。在函数内部还有另外一个功能调用不带括号的JavaScript函数

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

函数被调用,但没有明确。它在图像加载时调用。 – Blender

+0

在'img.onload = onComplete;'你为'onload'事件分配一个函数对象。所以当图像加载时,函数会在某个时刻执行。如果立即执行该函数,则将该函数的返回值分配给该事件,**期望**将被调用的函数。 – elclanrs

回答

0

img.onload = onComplete;将分配函数onCompleteonload处理程序。这意味着,当通风发生时,函数被调用。

img.onload = onComplete();将分配调用函数onCompleteonload处理器的结果。这意味着该函数立即被调用,预计会返回另一个函数(或者包含有效JS的字符串),当事件发生时该函数将被调用。

1

HTMLImageElement对象将导致分配给其onloadonerror属性功能,以在适当的时间被调用(即,当HTTP响应被接收或等待超时)。

执行此操作的代码已内置到浏览器中。这些属性(或更现代的代码中的addEventListener函数)是您可以与该代码进行交互的唯一方式。

1

在Javascript中,您可以将函数存储在变量中,这就是您使用onComplete()所做的。 img对象将在成功加载图像(onload)后执行函数(称为回调函数),或者它无法加载图像(onerror)。

说句IMG对象这些事件后调用哪个方法,你需要给它这样的方法,而不括号

img.onload = onComplete; 
    img.onerror = onComplete; 

如果你会使用括号中的功能将被执行立即img.onload将不包含对函数的引用,但是包含onCompleted的结果。