我正在阅读一本关于SPA的书 - 单页网页应用程序。这很有趣,但我被一段代码阻止了。到目前为止,我理解我在做什么,所以看起来很奇怪,这不是一件事。
我在聊天点击时触发了一个事件,该事件位于页面的右下角。此事件触发了URL哈希的更改,但是即使我将{+ 1}}
绑定到窗口,也不会触发hashchange事件我需要手动刷新页面以查看聊天从打开到关闭的变化,但这不应该发生,因为我希望它由$(window).bind('hashchange', onHashchange()).trigger('hashchange');
触发。
你能帮我看看发生了什么吗?
看起来我错过了一些东西,但周围的每个人都抱怨不能与其他浏览器兼容,而在这种情况下只是不起作用:S
赞赏任何提示=)
我有以下HTML代码
onhashchange
和3个脚本+ jquery清楚。第一个脚本可以在and is provided by the author of the book找到,其他两个是以下
spa.js
<html>
<head>
<title>SPA starter</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="css/spa.css" type="text/css">
<link rel="stylesheet" href="css/spa.shell.css" type="text/css">
<!-- 3rd party lib -->
<script id="jquery_js" src="js/libs/jquery/jquery.js"></script>
<script id="janchor_js" src="js/libs/jquery/jquery.uriAnchor.js"></script>
<!-- my lib -->
<script id ="spajs" src="js/spa.js"></script>
<script id="spashelljs" src="js/spa.shell.js"></script>
<script id="unloader" src="js/js_unloader.js"></script>
<script id="starter">
$(function() {
spa.initModule($('#spa'));
});
</script>
</head>
<body>
<div id="spa"></div>
</body>
</html>
spa.shell.js
var spa = (function() {
var initModule = function($container) {
spa.shell.initModule($container);
};
return {initModule: initModule};
}());
spa.css
spa.shell = (function() {
//----------- BEGIN MODULE SCOPE VARIABLES ---------
var configMap = {
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: 250,
chat_retract_time: 300,
chat_extend_height: 450,
chat_retract_height: 15,
chat_extended_title: 'Click to retract',
chat_retracted_title: 'Click to extend',
anchor_schema_map: {
chat: {open: true, closed: true}
}
},
stateMap = {
$container: null,
is_chat_retracted: true,
anchor_map: {}
},
jqueryMap = {},
setJqueryMap, toogleChat, onClickChat,
copyAnchorMap, changeAnchorPart, onHashchange,
initModule;
//----------- END MODULE SCOPE VARIABLES ---------
//----------- BEGIN UTILITY METHODS ---------
//Return copy of stored anchro map; minimizes overhead
copyAnchorMap = function() {
return $.extend(true, {}, stateMap.anchor_map);
};
//----------- END UTILITY METHODS ---------
//----------- BEGIN DOM METHODS ---------
//Begin DOM method /changeAnchorPart/
changeAnchorPart = function(arg_map) {
console.log("change anchor part");
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)) {
//console.log("key_name:= " + key_name);
//skip dependet keys during iteration
if (key_name.indexOf('_') === 0) {
console.log("key name starts with '_'");
continue KEYVAL;
}
//update independent key value
anchor_map_revise[key_name] = arg_map[key_name];
//update matching dependent key
key_name_dep = '_' + key_name;
//console.log("key_name_dep:= " + key_name_dep);
if (arg_map[key_name_dep]) {
//console.log("if");
anchor_map_revise[key_name_dep] = arg_map[key_name_dep];
}
else {
//console.log("else");
delete anchor_map_revise[key_name_dep];
delete anchor_map_revise['_s' + key_name_dep];
}
}
}
//END merge changes into anchor map
//BEGIN ateempt to update URI; revert if not successful
try {
console.log("setting anchor");
$.uriAnchor.setAnchor(anchor_map_revise);
console.log("set");
} catch (error) {
//replace URI with existing state
$.uriAnchor.setAnchor(stateMap.anchor_map, null, true);
console.log("changeAnchorPart error :=" + error);
bool_return = false;
}
//END attemp to update URI
return bool_return;
};
//END DOM method /changeAnchorPart/
//begin DOM method /setJqueryMap/
setJqueryMap = function() {
var $container = stateMap.$container;
jqueryMap = {$container: $container,
$chat: $container.find('.spa-shell-chat')
};
};
//end DOM method /setJqueryMap/
//Begin DOM method /toogleChat/
//
toogleChat = 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) {
console.log('avoid race condition');
return false;
}
//begin 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 rectract chat slider
};
//end DOM method /toogleChat/
//----------- END DOM METHODS ---------
//
//----------- BEGIN EVENT HANDLERS ---------
onClickChat = function(event) {
// console.log(stateMap.is_chat_retracted);
changeAnchorPart({
chat: (stateMap.is_chat_retracted ? 'open' : 'closed')
});
return false;
};
//
// BEGIN event handler /onHashchange/
//
onHashchange = function(event) {
console.log("on hash change");
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) {
console.log("onHashchange error:= " + 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 of component if changed
if (!anchor_map_previous || _s_chat_previous !== _s_chat_proposed) {
s_chat_proposed = anchor_map_proposed.chat;
console.log("adjusting components, chat:= " + s_chat_proposed);
switch (s_chat_proposed) {
case 'open':
toogleChat(true);
break;
case 'closed':
toogleChat(false);
break;
default :
toogleChat(false);
delete anchor_map_proposed.chat;
$.uriAnchor.setAnchor(anchor_map_proposed, null, true);
}
}
//END of the adjustment
return false;
};
//END event handler /onHashchange/
//----------- END EVENT HANDLERS ---------
//----------- BEGIN PUBLIC METHODS ---------
//Begin Public methods /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
//
if ("onhashchange" in window) {
console.log('SUPPORTED');
}
$(window).bind('hashchange', onHashchange()).trigger('hashchange');
};
//End PUBLIC methods /initModule/
return {initModule: initModule};
//----------- END PUBLIC METHODS ---------
}());
spa.shell.css
*{
margin : 0;
padding : 0;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
h1,h2,h3,h4,h5,h6, p{ margin-bottom: 10px;}
o1,ul,dl{list-style-position: inside;}
/** end reset */
/** begin standard selectors */
body{
font: 13px 'Trebuchet MS', Verdana, Helvetica, Arial, sans-serif;
color: #444;
background-color: #888;
}
strong{
font-weight: 800;
color:#000;
}
/** end standard selectors */
/** begin spa namespace selectors */
#spa{
position: absolute;
top:8px;
left:8px;
bottom:8px;
right:8px;
min-height: 500px;
min-width: 500px;
overflow: hidden;
border-radius: 0 8px 0 8px;
background-color: #fff;
}
/** end spa namespace selectors */
/** begin utility selectors */
.spa-x-select{}
.spa-x-clearfloat{
height: 0 !important;
float: none !important;
visibility: hidden !important;
clear: both !important;
}
/** */
答案 0 :(得分:1)
如果我弄错了,请纠正我,但你正在绑定中执行该功能。你想要这样:
$(window).bind('hashchange', onHashchange).trigger('hashchange');
没有&#39;()&#39;后。
请记住,在某些浏览器中,对此的支持是有限的。
if (("onhashchange" in window) && !($.browser.msie)) {
window.onhashchange = function () {
alert(window.location.hash);
}
// Or $(window).bind( 'hashchange',function(e) {
// alert(window.location.hash);
// });
}
else {
var prevHash = window.location.hash;
window.setInterval(function () {
if (window.location.hash != prevHash) {
prevHash = window.location.hash;
alert(window.location.hash);
}
}, 100);
}
根据您的需要进行调整。