#jquery #forms #dom #internet-explorer-8 #cross-browser
#jquery #формы #dom #internet-explorer-8 #кроссбраузерный
Вопрос:
Проблема
Следующие скрипты делают именно то, что мне требуется, во всех протестированных браузерах, кроме IE8, где кнопка удаляется, не заменяя ее чем-либо.
Предыстория
Я работал над методом замены входных данных типа отправки входными данными типа изображения с помощью jQuery.
Сначала у меня было следующее, которое работает с FF и webkit:
marker = jQuery('<span class="marker"></span>').insertBefore('input#SearchButton');
jQuery('input#SearchButton').detach().attr('type', 'image').attr('src',theme_folder '/style/images/search_button.png').insertAfter(marker);
marker.remove();
Но это не удается во всех версиях 6 , если IE (кнопка удаляется, но не заменяется изображением), поэтому я разработал следующий скрипт для браузеров IE:
marker = jQuery('<span class="marker"></span>').insertBefore('input#SearchButton');
new_search = jQuery('<input id="SearchButton" value="Search" name="Searchbutton" type="image" src="' theme_folder '/style/images/search_button.png' '" />')
jQuery(new_search).insertAfter('input#SearchButton');
jQuery('input#SearchButton').remove();
marker.remove();
Я использую условные обозначения HTML для фильтрации потока трафика в соответствующем скрипте, поэтому все это выглядит следующим образом:
<!--[if IE]>
<script>
marker = jQuery('<span class="marker"></span>').insertBefore('input#SearchButton');
new_search = jQuery('<input id="SearchButton" value="Search" name="Searchbutton" type="image" src="' theme_folder '/style/images/search_button.png' '" />')
jQuery(new_search).insertAfter('input#SearchButton');
jQuery('input#SearchButton').remove();
marker.remove();
</script>
<![endif]-->
<![if !IE]>
<script>
marker = jQuery('<span class="marker"></span>').insertBefore('input#SearchButton');
jQuery('input#SearchButton').detach().attr('type', 'image').attr('src',theme_folder '/style/images/search_button.png').insertAfter(marker);
marker.remove();
</script>
<![endif]>
Ответ №1:
В IE type
свойством input
элемента является однократная запись. Вы не сможете изменить его после того, как вы установили его в первый раз. (В attr
документации есть предупреждение об этом.)
Ваш единственный реальный вариант обеспечения совместимости с IE — это фактически заменить элемент на новый с тем же id
значением. Очевидно, что это влияет на обработчики событий (любые, которые вы прикрепили к старому элементу, не будут прикреплены к новому), поэтому вы можете захотеть использовать delegate
(или глобальную версию, live
) вместо того, чтобы прикреплять обработчики непосредственно к рассматриваемому элементу.
Обновить: А, я вижу, вы написали какой-то код для этого. Проблема с этим кодом заключается в том, что вы временно создаете недопустимый документ (в нем есть два разных элемента с одинаковым id
значением), а затем ищете элемент по этому дубликату id
. Будет хорошо, если вы просто возьмете элемент заранее:
// Get the old search button
old_search = jQuery('input#SearchButton');
// Create the new search button
new_search = jQuery('<input id="SearchButton" value="Search" name="Searchbutton" type="image" src="' theme_folder '/style/images/search_button.png' '" />')
// Insert the new one after the old (temporarily creates an invalid document)
jQuery(new_search).insertAfter(old_search);
// Now remove the old one
old_search.remove();
(Для этого вам не нужен маркер, поэтому я удалил его из приведенного выше.)
Но вы можете вместо этого рассмотреть использование replaceWith
:
jQuery('input#SearchButton').replaceWith(
'<input id="SearchButton" value="Search" name="Searchbutton" type="image" src="' theme_folder '/style/images/search_button.png' '" />'
);
Вот упрощенный replaceWith
пример (также демонстрирующий delegate
):
HTML:
<div id='container'>
<p>This button is in the container, and so clicks
on it will convert it back and forth between
<code>input type='button'</code> and
<code>input type='image'</code>.</p>
<input type='button' value='Click Me'>
</div>
<div>
<p>This button is <strong>not</strong> in the
container, and so clicks on it aren't processed.</p>
<input type='button' value='Click Me'>
</div>
JavaScript:
$('#container').delegate('input', 'click', function() {
if (this.type === "button") {
$(this).replaceWith(
"<input type='image' src='" imageSrc "'>"
);
}
else {
$(this).replaceWith(
"<input type='button' value='Click Me'>"
);
}
});
У кнопки там нет id
, но это совершенно нормально, если она есть:
HTML:
<div id='container'>
<input type='button' id='theButton' value="Click Me, I'll Change">
<br><input type='button' value="Click Me, I Won't Change">
</div>
JavaScript:
$('#container').delegate('#theButton', 'click', function() {
if (this.type === "button") {
$(this).replaceWith(
'<input id="theButton" type="image" src="' imageSrc '">'
);
}
else {
$(this).replaceWith(
'<input id="theButton" type="button" value="Click Me, I'll Change">'
);
}
});
Не по теме: Поскольку вам все равно придется заменить элемент для поддержки IE, я бы рекомендовал иметь только одну копию кода и использовать ее во всех браузерах. Замена элемента обходится не так дорого, даже в браузерах, которые позволяют его изменять.
Комментарии:
1. Обратите внимание на то, что вы отклонились от темы, мне нужно изменить много кнопок, а скрипт, отличный от IE, работает быстрее.
2. Добавит ли делегат щелчок к элементу body? Я не совсем понимаю это!
3. @Mild Fuzz: Правильно. Это удобный синтаксис jQuery для общего метода, называемого делегированием событий . Если они не остановлены, большинство событий DOM перемещаются от элемента, на котором они фактически произошли, к родительскому элементу этого элемента, затем к родительскому элементу родительского элемента и т.д. Итак, если есть контейнер для всех этих кнопок, вы можете использовать его (вместо «body»). Нажатия будут начинаться с кнопок, но переходить в контейнер, где они будут обработаны. jQuery обработает проверку того, что событие началось с элемента, соответствующего указанному вами селектору, и вызовет вашу функцию, если это так.
4. @Mild Fuzz: Я обновил примеры в конце, надеюсь, они более понятны.
Ответ №2:
Вы не можете динамически изменять тип элемента ввода в Internet Explorer. Вы должны удалить старый ввод и добавить новый ввод
Комментарии:
1. это то, что делает скрипт только для IE