в jQuery "на('Нажмите')" для переключения содержимого веб-страницы


Я сделал успешную тестовую страницу, которая удовлетворяет мои цели с использованием JavaScript ( jQuery в частности ), чтобы добавить и удалить контент с веб-страницы.

<!doctype html>
<head>
<title>test</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>

<body>
<div id="main"></div>
<script>

    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);
    })
</script>
</body>
</html>

На этом простом примере, где только два возможных исхода существует код не так уж плохо, чтобы смотреть на, но я знаю, что если это были взвинчены до того, что весь сайт может повлечь за собой (например, десятки ссылок на каждой странице, в каждом указав разного содержания) в .on(click) цепочка будет сделать очень сложно.

Как еще я мог поступить в этой ситуации?

Я знаю, что я мог бы просто сделать два разных .HTML-файлы ( foo и Bar ) и установки простой якорные ссылки (т. е. <a href="...">) между ними и получить тот же эффект, но моя цель-иметь внешнего источника генерировать контент, который отображается.

Я привыкаю к JavaScript-программирования в целом, поэтому, пожалуйста, отметить, другими способами я могу улучшить то, что я делаю.



242
2
задан 6 февраля 2018 в 03:02 Источник Поделиться
Комментарии
3 ответа

Ну если вы используете event delegation на <h3> элемент вам не нужно заботиться, сколько страниц или ссылок просто привязать его один раз на странице загрузки, и он будет заботиться об остальном при условии ссылки на основе h3 после вашего примера, так что решает ваша главная проблема.

$(document).on('click', 'h3', function() {
//do your thing
});

Поскольку вы указали, что у вас есть внешний источник для генерации HTML я хотел создать функцию pageloader() для загрузки содержимого.если это будет в AJAX функции, чтобы получить контент или шаблон файла, используя mutache.js или любое другое.

function pageLoader(){
$.ajax({
url:'path/to/content/',
//other params...
success:function(data){
//load content here
$("#map").html(data);
},
});
}

Но если этот контент должен быть использован в тот же сценарий, что вы предоставили
тогда у вас есть возможность создания object literals для учета всех страницах в одном месте и, называя их в одном месте и при вызове использовать hasOwnProperty() чтобы избежать унаследованные свойства.

var pages={
pagename:function(){
//load the content of the page
},
pagename2:function(){
//load content of the page
}
}

В этом случае то, что вам нужно, чтобы рассмотреть, что вы либо держите id из h3 похожие страницы имя или определение данных-атрибута на h3 и добавить название страницы там, как мы бы мимоходом, что id/data-attribute в качестве параметра наш pageLoader() функция, которая хранит все наши страницы и называет их слишком потому что мы будем создавать свойства объекта литерал в разделе Имя и затем загрузить их.

Ниже демонстрация, хотя я не могу создать AJAX для примера, чтобы показать то, о чем говорил в первой части, я буду использовать литерал объекта Раздел для создания демо с вашего фактического беспокойства является обязательным для одной и не в том, чтобы загрузить контент, и это транслируется. Так что вы можете обновить pageLoader() функция с какой бы подход вы хотите загрузить контент



function pageLoader(pagename) {
"use strict";
var pages = {

"foo": function() {
$("#main").html(`<h1 id="title">Page-Foo</h1></div>
<p>Some text about foo foo foo.</p>
<h3 id="foo">Link to Foo</h3><h3 id="bar">Link to bar</h3><h3 id="contact">Link to Contact</h3><h3 id="about">Link to About</h3>`);
},
"bar": function() {
$("#main").html(`<h1 id="title">Page-Bar</h1></div>
<p>Some text about conatct bla bla bla.</p>
<h3 id="foo">Link to Foo</h3><h3 id="bar">Link to bar</h3><h3 id="contact">Link to Contact</h3><h3 id="about">Link to About</h3>`);
},
"contact": function() {
$("#main").html(`<h1 id="title">Page-Contact</h1></div>
<p>Some text about conatct bla bla bla.</p>
<h3 id="foo">Link to Foo</h3><h3 id="bar">Link to bar</h3><h3 id="contact">Link to Contact</h3><h3 id="about">Link to About</h3>`);
},
"about": function() {
$("#main").html(`<h1 id="title">Page-about-Two</h1></div>
<p>Some text about about about about.</p>
<h3 id="foo">Link to Foo</h3><h3 id="bar">Link to bar</h3><h3 id="contact">Link to Contact</h3><h3 id="about">Link to About</h3>`);

}
};

//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);
});


<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="main"></div>



Надеюсь, что это помогает

1
ответ дан 7 февраля 2018 в 01:02 Источник Поделиться

Шаблон код:

$("#main").html("");
$("#main").append(bar);

может быть упрощен до:

$("#main").html(bar);

В общем, код, ясный, легко читаемый и хорошо организованный. Все решения среди альтернатив являются обоснованными и прямой вперед. Делаем самое простое, что может сработать-это хороший подход, поскольку он позволяет избежать добавления ненужных сложности необходимой сложности.

Использование шаблона литералы, а не строками, могут быть ненужные сложности, потому что шаблонов не используется. Поддержка шаблона литералы не является универсальным среди браузеров. Страница может сломаться без причины для некоторых людей. Иначе говоря, используя шаблон литералы, а не строк создает потенциал сломанных страниц без увеличения в браузере, который поддерживает литералы шаблона.

2
ответ дан 7 февраля 2018 в 02:02 Источник Поделиться

Бен правильно - код в основном ясно и легко читается, несмотря на некоторую избыточность (например, $("#main").append(foo);и даже просто $("#main") имеет много вхождений).

Я согласен с Мухаммадом , что событие делегация является отличным способом, чтобы упростить логику.

Еще один аспект, чтобы рассмотреть, что каждый раз $() появляется с CSS-селектору (напр. $("#main")) в дом поиск выполняется. Это может быть оптимизировано хранение, ссылающиеся на дом в переменной, а затем заменить эту переменную на всей остальной части кода. Для больше на этой теме и другие оптимизации, см. раздел Кэш-Дом поиск на этот пост. Я знаю, что пост начинается трепка на 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') и это может использоваться, чтобы определить, какой элемент был выбран и, соответственно, какие действия предпринять. Или .is() может использоваться, чтобы определить, если цель соответствует CSS-селектору.



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>`;
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);
}
}
});


<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div id="main"></div>


Мне нравится, как Мухаммад выложил pages объект в pageLoader() на карте идентификаторов селекторы в HTML-строк. Однако вызовы функций могут быть удалены из отображения, и двигаться, что вызов .html() на один вызов позже в pageLoader()как фрагмент ниже:

var pages = {
"foo": `<h1 id="title">Page-Foo</h1></div>
<p>Some text about foo foo foo.</p>
<h3 id="foo">Link to Foo</h3><h3 id="bar">Link to bar</h3><h3 id="contact">Link to Contact</h3><h3 id="about">Link to About</h3>`,
...
};

if (pages.hasOwnProperty(pagename)) {
$('#main').html(pages[pagename]);
}

Так что есть только одно место .html() называется, а не один раз для каждого объекта.

1
ответ дан 7 февраля 2018 в 04:02 Источник Поделиться