2013-11-24 37 views
0

我有这个事件监听器,我试图找出为什么它随时被浏览器URL文本框中的URI更改触发。代码中没有其他对此函数的引用。代码来自“单页应用程序”一书。jQuery窗口绑定触发器

$(window) 
     .bind('hashchange', onHashchange) 
     .trigger('hashchange'); 

这是所有的代码:我理解除了我的问题之外的所有内容。我相信大部分可以被忽略。我只是希望你能够在上下文中看到它。

spa.shell = (function() { 
    //---------------- BEGIN MODULE SCOPE VARIABLES -------------- 
    var 
    configMap = { 
     anchor_schema_map : { 
     chat : { open : true, closed : true } 
     }, 
     main_html : String() 
     + '<div class="spa-shell-head">' 
      + '<div class="spa-shell-head-logo"></div>' 
      + '<div class="spa-shell-head-acct"></div>' 
      + '<div class="spa-shell-head-search"></div>' 
     + '</div>' 
     + '<div class="spa-shell-main">' 
      + '<div class="spa-shell-main-nav"></div>' 
      + '<div class="spa-shell-main-content"></div>' 
     + '</div>' 
     + '<div class="spa-shell-foot"></div>' 
     + '<div class="spa-shell-chat"></div>' 
     + '<div class="spa-shell-modal"></div>', 
     chat_extend_time  : 1000, 
     chat_retract_time : 300, 
     chat_extend_height : 450, 
     chat_retract_height : 15, 
     chat_extended_title : 'Click to retract', 
     chat_retracted_title : 'Click to extend' 
    }, 
    stateMap = { 
     $container  : null, 
     anchor_map  : {}, 
     is_chat_retracted : true 
    }, 
    jqueryMap = {}, 

    copyAnchorMap, setJqueryMap, toggleChat, 
    changeAnchorPart, onHashchange, 
    onClickChat,  initModule; 
    //----------------- END MODULE SCOPE VARIABLES --------------- 

    //------------------- BEGIN UTILITY METHODS ------------------ 
    // Returns copy of stored anchor map; minimizes overhead 
    copyAnchorMap = function() { 
    return $.extend(true, {}, stateMap.anchor_map); 
    }; 
    //-------------------- END UTILITY METHODS ------------------- 

    //--------------------- BEGIN DOM METHODS -------------------- 
    // Begin DOM method /setJqueryMap/ 
    setJqueryMap = function() { 
    var $container = stateMap.$container; 

    jqueryMap = { 
     $container : $container, 
     $chat  : $container.find('.spa-shell-chat') 
    }; 
    }; 
    // End DOM method /setJqueryMap/ 


    toggleChat = function (do_extend, callback) { 
    var 
     px_chat_ht = jqueryMap.$chat.height(), 
     is_open = px_chat_ht === configMap.chat_extend_height, 
     is_closed = px_chat_ht === configMap.chat_retract_height, 
     is_sliding = ! is_open && ! is_closed; 

    // avoid race condition 
    if (is_sliding) { return false; } 

    // Begin extend chat slider 
    if (do_extend) { 
     jqueryMap.$chat.animate(
     { height : configMap.chat_extend_height }, 
     configMap.chat_extend_time, 
     function() { 
      jqueryMap.$chat.attr(
      'title', configMap.chat_extended_title 
     ); 
      stateMap.is_chat_retracted = false; 
      if (callback) { callback(jqueryMap.$chat); } 
     } 
    ); 
     return true; 
    } 
    // End extend chat slider 

    // Begin retract chat slider 
    jqueryMap.$chat.animate(
     { height : configMap.chat_retract_height }, 
     configMap.chat_retract_time, 
     function() { 
     jqueryMap.$chat.attr(
     'title', configMap.chat_retracted_title 
     ); 
     stateMap.is_chat_retracted = true; 
     if (callback) { callback(jqueryMap.$chat); } 
     } 
    ); 
    return true; 
    // End retract chat slider 
    }; 

    changeAnchorPart = function (arg_map) { 
    var 
     anchor_map_revise = copyAnchorMap(), 
     bool_return  = true, 
     key_name, key_name_dep; 

    // Begin merge changes into anchor map 
    KEYVAL: 
    for (key_name in arg_map) { 
     if (arg_map.hasOwnProperty(key_name)) { 

     // skip dependent keys during iteration 
     if (key_name.indexOf('_') === 0) { continue KEYVAL; } 

     // update independent key value 
     anchor_map_revise[key_name] = arg_map[key_name]; 

     // update matching dependent key 
     key_name_dep = '_' + key_name; 
     if (arg_map[key_name_dep]) { 
      anchor_map_revise[key_name_dep] = arg_map[key_name_dep]; 
     } 
     else { 
      delete anchor_map_revise[key_name_dep]; 
      delete anchor_map_revise['_s' + key_name_dep]; 
     } 
     } 
    } 
    // End merge changes into anchor map 

    // Begin attempt to update URI; revert if not successful 
    try { 
     $.uriAnchor.setAnchor(anchor_map_revise); 
    } 
    catch (error) { 
     // replace URI with existing state 
     $.uriAnchor.setAnchor(stateMap.anchor_map,null,true); 
     bool_return = false; 
    } 
    // End attempt to update URI... 

    return bool_return; 
    }; 
    // End DOM method /changeAnchorPart/ 
    //--------------------- END DOM METHODS ---------------------- 

    //------------------- BEGIN EVENT HANDLERS ------------------- 
    // Begin Event handler /onHashchange/ 
    // Purpose : Handles the hashchange event 
    // Arguments: 
    // * event - jQuery event object. 
    // Settings : none 
    // Returns : false 
    // Action : 
    // * Parses the URI anchor component 
    // * Compares proposed application state with current 
    // * Adjust the application only where proposed state 
    //  differs from existing 
    // 
    onHashchange = function (event) { 
    var 
     anchor_map_previous = copyAnchorMap(), 
     anchor_map_proposed, 
     _s_chat_previous, _s_chat_proposed, 
     s_chat_proposed; 

    // attempt to parse anchor 
    try { anchor_map_proposed = $.uriAnchor.makeAnchorMap(); } 
    catch (error) { 
     $.uriAnchor.setAnchor(anchor_map_previous, null, true); 
     return false; 
    } 
    stateMap.anchor_map = anchor_map_proposed; 

    // convenience vars 
    _s_chat_previous = anchor_map_previous._s_chat; 
    _s_chat_proposed = anchor_map_proposed._s_chat; 

    // Begin adjust chat component if changed 
    if (! anchor_map_previous 
    || _s_chat_previous !== _s_chat_proposed 
    ) { 
     s_chat_proposed = anchor_map_proposed.chat; 
     switch (s_chat_proposed) { 
     case 'open' : 
      toggleChat(true); 
     break; 
     case 'closed' : 
      toggleChat(false); 
     break; 
     default : 
      toggleChat(false); 
      delete anchor_map_proposed.chat; 
      $.uriAnchor.setAnchor(anchor_map_proposed, null, true); 
     } 
    } 
    // End adjust chat component if changed 

    return false; 
    }; 
    // End Event handler /onHashchange/ 

    // Begin Event handler /onClickChat/ 
    onClickChat = function (event) { 
    changeAnchorPart({ 
     chat : (stateMap.is_chat_retracted ? 'open' : 'closed') 
    }); 
    return false; 
    }; 
    // End Event handler /onClickChat/ 
    //-------------------- END EVENT HANDLERS -------------------- 

    //------------------- BEGIN PUBLIC METHODS ------------------- 
    // Begin Public method /initModule/ 
    initModule = function ($container) { 
    // load HTML and map jQuery collections 
    stateMap.$container = $container; 
    $container.html(configMap.main_html); 
    setJqueryMap(); 

    // initialize chat slider and bind click handler 
    stateMap.is_chat_retracted = true; 
    jqueryMap.$chat 
     .attr('title', configMap.chat_retracted_title) 
     .click(onClickChat); 

    // configure uriAnchor to use our schema 
    $.uriAnchor.configModule({ 
     schema_map : configMap.anchor_schema_map 
    }); 

    // Handle URI anchor change events. 
    // This is done /after/ all feature modules are configured 
    // and initialized, otherwise they will not be ready to handle 
    // the trigger event, which is used to ensure the anchor 
    // is considered on-load 
    // 
    $(window) 
     .bind('hashchange', onHashchange) 
     .trigger('hashchange'); 

    }; 
    // End PUBLIC method /initModule/ 

    return { initModule : initModule }; 
    //------------------- END PUBLIC METHODS --------------------- 
}()); 
+0

