programing

onclick () 및 onblur () 주문 문제

bestprogram 2023. 9. 19. 21:21

onclick () 및 onblur () 주문 문제

사용자 정의 드롭다운 메뉴를 불러오는 입력 필드가 있습니다.저는 다음 기능을 원합니다.

  • 사용자가 입력 필드 밖의 아무 곳이나 클릭하면 메뉴를 제거해야 합니다.
  • 보다 구체적으로 사용자가 메뉴 내의 div를 클릭하면 메뉴를 제거하고, 어떤 div를 클릭했는지에 따라 특별한 처리가 이루어져야 합니다.

구현 방법은 다음과 같습니다.

에 가 .onblur() (하는 트)하여)를innerHTML사용자가 입력 필드 밖에서 클릭할 때마다 빈 문자열로 이동합니다.e을 가지고 있습니다.onclick()특수 처리를 실행하는 이벤트입니다.

.onclick() 입력 필드가onblur()를 를 포함한합니다.onclick()s!

를 해결했습니다.onclick()안으로onmousedown()그리고.onmouseup()이벤트 및 마우스 아래에 글로벌 플래그를 설정하는 것은 이 답변에서 제안한 것과 유사합니다.왜냐면onmousedown() 앞에 을 지피다onblur()는 , , 에 입니다.onblur()메뉴 디브 중 하나를 클릭한 경우, 화면의 다른 곳이 클릭한 경우.다에서 .onblur()고다를 .onclick()발사할 수 있습니다. 이 시점에서 안전하게 메뉴를 삭제할 수 있습니다.

좀 더 우아한 해결책이 있을까요?

코드는 다음과 같습니다.

<div class="menu" onmousedown="setFlag()" onmouseup="doProcessing()">...</div>
<input id="input" onblur="removeMenu()" ... />

var mouseflag;

function setFlag() {
    mouseflag = true;
}

function removeMenu() {
    if (!mouseflag) {
        document.getElementById('menu').innerHTML = '';
    }
}

function doProcessing(id, name) {
    mouseflag = false;
    ...
}

저도 당신과 똑같은 문제가 있었습니다, 제 UI는 당신이 설명한 것과 똑같이 디자인되었습니다.했습니다.onClickn가 경우onMouseDown 건 도 안 했어요., 요.onMouseUp가 없습니다 없이 이벤트 에 따라 를 해결했습니다이것은 저의 추가적인 작업 없이 브라우저가 이러한 이벤트 핸들러의 우선 순위에 따라 자동으로 재주문하도록 함으로써 문제를 해결했습니다.

이것이 당신에게도 효과가 없었을 이유가 있습니까?

onClick다로 는 안 .onMouseDown.

이 접근 방식은 다소 효과가 있지만, 두 가지는 사용자의 눈에 다른 기대를 가지고 있는 근본적으로 다른 이벤트입니다.사용.onMouseDownonClick이 경우 소프트웨어의 예측 가능성을 망칠 수 있습니다.따라서 두 이벤트는 상호 교환할 수 없습니다.

설명하기: 실수로 버튼을 클릭한 경우 사용자는 마우스 클릭을 누르고 요소 외부로 커서를 끌어서 마우스 버튼을 놓으면 궁극적으로 아무런 조치도 취하지 않습니다.onClick이렇게 합니다.onMouseDown를 사용하면 사용자가 마우스를 누르고 있을 수 없으며 대신 사용자가 사용할 수 없는 작업을 즉시 트리거합니다.onClick는 컴퓨터에서 행동을 유발할 수 있는 기준입니다.

에 를 걸어보세요.event.preventDefault()onMouseDown이벤트성의onMouseDown는 기본적으로 블러 이벤트를 발생시키고, 다음과 같은 경우에는 발생하지 않습니다.preventDefault라고 합니다.그리고나서,onClick부름을 받을 기회가 있을 겁니다블러 이벤트는 다음과 같은 경우에만 발생합니다.onClick.

은.onClick입니다의 입니다.onMouseDown그리고.onMouseUp다됩니다.

여기 예시가 있습니다.

로 대체합니다. 그러면 포커스가 텍스트 상자 안에 있을 때 이 이벤트가 트리거됩니다.

로 바꿉니다.텍스트 상자에서 포커스를 빼는 순간 온블러가 실행됩니다.

이것이 당신에게 필요한 것 같네요.

업데이트:

focus -->onblur에서 적용할 클래스를 제거하고 focus에서 실행할 클래스를 추가합니다.

그리고.

blur에서 함수를 실행할 때-->Focus에서 적용할 클래스를 제거하고 blur에서 실행할 클래스를 추가합니다.

