Javascript 聚合物核心菜单双事件
我正在使用我的web应用程序,目前在页面链接方面遇到一些问题。这是我使用所有ajax/javascript创建的第一个站点,因此我还没有太多使用javascript的历史函数 不管怎样,我在左侧边栏有一个主菜单。当按下其中一个按钮时,它应更改浏览器的url,并将其放入浏览器的历史记录中。为此,我有以下代码:Javascript 聚合物核心菜单双事件,javascript,browser-history,polymer,Javascript,Browser History,Polymer,我正在使用我的web应用程序,目前在页面链接方面遇到一些问题。这是我使用所有ajax/javascript创建的第一个站点,因此我还没有太多使用javascript的历史函数 不管怎样,我在左侧边栏有一个主菜单。当按下其中一个按钮时,它应更改浏览器的url,并将其放入浏览器的历史记录中。为此,我有以下代码: Polymer('my-app', { mainMenu: function(){ this.$.mainPages.selected = this.$.mainMe
Polymer('my-app', {
mainMenu: function(){
this.$.mainPages.selected = this.$.mainMenu.selected;
console.log("Pusing state " + this.$.mainMenu.selected);
history.pushState(null , "title", this.$.mainMenu.selected);
}
});
现在的问题是它会被调用两次,所以如果单击一次,pushState会被调用两次。不用说,这是不好的
我在这里生成了一个示例代码:
在这个示例代码中,您可以看到在按下两个菜单项后,首先会触发两次事件。我还注意到,当按下后退按钮时,更新页面似乎也会重新刷新pushState
因此,简而言之,我的第一个关注点是,从主菜单
函数中按下一个元素的事件会被调用两次第二个问题是,我回去时会对国家产生反感,我认为这也应该避免
更新代码:
Polymer('my-app', {
ready: function(){
var link = document.URL.split("/");
this.$.mainMenu.selected = link[link.length-1];
console.log("ready with link: "+link[link.length-1]);
window.onpopstate = function(){
var link = document.URL.split("/");
console.log("Calling onpopstate. New link is: "+link[link.length-1]);
this.$.mainMenu.selected = link[link.length-1];
this.$.mainPages.selected = this.$.mainMenu.selected;
}
},
nav: function(){
this.$.drawerPanel.togglePanel();
},
back: function(){
window.history.back();
},
mainMenu: function(){
console.log("Pusing state " + this.$.mainMenu.selected);
this.$.mainPages.selected = this.$.mainMenu.selected;
history.pushState(null , "title", this.$.mainMenu.selected);
}
}
您将获得两个事件,一个用于取消选择当前选定的项目,另一个用于新选定的项目。检查传递给回调函数的事件对象:
mainMenu: function(e) {
console.log(e.detail.isSelected);
console.log(e.detail.item);
}
但是,如果您在core activate上使用,
则当用户点击菜单项时,您的回调只会被调用一次(当您以编程方式更改菜单选择时,不会调用回调)。这可以防止在您更改程序中的菜单选择时出现不必要的窗口历史推送
然后,您应该设置一个窗口.onpopstate
回调,在其中选择(上一个)菜单项。如果在back()
函数中调用document.URL
,它将返回当前URL,而不是window.history.back()
设置的新URL。相反,此函数仅从历史记录中弹出
这应该起作用:
<core-menu ... on-core-activate="{{mainMenu}}">
Polymer("my-app", {
ready: function() {
var self = this;
this.$.mainMenu.selected = "home";
history.pushState(null, "Title", this.$.mainMenu.selected);
window.onpopstate = function() {
var link = document.URL.split("/");
self.$.mainMenu.selected = link[link.length-1];
self.$.mainPages.selected = self.$.mainMenu.selected;
};
},
mainMenu: function() {
this.$.mainPages.selected = this.$.mainMenu.selected;
history.pushState(null, "Title", this.$.mainMenu.selected);
},
back: function() {
window.history.back();
}
});
聚合物(“我的应用程序”{
就绪:函数(){
var self=这个;
此.$.main menu.selected=“home”;
history.pushState(null,“Title”,this.$.main menu.selected);
window.onpopstate=函数(){
var link=document.URL.split(“/”);
self.$.main menu.selected=link[link.length-1];
self.$.mainPages.selected=self.$.mainMenu.selected;
};
},
主菜单:函数(){
this.$.mainPages.selected=this.$.main menu.selected;
history.pushState(null,“Title”,this.$.main menu.selected);
},
返回:函数(){
window.history.back();
}
});
您将获得两个事件,一个用于取消选择当前选定的项目,另一个用于新选定的项目。检查传递给回调函数的事件对象:
mainMenu: function(e) {
console.log(e.detail.isSelected);
console.log(e.detail.item);
}
但是,如果您在core activate上使用,
则当用户点击菜单项时,您的回调只会被调用一次(当您以编程方式更改菜单选择时,不会调用回调)。这可以防止在您更改程序中的菜单选择时出现不必要的窗口历史推送
然后,您应该设置一个窗口.onpopstate
回调,在其中选择(上一个)菜单项。如果在back()
函数中调用document.URL
,它将返回当前URL,而不是window.history.back()
设置的新URL。相反,此函数仅从历史记录中弹出
这应该起作用:
<core-menu ... on-core-activate="{{mainMenu}}">
Polymer("my-app", {
ready: function() {
var self = this;
this.$.mainMenu.selected = "home";
history.pushState(null, "Title", this.$.mainMenu.selected);
window.onpopstate = function() {
var link = document.URL.split("/");
self.$.mainMenu.selected = link[link.length-1];
self.$.mainPages.selected = self.$.mainMenu.selected;
};
},
mainMenu: function() {
this.$.mainPages.selected = this.$.mainMenu.selected;
history.pushState(null, "Title", this.$.mainMenu.selected);
},
back: function() {
window.history.back();
}
});
聚合物(“我的应用程序”{
就绪:函数(){
var self=这个;
此.$.main menu.selected=“home”;
history.pushState(null,“Title”,this.$.main menu.selected);
window.onpopstate=函数(){
var link=document.URL.split(“/”);
self.$.main menu.selected=link[link.length-1];
self.$.mainPages.selected=self.$.mainMenu.selected;
};
},
主菜单:函数(){
this.$.mainPages.selected=this.$.main menu.selected;
history.pushState(null,“Title”,this.$.main menu.selected);
},
返回:函数(){
window.history.back();
}
});
使用数据绑定会更好。这里的想法是使您的元素模型成为受驱动的,一种模型视图演示器(MVP)模式。模型由元素中的属性组成,视图由模板描述,演示者在脚本中。数据绑定允许我们从逻辑松散地耦合视图
让我们决定当前页面将由名为page
的属性控制
然后,我们可以将UI设置为由页面
属性驱动:
<core-menu selected="{{page}}" valueattr="id">
...
</core-menu>
<core-animated-pages class="main" selected="{{page}}" valueattr="id" transitions="slide-from-right">
我们跟踪poppedPage
,以便区分前后。我们只想在前进的时候推动一个新的国家
现在,我们需要在历史记录中反映页面,因此我们需要在页面更改时推送状态。如上所述,一个警告是,如果我们继续前进,我们只需要推动国家
pageChanged: function() {
// if the selected page changes, push a state (unless we are going backward)
if (this.poppedPage !== this.page) {
history.pushState(this.page, "Title", '#' + this.page);
}
}
在这里,所有这些都放在一起:
使用数据绑定会更好。这里的想法是使您的元素模型成为受驱动的,一种模型视图演示器(MVP)模式。模型由元素中的属性组成,视图由模板描述,演示者在脚本中。数据绑定允许我们从逻辑松散地耦合视图 让我们决定当前页面将由名为
page
的属性控制
然后,我们可以将UI设置为由页面
属性驱动:
<core-menu selected="{{page}}" valueattr="id">
...
</core-menu>
<core-animated-pages class="main" selected="{{page}}" valueattr="id" transitions="slide-from-right">
我们跟踪poppedPage
,以便区分前后。我们只想在前进的时候推动一个新的国家
现在,我们需要在历史记录中反映页面,因此我们需要在页面更改时推送状态。如上所述,一个警告是,如果我们继续前进,我们只需要推动国家
pageChanged: function() {
// if the selected page changes, push a state (unless we are going backward)
if (this.poppedPage !== this.page) {
history.pushState(this.page, "Title", '#' + this.page);
}
}
在这里,所有这些都放在一起:
请注意,
core activate
在每次单击某个项目时都会触发,即使该项目已被选中。请注意,core activate
在每次单击某个项目时都会触发