옵션을 동적으로 변경할 때 IE 선택 문제를 수정하는 방법
모두 같은 옵션을 선택할 수 있는 선택사항이 있습니다.그런 다음 다른 선택에서 선택한 옵션이 선택 항목에 나타나지 않도록 필터를 통해 이러한 옵션을 실행합니다.이 jsFiddle(IE 이외의 브라우저)을 참조해 주세요.기본적으로 선택 항목 중에서 동일한 옵션이 여러 번 선택되는 것을 방지하고 있습니다.
제가 한 일은 IE에 문제가 있습니다.IE에서 해당 바이올린을 엽니다(IE9에서만 시도했지만 이전 버전에서도 같은 문제가 있을 수 있습니다).마지막 선택을 AAA로 변경합니다.다른 3명이 모두 선택한 경우 표시되는 내용이 어떻게 변경되었는지 확인하십시오.이 모델의 모델은 변경되지 않았지만 IE는 옵션이 변경되었을 때 어떤 이유로든 쐐기를 박습니다.
첫 번째 질문은 이 기능에 대해 전반적으로 문제가 있습니까?이 코드는 Chrome과 FF에서 내가 원하는 대로 작동하는데, 내가 해서는 안 될 일을 하고 있는 걸까요?둘째, IE에서는 어떻게 하면 이 문제를 해결할 수 있을까요?모델을 클리어하고 리셋하는 타임아웃을 시도했지만 눈에 띄는 것이 눈에 띄었다.이 문제에 대한 효과적이고 깔끔한 해결 방법이 있는지 궁금합니다.
어떤 도움이라도 주시면 감사하겠습니다.감사해요.
--갱신--
이것은 아래 A. S. Ranjan의 솔루션을 사용하여 버전 1.3.3에서 Angular 자체에서 수정되었습니다.1.3.3의 새로운 바이올린 보기:http://jsfiddle.net/m2ytyapv/
//dummy code so I can post the edit
요전 날 밤에도 같은 문제를 경험했고, 생각할 수 있는 모든 것을 던져 본 결과 IE는 선택 항목을 사용할 때 필터 업데이트를 처리하고 싶지 않다는 결론에 도달했습니다.
내 솔루션은 다음과 같이 선택 항목을 변경하는 것입니다.
<select class="selectList" ng-repeat="currId in selectedIds" ng-model="selectedIds[$index]" ng-options="currOption.id as currOption.value for currOption in myObj | myfilter:selectedIds:$index" data-ng-change="fixIE()"></select>
이제 클래스 및 ng-change가 있습니다.그런 다음 컨트롤러에서 다음과 같은 재미있는 코드를 실행합니다.
$scope.fixIE = function(){
//code to check if IE so the other browsers don't get this ugly hack.
var selectLists = document.querySelectorAll(".selectList");
for(var x = 0;x < selectLists.length; x++){
selectLists[x].parentNode.insertBefore(selectLists[x], selectLists[x]);
}
};
이 기능은 요소를 DOM에서 분리하여 같은 위치로 교체하는 것입니다.여기 작동하는 바이올린 jsFiddle이 있습니다.
javascript를 사용하지 않은 다른 솔루션으로는 선택 항목 표시/가시성 전환 등이 있습니다.zIndex가 이동되었습니다.확실히 고쳐진 건 이 코드 조각뿐이었어요
내가 해결했어.
IE8에서 렌더링을 트리거하려면 옵션 목록을 추가 및 삭제해야 합니다.
http://kkurni.blogspot.com.au/2013/10/angularjs-ng-option-with-ie8.html
/**
* Fix for IE select menus getting stuck when their underlying list changes.
* Original code: http://kkurni.blogspot.com.au/2013/10/angularjs-ng-option-with-ie8.html
*
* Set the `ie-select-fix` attribute to the model expression that should trigger the list to re-render.
*
* @example <select ng-model="modelValue" ie-select-fix="itemList" ng-options="item.label for item in itemList">
*/
app.directive('ieSelectFix', ['$document',
function($document) {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attributes, ngModelCtrl) {
var isIE = $document[0] && $document[0].attachEvent;
if (!isIE) return;
var control = element[0];
//to fix IE8 issue with parent and detail controller, we need to depend on the parent controller
scope.$watch(attributes.ieSelectFix, function() {
// setTimeout is needed starting from angular 1.3+
setTimeout(function() {
//this will add and remove the options to trigger the rendering in IE8
var option = document.createElement("option");
control.add(option,null);
control.remove(control.options.length-1);
}, 0);
});
}
}
}
]);
드디어 내 요구에 맞는 해결책을 찾아냈어.기본적으로 선택한 인덱스의 옵션에 대한 텍스트가 해당 위치에 있던 이전 문자열을 가리키고 있는 것으로 보입니다.이 텍스트를 변경하면 문자열 및/또는 참조가 업데이트됩니다.저는 이렇게 했어요.
angular.forEach($("select"), function (currSelect) {
currSelect.options[currSelect.selectedIndex].text += " ";
});
다음은 업데이트된 바이올린입니다.http://jsfiddle.net/H48sP/35/
앱에는 에, 저는 이 선택지가 어디에 .element.find("select")
$("select")
요소의 선택 범위를 제한합니다.텍스트는 강제로 새로 고침되므로 모든 다이제스트 사이클이 실행된 후 올바르게 표시됩니다.
는, 「」를 경우가 있습니다.$timeout
예를 들어 바이올린을 켜거나 나중에 문제가 발생하면 옵션텍스트에 추가된 여분의 공간을 삭제해야 할 수 있습니다.
select Direct in angular.js의 렌더링 기능에서 다음 부분(굵은 글씨로 **로 표시)을 몇 줄 추가하면 문제가 없습니다.각진 패치 외에 다른 방법이 없는지 알아보고 있습니다.아래에 제시된 JS 또는 for?
if (existingOption.label !== option.label) {
lastElement.text(existingOption.label = option.label);
**lastElement.attr('label', existingOption.label);**
}
그리고.
(element = optionTemplate.clone())
.val(option.id)
.attr('selected', option.selected)
.text(option.label);
**element.attr('label', option.label);**
문제는 IE에서 라벨이 공백일 경우 HTMLOptionElement의 라벨 속성이 텍스트 속성과 동일하지 않다는 것입니다.
이는 화면 로드 후 다음 코드를 추가하여 FF와 IE의 웹 콘솔을 보고 차이를 확인함으로써 확인할 수 있습니다.라벨이 텍스트로 설정되어 있는 마지막 행의 코멘트를 해제하면 정상적으로 동작합니다.또는 위와 같이 angular.js에 패치를 적용합니다.
// This is an IE fix for not updating the section of dropdowns which has ng-options with filters
angular.forEach($("select"), function (currSelect) {
console.log("1.text ", currSelect.options[currSelect.selectedIndex].text);
console.log("1.label ", currSelect.options[currSelect.selectedIndex].label);
//console.log("1.innerHTML ", currSelect.options[currSelect.selectedIndex].innerHTML);
//console.log("1.textContent ", currSelect.options[currSelect.selectedIndex].textContent);
//console.log("1.cN.data ", currSelect.options[currSelect.selectedIndex].childNodes[0].data);
//console.log("1.cN.nodeValue ", currSelect.options[currSelect.selectedIndex].childNodes[0].nodeValue);
//console.log("1.cN.textContent ", currSelect.options[currSelect.selectedIndex].childNodes[0].textContent);
//console.log("1.cN.wholeText ", currSelect.options[currSelect.selectedIndex].childNodes[0].wholeText);
//console.log("1. ", currSelect.options[currSelect.selectedIndex], "\n");
//currSelect.options[currSelect.selectedIndex].label = "xyz";
//currSelect.options[currSelect.selectedIndex].label = currSelect.options[currSelect.selectedIndex].text;
});
이 문제는 필터에 의해 반환되는 옵션의 순서와 관련이 있는 것 같습니다.을 '다음에 하다'로 A
하다IE에 문제가 있는 것 같은 것은, 선택한 옵션이 장소를 변경하는 것입니다. 번째 상자 " " " " 。C
는 음음음음 is is 、 ' is 、 is is 、 ' is is is is is is is is is 。A, B, C, D
선택한 옵션이 세 번째 옵션입니다.네 번째 선택 상자를 변경할 때G
로로 합니다.A
필터는 첫의 옵션을 "알겠습니다"로 B, C, D, G
선택한 옵션이 두 번째 옵션이 되어 IE에 문제가 생깁니다.이것은 Angular의 버그일 수도 있고 IE의 이상한 동작일 수도 있습니다.선택한 요소가 항상 필터링된 옵션에서 첫 번째 옵션이 되도록 함으로써 이 문제를 해결할 수 있는 포크를 만들었습니다.
var newOptions = [],selected;
angular.forEach(allOptions, function (currentOption) {
if (!isIdInUse(selectedIds, currentOption.id)){
newOptions.push(currentOption);
}else if(currentOption.id == selectedIds[parseInt(index)]){
selected = currentOption;
}
});
if(selected){newOptions.unshift(selected);}
http://jsfiddle.net/XhxSD/ (구)
업데이트:
디버깅을 좀 해봤는데 IE에서 문제가 되는 라인을 찾았는데 왜 그런 건지 모르겠어요.렌더링 버그나 뭐 그런 것 같아요.옵션을 재배치할 필요가 없는 다른 회피책을 만들었습니다.이것은 선택한 요소의 변경을 감시하는 지시입니다.변경이 검출되면 옵션이 추가되고 즉시 삭제됩니다.
.directive('ieSelectFix',function($timeout){
return {
require:'select',
link: function (scope, element) {
var isIE = document.attachEvent;
if(isIE){
$timeout(function(){
var index = element.prop('selectedIndex'), children = element.children().length;
scope.$watch(function(){
if(index !== element.prop('selectedIndex') || children !== element.children().length){
index = element.prop('selectedIndex');
children = element.children().length;
var tmp =angular.element('<option></option>');
element.append(tmp);
tmp.remove();
}
})
});
}
}
}
});
ng-repeats 내의 요소를 선택하려면 ie-select-fix를 추가합니다.
<div ng-app="myApp" ng-controller="MyCtrl">
<select ie-select-fix ng-repeat="currId in selectedIds" ng-model="selectedIds[$index]" ng-options="currOption.id as currOption.value for currOption in myObj | myfilter:selectedIds:$index"></select><br>
{{selectedIds}}
</div>
http://jsfiddle.net/VgpyZ/ (신규)
IE에서 셀렉트 버그와 같은 버그를 발견했습니다.이 버그는 DOM 노드를 복제한 결과입니다.
SELECT like(jQuery 타를를) :
$select = $template.clone();
그 후 다음을 수행합니다.
$select.html('<option>111</option>');
위에서 설명한 바와 같이 버그가 발생합니다.
하지만, 만약 당신이
$select = $('< div />').html( $template ).html();
버그가 발생하지 않았습니다:)
오, 난 지옥으로 갈 거야 다음 조언 때문에...!
나는 이 제안들을 시도해 보았지만, 어느 것도 나에게 통하지 않았다.
실제로는 Angular를 사용하여 여러 개의 옵션을 각각 선택한 컨트롤에 입력했습니다.
<select class="cssMultipleSelect" multiple="multiple" ...>
때때로 Angular가 이러한 컨트롤을 채우고 새로운 데이터가 나타나지만 IE에서는 모든 옵션을 표시하기 위해 위아래로 스크롤할 수 없습니다.
그러나 F12를 눌러 폭을 수정하고 원래 너비로 되돌리면 IE가 다시 활성화되어 값 목록에서 위아래로 스크롤할 수 있습니다.
그래서 Angular가 컨트롤을 채우고 나서1초 정도 지나면 이 명령을 내릴 수 있었습니다.
function RefreshMultipleSelectControls()
{
// A dodgy fix to an IE11 issue.
setTimeout(function () {
$(".cssMultipleSelect").width("");
}, 1500);
setTimeout(function () {
$(".cssMultipleSelect").width(298);
}, 1600);
}
(내가 이거 위험한 해결책이라고 했잖아)
외, IE11에서는, 「IE11」이라고 하는 에 주의해 주세요.navigator.appName
에서 will will will 、 will will 。NETSCAPE
)MSIE
★★★★★★★★★★★★★★★★★」Microsoft Internet Explorer
따라서 코드가 IE 또는 적절한 브라우저에서 실행 중인지 테스트할 때는 주의하십시오.
경고했잖아요..!!
IE9이 인덱스에 문제가 있는 것 같습니다.두 번째 예를 들어 다음 코드로 변경합니다.
var hwcalcModule = angular.module('ie9select', []);
function AnimalCtrl($scope) {
$scope.categories = [{
name: "Cats",
kinds: ["Lion", "Leopard", "Puma"]
}, {
name: "Dogs",
kinds: ["Chihua-Hua", " Yorkshire Terrier", "Pitbull"]
}];
$scope.animals = [{
category: $scope.categories[1],
kind: $scope.categories[1].kinds[1]
}];
$scope.changeCategory = function (animal) {
console.log(animal.category.name);
var name = animal.category.name;
var index = 0;
angular.forEach($scope.categories, function (currentOption) {
console.log(currentOption.name);
if (name == currentOption.name)
{
console.log(index);
$scope.animals = [{
category: $scope.categories[index],
kind: $scope.categories[index].kinds[0]
}];
}
index++;
});
}
}
http://jsfiddle.net/seoservice/nFp62/10/
Mathew Berg의 답변 라인에서 Angular를 사용하여 작동하도록 수정했습니다.JS 지시:
angular.module('select',[]).directive("select", function() {
return {
restrict: "E",
require: "?ngModel",
scope: false,
link: function (scope, element, attrs, ngModel) {
if (!ngModel) {
return;
}
element.bind("change", function() {
//Fix for IE9 where it is not able to properly handle dropdown value change
//The fix is to rip out the dropdown from DOM and add it back at the same location
if (isIE9){
this.parentNode.insertBefore(this, this); //this rips the elements out of the DOM and replace it into the same location.
}
})
}
}
});
이 방법으로 수정은 모든 사용자에게 적용됩니다.select
기존 HTML 마크업을 변경할 필요가 없습니다.또한 설정할 IE 버전을 검출하기 위해 다음 방법을 사용했습니다.isIE9
에 가변적인.true
:
var Browser = {
IsIE: function () {
return navigator.appVersion.indexOf("MSIE") != -1;
},
Navigator: navigator.appVersion,
Version: function() {
var version = 999; // we assume a sane browser
if (navigator.appVersion.indexOf("MSIE") != -1)
// bah, IE again, lets downgrade version number
version = parseFloat(navigator.appVersion.split("MSIE")[1]);
return version;
}
};
var oldIE = false; //Global Variable
var isIE9 = false; //Global Variable
if (Browser.IsIE && Browser.Version() <= 8) {
oldIE = true;
}
if (Browser.IsIE && Browser.Version() == 9) {
isIE9 = true;
}
범위를 바꿔야 했어요.$watch to scope.$watch Collection은 위의 @kurni 솔루션을 IE9용으로 만듭니다.IE9에서 선택 옵션을 변경할 때 렌더링하는 데 문제가 있는 다른 사용자를 돕고 싶을 뿐입니다.
일부 속성을 변경하면 렌더링이 업데이트되고 동기화됩니다.무해한 변경은 다음과 같은 설정을 하는 것일 수 있습니다.selectedIndex
자신의 값에 기인합니다.
function fixIEselect() {
for (var nForm = 0; nForm < document.forms.length; ++nForm) {
var form = document.forms[nForm];
var children = form.children;
for (var nChild = 0; nChild < children.length; ++nChild) {
var child = children.item(nChild);
if (child.tagName == "SELECT") {
alert("Fixed: " + child.name);
child.selectedIndex = child.selectedIndex; // dummy nop but not
}
}
}
}
fixIEselect();
다이내믹 옵션이 추가된 후 제어 재렌더링을 시행하는 방법은 비용이 적게 듭니다.따라서 더미 요소를 드롭다운에 삽입/삭제하는 대신 컨트롤 렌더링을 일으키는 CSS 스타일을 리셋할 수 있습니다.
selElement.style.zoom = selElement.style.zoom ? "" : 1;
IE 픽리스트 문제에 대한 해결 방법이 있습니다.
수정 전 : http://plnkr.co/edit/NGwG1LUVk3ctGOsX15KI?p=preview
수정 후 : http://plnkr.co/edit/a7CGJavo2m2Tc73VR28i?p=preview
$("select").click(function(){
$(this).append('<option></option>');
$(this).find('option:last').remove();
});
방금 돔에서 선택 항목을 다시 렌더링하는 더미 옵션을 추가하고 삭제했습니다.너에게 효과가 있다는 것을 내게 알려줘
언급URL : https://stackoverflow.com/questions/12942681/how-to-fix-ie-select-issue-when-dynamically-changing-options
'programing' 카테고리의 다른 글
@RibbonClient와 @LoadBalanced의 차이점 (0) | 2023.04.02 |
---|---|
WordPress에서 포스트슬러그를 얻는 방법 (0) | 2023.04.02 |
Mongo에서 "not null"을 어떻게 조회합니까? (0) | 2023.04.02 |
Node.js 및 Express를 사용한 간단한 API 호출 (0) | 2023.04.02 |
Word Press가 제대로 프로그래밍되지 않은 것으로 간주되는 이유는 무엇입니까? (0) | 2023.04.02 |