플래그 변수가 필요 없다고 봅니다.

업데이트 2:

마우스 아웃 및 마우스 오버에서 이벤트를 사용할 수 있습니다.

on mouse over-커서가 위에 있을 때를 탐지합니다.

on mouse out- 커서가 떠날 때를 탐지합니다.

onFocus/onBlur거품이 생기지 않는 사건들입니다.그러나 거품을 일으키는 초점 사건들이 있습니다.는.focusin그리고.focusout.

이제 해결 방법: 을 모두 하고 입력과 드롭다운을 모두 분할 요소로 포장하고 설정합니다를 설정합니다.tabindex 수 / 순서에는 ) 록 /록).합니다에 합니다.focusin그리고.focusout이 디브에게.그리고 다가 .focusin event 다)

이제 입니다( 합니다)를 합니다).focusout/blur절대 발사하지 않고 드롭다운이 열려 있습니다.)

아래 코드 조각을 사용하여 이 작업을 시도해 볼 수 있습니다. (드롭다운은 초점 손실 시에만 닫힙니다. 단, 드롭다운을 클릭할 때 닫으려면 JS의 한 줄에 대한 코멘트를 해제하십시오.)

const container = document.getElementById("container")
const dropDown = document.getElementById("drop-down")

container.addEventListener("focusin", (event) => {
  dropDown.classList.toggle("hidden", false)
})
container.addEventListener("focusout", (event) => {
  dropDown.classList.toggle("hidden", true)
})
dropDown.addEventListener("click", (event) => {
  console.log("I - the drop down - have been clicked");
  //dropDown.classList.toggle("hidden", true);
});
.container {
  width: fit-content;
}

.drop-down {
  width: 100%;
  height: 200px;
  border: solid 1px black
}

.hidden {
  display: none
}
<div class="container" id="container" tabindex="-1">
  <input id="input" />
  <div class="drop-down hidden" id="drop-down" > Hi I'm a drop down </div>
</div>

그러나 탭 순서에 드롭다운을 추가하거나 드롭다운에 버튼이 있거나 일반적으로 포커스를 받을 수 있는 요소가 있는 경우 한 가지 문제가 발생합니다.그러면 클릭하면 드롭다운 포커스에 있는 요소가 먼저 표시되기 때문입니다.그러면 용기 div가 포커스를 잃으면 포커스 이벤트가 더 이상 버블링할 수 없으므로 포커스 이벤트를 트리거할 수 없습니다.focusin우리 컨테이너에.

우리는 이 문제를 확장함으로써 해결할 수 있습니다.focusout이벤트 청취자 여러분.

새 이벤트 수신기는 다음과 같습니다.

container.addEventListener("focusout", (event) => {
  dropDown.classList.toggle("hidden", !container.matches(":hover"))
})

우리는 기본적으로 다음과 같이 말합니다. "누군가가 그 위를 맴돌면 DropDown을 닫지 않습니까?" (이 솔루션에서는 마우스 사용만 고려합니다. 하지만 이 경우에는 문제가 발생했습니다. 마우스를 사용할 때나 dropDown을 탭하거나 통과할 때만 해결하려는 문제가 발생했기 때문에 처음부터 모두 잘 작동했습니다.)

클릭할 때 포커스 변경

온블러와 온클릭이 잘 맞지 않더라도, 분명히 초점에 맞추어서, 네가 온블러를 할 수 있습니다.메뉴를 닫은 후에도 온포커스는 안에서 클릭한 요소에 대해 여전히 유효합니다.

제가 해봤는데 효과가 있었어요.

저에게 적합한 이상적인 솔루션은 단순히 onBlur 함수에 시간 초과를 추가하는 것이었습니다.저는 250ms를 사용했는데, 이는 블러 이벤트에 원활한 동작을 제공하고 onBlur 이전에 onClick이 발화되도록 허용했습니다.이 예를 참고 자료로 https://erikmartinjordan.com/onblur-prevents-onclick-react 에 사용했습니다.

당신은 a를 사용할 수 있습니다.setInterval너의 안에 있는 기능onBlur핸들러는 다음과 같습니다.

<input id="input" onblur="removeMenu()" ... />

function removeMenu() {
    setInterval(function(){
        if (!mouseflag) {
            document.getElementById('menu').innerHTML = '';
        }
    }, 0);
}

setInterval함수는 당신의 것을 제거할 것입니다.onBlur콜 스택에서 기능을 수행합니다. 시간을 0으로 설정했기 때문에 추가합니다. 이 함수는 다른 이벤트 핸들러가 완료된 후 즉시 호출됩니다.

언급URL : https://stackoverflow.com/questions/17769005/onclick-and-onblur-ordering-issue