hashchange不是一个跨浏览器的事件FYI –

+0

不知道我知道你在找什么(或者没有),但在这里,每次重新加载页面时,你正在引发onhashchange事件。那么你的问题是什么?你期望使用你的代码发生什么? –

+0

页面未重新加载。 – user3027430

回答

0

我几乎有一半的方式,通过阅读单页Web应用程序,我真的学到了很多关于如何编写干净独立的JavaScript模块以及如何配置各模块。这本书已经回答了我脑海中旋转的许多设计问题。

我相信你的问题的答案在第123页。这段代码的边距注释是“更新onClick事件处理程序来调用来更改URI锚点,然后立即退出,留下hashchange事件处理程序在壳牌拿起改变。“

当您单击聊天滑块时,会执行此回调,然后窗口的hashchange事件会自动执行spa.shell.onHashChange。

//------------------- BEGIN EVENT HANDLERS ------------------- 
onClickToggle = function (event){ 
    var set_chat_anchor = configMap.set_chat_anchor; 
    if (stateMap.position_type === 'opened') { 
    set_chat_anchor('closed'); 
    } 
    else if (stateMap.position_type === 'closed'){ 
    set_chat_anchor('opened'); 
    } return false; 
}; 
//-------------------- END EVENT HANDLERS --------------------