UI 线程阻止 - 在 chrome 中动态禁用输入类型范围时,所有输入元素都将停止工作,并且似乎无法访问



当我尝试动态禁用页面上的输入范围时,页面上的所有其他输入元素在 chrome 中停止工作。

在这里,当我禁用#mySlider时,#chkBox#myButton变得无法访问并且不会触发相应的功能,甚至无法选中复选框。

我的镀铬版本:31.0.1650.63 m

小提琴演示>>

.HTML

 <input type="range" min="0" max="5" value="0" id="mySlider" onChange="checkMove(this)" />
 <input type="checkbox" value="one" id="chkBox" ><br/>
 <input type="button" id="myButton" value="Click Me" onClick="clickCheck();" />

脚本

function checkMove(elem) {
    var minVal = elem.value;
    if (minVal == 2) {
        elem.disabled = true;
    }
}
function clickCheck() {
    alert("hi")
}

1)因为这似乎是Chrome的错误。您可以通过模拟禁用的输入来破解它,只需将事件更改为onmouseup即可正常工作

/* CSS */
#range {
 position: relative    
}
#range.disabled .cover {
  display: block;
}
#range.disabled input {
 color: rgb(82,82,82);
}
.cover {
 width: 100%;
 height: 100%;
 background: transparent;
 z-index:5;
 position: absolute;
 top: -5px;
 bottom: 0;
 right:0;
 left: 0;
 display: none;
}
<!-- HTML -->
<label id="range">
  <input type="range" min="0" max="5" value="0" id="mySlider" onmouseup="checkMove(this)">
  <div class="cover"></div>
</label>
<input type="checkbox" value="one" id="chkBox">
<br/>
<input type="button" id="myButton" value="Click Me" onClick="clickCheck();" />

// JAVASCRIPT
var range = document.getElementById('range');
function checkMove (elem) {
    var minVal = elem.value;
    console.log(minVal)
    if (minVal >= 2) {
       range.className = 'disabled';
    }
}

工作小提琴

编辑:

2)破解此问题的另一种方法是避免动态禁用它,这是错误首先发生的时候。有两个range元素,一个disabled,一个abled。隐藏禁用的元素,同时从 abled 元素镜像值。
当您要禁用该元素时,请根据您的条件切换两者。
看看这个小提琴,开关是烟雾缭绕的,不明显。

<div id="range">
  <input type="range" min="0" max="5" value="0" id="mySlider" onchange="checkMove(this)">
  <input type="range" disabled min="0" max="5" value="0" id="altSlider">
</div>
// Javascript
var range = document.getElementById('range'),
    alt   = document.getElementById('altSlider');
function checkMove(elem) {
    var minVal = elem.value;
    alt.value = minVal;
    console.log(minVal)
    if (minVal == 2) {
      range.className = 'disabled';
    }
}

.CSS:

#range {
 position: relative;
 display: inline-block;
}
#range.disabled #altSlider {
  opacity: initial;
}
#range.disabled #mySlider {
 display: none;
}
#altSlider {
 opacity: 0;
}
#mySlider {
 z-index:5;
 position: absolute;
 top: 0;
 left: 0;
}

你为什么不尝试jquery选择器来禁用它Html 是 <input type="range" min="0" max="5" value="0" id="mySlider" /> <input type="checkbox" value="one" id="chkBox" ><br/> <input type="button" id="myButton" value="Click Me" />

jquery

   jQuery(document).ready(function($){    $("#mySlider").change(function(){       var val = parseInt($(this).val());       var maxrange= parseInt($(this).attr("max"));       if(val>=2){        $(this).val(2);        $(this).attr("disabled", "true");          }       })        $("#chkBox, #myButton").click(function(){          警报("它有效!        });     })    

我知道该错误已在chrome中修复...有一段时间了,但是在查看了原因并为该错误实施的修复程序后,我想如果需要,我会提供解决方法。

    // Replace the `elem.disabled = true;` with
    setTimeout(function(){ elem.disabled = true; },0); 

我们的想法是让浏览器退出其当前事件流,然后禁用输入元素。

问题本质上是一个 catch-22,禁用输入,然后在最后一个事件进入时更新范围,问题是该元素现在被禁用,因此永远不会收到这样的事件,这让浏览器挂起,并且它永远不会发布 UI。

有关更多详细信息,请查看上面评论链接中提供的补丁@PrasanthKC。

最新更新