Да. Как вы указали, не используйте идентификаторы и селекторы идентификаторов в вашем JavaScript. Вместо этого используйте селекторы классов:
Например, по вашему мнению разметка :
<div class="container">Partial View content</div>
JS:
var $div = $('div.container');
// do something
Чтобы исключить возможность выбора других тегов с тем же именем класса, присвойте программному имени элементы в частичном представлении, которые используются только как дескриптор селектора, а не как класс CSS.
Несмотря на то, что поиск на основе идентификаторов является лучшим с точки зрения производительности, в этом случае имеет больше смысла использовать поиск на основе [tag + class], чтобы избежать конфликтов идентификаторов. Поиски на основе [tag + class] очень близки к селекторам идентификаторов по производительности.
Кроме того, вы можете добиться дальнейшего улучшения, ограничив область поиска:
<div class="container">Partial View content <span class="child">Child content </span></div>
var $span = $(span.child') // scope of lookup here is entire document
Однако, если вы знаете, что child
находится внутри контейнера div, вы можете ограничить область, сказав:
var $div = $('div.container').children('span.child'); // or just '.child'
Еще один совет - один раз выполнить поиск и использовать его повторно:
// less performant
function doSomething() {
// do something here
$('div.container').css('color', 'red');
// do other things
$('div.container').find('.child');
// do more things
$('div.container').click(function() {...});
}
// better
function doSomething() {
var $div = $('div.container');
// do something here
$div.css('color', 'red');
// do other things
$div.find('.child');
// do more things
$div.click(function() {...});
// or chaining them when appropriate
$('div.container').css('color', 'red').click(function() { ... });
}
Обновление: Рефакторинг поста ОП для демонстрации концепции:
<script type="text/javascript">
function SetProductTabContent(selectedTab, ctx) {
var $container = $("div.pv_productDescriptionContent", ctx);
// this will find only the immediate child (as you had shown with '>' selector)
$container.children('div').css('display', 'none');
switch (selectedTab) {
case '#tab-1':
$('div.pv_productDescriptionText', $container).css('display', 'block');
// or $container.children('div.pv_productDescriptionText').css('display', 'block');
break;
case '#tab-2':
$('div.pv_productSpecificationText', $container).css('display', 'block');
// or $container.children('div.pv_productSpecificationText').css('display', 'block');
break;
}
function SetUpMenuItems(ctx) {
// Get all the menu items within the passed in context (parent element)
var menuItems = $("div.pv_productMenu a", ctx);
// Select the first tab as default
menuItems.first().addClass("menuItemActive");
// Handle the look of the tabs, when user selects one.
menuItems.click(function () {
var item = $(this);
// Get content for the selected tab
SetProductTabContent(item.attr('href'), ctx);
menuItems.removeClass("menuItemActive");
item.addClass("menuItemActive");
return false;
});
}
</script>
<div style="" class="pv_productMenu">
<a href="#tab-1">
<div class="menuItemHeader">
Menu1</div>
</a><a href="#tab-2">
<div class="menuItemHeader">
Menu2
</div>
</a>
</div>
<div class="pv_productDescriptionContent">
<div class="pv_productDescriptionText" style="display: none;">
<%: Model.Product.Description %>
</div>
<div class="pv_productSpecificationText" style="display: none;">
<%: Model.Product.Description2%>
</div>
</div>
Примечание: Я удалил document.ready
упаковщик, так как он не будет срабатывать при загрузке частичного представления. Вместо этого я реорганизовал JS вашего View для вызова функции установки, а также передал область действия (что позволит избежать выбора других элементов div с тем же классом):
// Fetch content in the background
$.get(url, input, function (result, response) {
$('#dialogBox').html(result);
SetUpMenuItems($('#dialogBox'));
});
Очевидно, что вы можете изменить это дальше, как считаете нужным, в своем приложении. Я показал идею, а не окончательное решение.
- Если вы снова загрузите
#dialog
, они будут перезаписывать существующую разметку, поэтому дубликатов не будет.
- Если вы снова загрузите частичное представление в каком-либо другом контейнере, вы можете передать его в качестве контекста, и это помешает вам получить доступ к
children
из #dialog
- Я придумал этот произвольный префикс
pv_
для программных дескрипторов классов. Таким образом, вы можете определить имя класса для CSS или для использования в вашем скрипте.