我制作了一个成功的测试页面,它满足了我使用JavaScript ( jQuery )从网页中添加和删除内容的目标。
test
const foo = `<h1 id="title">Page-Foo-One</h1></div>
<p>Some text about foo foo foo.</p>
<h3 id="bar_link">Link to bar</h3>`;
const bar = `<h1 id="title">Page-Bar-Two</h1></div>
<p>Some text about bar bar bar.</p>
<h3 id="foo_link">Link to foo</h3>`;
$("#main").append(foo);
$("#main").on('click','h3#bar_link', function (){
console.log("Clicked bar_link");
$("#main").html("");
$("#main").append(bar);
}).on('click','h3#foo_link', function (){
console.log("Clicked foo_link");
$("#main").html("");
$("#main").append(foo);
}).on('click','h1#title', function (){
console.log("Clicked title");
$("#main").html("");
$("#main").append(foo);
})在这个简单的例子中,只有两种可能的结果,代码并不是太糟糕,但是我知道,如果这被夸大到一个完整的网站可能需要的内容(例如,每个页面上有几十个链接,每个页面都有不同的内容),那么.on(click)链就会变得非常复杂。
不然我怎么处理这种情况?
我知道我可以创建两个不同的.html文件( foo和bar ),并在它们之间设置简单的锚链接(即),并获得相同的效果,但我的目标是让外部源生成所显示的内容。
总的来说,我已经习惯了JavaScript编程,所以请指出我可以改进我正在做的事情的其他方法。
发布于 2018-02-07 01:25:21
那么,如果您在事件委托元素上使用了
h3的话,它就会处理剩下的页面或链接,这就解决了您的主要问题。$(document).on('click', 'h3', function() {
//do your thing
});由于您已经声明您有一个外部源来生成HTML,所以我将创建一个函数pageloader()来加载content.if,该函数将是一个ajax函数,用于使用mutache.js或任何其他方法获取内容或模板文件。
function pageLoader(){
$.ajax({
url:'path/to/content/',
//other params...
success:function(data){
//load content here
$("#map").html(data);
},
});
}但是,如果要在与您提供的场景相同的场景中使用该内容,则可以选择创建对象文字,将所有页面保存在一个位置,并从一个地方调用它们,并在调用时使用hasOwnProperty()以避免继承属性。
var pages={
pagename:function(){
//load the content of the page
},
pagename2:function(){
//load content of the page
}
}在这种情况下,您需要考虑的是要么将h3的D11保持与页面名称类似,要么在h3上定义一个数据属性并在那里添加页面名,因为我们将把该id/data-attribute作为参数传递给我们的pageLoader()函数,后者保存我们所有的页面并调用它们,因为我们将将对象的属性创建为文字页面名,然后加载它们。
下面是一个演示,尽管我不能创建一个ajax示例来演示我在第一节中谈到的内容,但我将使用object文字部分来创建一个演示,因为您实际关心的是链接的绑定,而不是如何加载内容,这一点已经讨论过了。因此,您可以使用您想要加载内容的任何方法更新pageLoader()函数。
function pageLoader(pagename) {
"use strict";
var pages = {
"foo": function() {
$("#main").html(`Page-Foo
Some text about foo foo foo.
Link to FooLink to barLink to ContactLink to About`);
},
"bar": function() {
$("#main").html(`Page-Bar
Some text about conatct bla bla bla.
Link to FooLink to barLink to ContactLink to About`);
},
"contact": function() {
$("#main").html(`Page-Contact
Some text about conatct bla bla bla.
Link to FooLink to barLink to ContactLink to About`);
},
"about": function() {
$("#main").html(`Page-about-Two
Some text about about about about.
Link to FooLink to barLink to ContactLink to About`);
}
};
//call the page
if (pages.hasOwnProperty(pagename)) {
pages[pagename].call(this);
}
}
//call on page load for the first time
$(document).ready(function() {
pageLoader("foo");
});
//use event delegation and bind the h3
$(document).on('click', 'h3', function() {
let pagename = $(this).prop("id");
pageLoader(pagename);
});希望这能有所帮助
发布于 2018-02-07 14:08:44
代码模式:
$("#main").html("");
$("#main").append(bar);可简化为:
$("#main").html(bar);一般来说,代码是清晰的,易于阅读,并且组织良好。备选方案中的所有决定都是合理和直接的。做最简单可行的事情是一种很好的方法,因为它避免了在必要的复杂性中增加不必要的复杂性。
使用模板文字而不是字符串可能是不必要的复杂性,因为模板特性不被使用。对模板文字的支持在浏览器中并不普遍。对于某些人来说,这一页可能会无缘无故地被打破。换句话说,使用模板文字而不是字符串可以在支持模板文字的浏览器中创建潜在的破页。
发布于 2018-02-07 16:49:18
本是正确的--代码大多清晰易懂,尽管存在一些冗余(例如,$("#main").append(foo);,甚至只有$("#main")也有很多冗余)。
我同意穆罕默德的观点,即事件委托是简化逻辑的好方法。
需要考虑的另一个方面是,每次$()与CSS选择器(例如$("#main"))一起出现时,都会执行DOM查找。通过将DOM引用存储在变量中,然后在代码的其余部分替换该变量,可以对此进行优化。有关此主题和其他优化的更多信息,请参见关于Cache的这个职位 DOM查找一节。我知道这篇文章是从抨击jQuery开始的,但是如果你的目标是使用它,那么一定要保留它。但是,您可能会考虑其他选择--参见youmightnotneedjquery.com。
所以你可以定义一个常量:
const mainElement = $("#main");然后在其他地方使用:
mainElement.append(foo);
mainElement.on('click','h3#bar_link', function (){
mainElement.html(bar); //take advice from Ben
});//... and so on ...此外,可以使用快捷.click()代替.on('click', handler)。然后,要使用事件委托,请检查事件目标的属性。例如,单击处理程序将接收具有事件属性的目标对象。可以使用.attr('id')获取该目标的id属性,该属性可用于确定单击了哪个元素,从而确定了要采取的操作。也可以使用.is()来确定目标是否匹配CSS选择器。
const foo = `Page-Foo-One
Some text about foo foo foo.
Link to bar`;
const bar = `Page-Bar-Two
Some text about bar bar bar.
Link to foo`;
const mainElement = $("#main");
mainElement.append(foo);
mainElement.click(function(clickEvent) {
const clickedId = $(clickEvent.target).attr('id');
if (clickedId) {
if (clickedId == 'bar_link') {
mainElement.html(bar);
} else {
mainElement.html(foo);
}
}
});我确实喜欢穆罕默德如何在pages中部署pageLoader()对象,以便将id选择器映射到HTML。但是,函数调用可以从映射中删除,并将对.html()的调用移到稍后的pageLoader()中的单个调用,如下所示:
var pages = {
"foo": `Page-Foo
Some text about foo foo foo.
Link to FooLink to barLink to ContactLink to About`,
...
};
if (pages.hasOwnProperty(pagename)) {
$('#main').html(pages[pagename]);
}这样,只有一个地方调用.html(),而不是每个对象的每个属性都调用一次。
https://codereview.stackexchange.com/questions/186921
复制相似问题