CSS ": hover"를 활성화하는 순수 JavaScript에서 마우스 오버를 어떻게 시뮬레이션합니까?


83

mouseoverChrome 에서 시뮬레이션 할 코드를 찾으려고 했지만 "mouseover"리스너가 실행 되더라도 CSS "hover"선언이 설정되지 않았습니다!

나는 또한 시도했다 :

//Called within mouseover listener
theElement.classList.add("hover");

그러나 요소를 선언에 선언 된 것으로 변경하는 것은 없습니다 hover.

이것이 가능한가?


6
@PSL 나는 그가 원하는 :hover것은 요소에 대한 강제 상태 라고 생각합니다 .
Benjamin Gruenbaum 2013-06-21

1
@BenjaminGruenbaum 그래 맞아. 나는 오해했다.
PSL 2013 년

1
이것은 중복이 아닙니다. 다른 질문은 jQuery에 관한 것입니다. 이 질문은 순수 JS에 관한 것입니다.
Chuck Le Butt

1
@Monk OQ에는 jQuery 태그가 포함되었습니다. 이것은 중복입니다.
JasonMArcher 2014

1
@JasonMArcher 질문 (및 그 대답)은 순수 JS에 관한 것입니다. 그들이 오해했을 가능성이 더 높다고 생각하지 않습니까?
Chuck Le Butt

답변:


106

당신은 할 수 없습니다. 신뢰할 수있는 이벤트 가 아닙니다 .

사용자 상호 작용의 결과 또는 DOM 변경의 직접적인 결과로 사용자 에이전트에 의해 생성 된 이벤트는 DocumentEvent.createEvent를 통해 스크립트에 의해 생성 된 이벤트에 부여되지 않는 권한을 가진 사용자 에이전트에 의해 신뢰됩니다. ( "Event") 메서드, Event.initEvent () 메서드를 사용하여 수정하거나 EventTarget.dispatchEvent () 메서드를 통해 전달합니다. 신뢰할 수있는 이벤트의 isTrusted 속성 값은 true이고 신뢰할 수없는 이벤트의 isTrusted 속성 값은 false입니다.

대부분의 신뢰할 수없는 이벤트는 click 또는 DOMActivate 이벤트를 제외하고 기본 작업을 트리거하지 않아야합니다.

클래스를 추가하고 mouseover / mouseout 이벤트에서 수동으로 추가 / 제거해야합니다.


4
@Tim, 실제로 대답하지 않습니다 . 그것은 단지 질문을 바꾼다 .
Pacerier

7
@Pacerier 사용자가 시작하지 않았기 때문에 신뢰할 수있는 이벤트가 아닙니다. 너무 말한다 바로 내 대답에 위의 인용에서. 말 그대로 답이 시작되는 것입니다.
Benjamin Gruenbaum

1
@BenjaminGruenbaum, "클릭 또는 DOMActivate 이벤트 제외"를 인용하고 있습니다. 이 예외 목록에없는 "hover"의 특별한 점은 무엇입니까? "포커스"를 호출 있지만 "호버" 는 허용 하지 않는 이유는 무엇 입니까? 이것들은 우리가 대답해야하는 질문 들이며, 다른 것에 대답 하는 것은 단지 질문을 바꾸는 것입니다 .
Pacerier

1
마우스 오버 (및 드래그 앤 드롭을 위해 클릭 또는 마우스 위아래로 결합)가 사용자의 시스템을 하이재킹하는 것처럼 행동하거나 나타날 수 있으므로 (자동화 사례를 무시하는 경우) 지원하는 것이 이상적이지 않습니다. 말할 수는 없지만 포커스를 사용하면 사이트 디자이너가 사용자가 집중하기를 원하는 대상 양식 필드 또는 요소 (예 : 누락되거나 잘못된 데이터가있는 텍스트 필드 (예 : 양식 필드 유효성 검사))에 자동 초점을 맞출 수 있습니다. 그러나 그것은 단지 나의 가정입니다.
David

2
예, 말도 안되게 들리 겠지만 초점이 그렇지 않은 사용자 상호 작용으로 인해 발생한 것처럼 보일 수 있습니다. 실제로-브라우저 API는 기꺼이 사양을 위반하고 포커스를 무시하고 신뢰할 수없는 이벤트로 클릭합니다 (최소한 Chrome). 예를 들어 크롬 확장에 대한 확장 설치 버튼 클릭을 시뮬레이션하고 어떤 일이 발생하는지 확인하십시오. :)
Benjamin Gruenbaum

39

다음과 같이 mouseover 이벤트를 시뮬레이션 할 수 있습니다.

HTML

<div id="name">My Name</div>

자바 스크립트

var element = document.getElementById('name');
element.addEventListener('mouseover', function() {
  console.log('Event triggered');
});

var event = new MouseEvent('mouseover', {
  'view': window,
  'bubbles': true,
  'cancelable': true
});

element.dispatchEvent(event);

고마워요, 제가 필요한 건 거품뿐이었습니다! 개발자 콘솔 인스펙터에서 요소를 마우스 오른쪽 버튼으로 클릭하고 "콘솔에서 사용"(Firefox) 또는 "전역 변수로 저장"(Chrome)을 수행합니다. 그런 다음 예를 들어 temp0.dispatchEvent(new MouseEvent('mouseover', {bubbles: true})) 마우스 오버시에만 나타나는 도구 설명이나 기타 콘텐츠의 스타일을 지정하는 데 매우 유용합니다.
Denis Howe

이건 끝내줘.
rebelliard

1
@DenisHowe 사용 사례 :hov에 대해서는 devtools의 스타일 검사기 상단에있는 버튼을 확인해야합니다 . 검사중인 요소에서 원하는 가상 클래스를 활성화 할 수 있습니다.
안녕하세요

17

배경

나는 주어진 페이지의 특정 요소 세트가 호버 이벤트에 대한 CSS에 의해 설정된 일부 CSS 속성 세트를 가지고 있는지 확인하기 위해 자동화 된 테스트를 작성하려고 시도하는 동안이 질문을 발견했습니다.

위의 답변이 완벽하게 설명하지만 JS에 의해 hover 이벤트를 트리거 한 다음 관심있는 일부 css 값을 조사하는 것이 불가능한 이유는 "CSS를 활성화하는 순수 JavaScript에서 마우스 오버를 어떻게 시뮬레이션합니까?"라는 초기 질문에 대답합니다. : hover”? " 부분적으로 만.

부인 성명

이것은 성능이 뛰어난 솔루션이 아닙니다. 성능이 문제가되지 않는 자동화 된 테스트에만 사용합니다.

해결책

simulateCssEvent = function(type){
    var id = 'simulatedStyle';

    var generateEvent = function(selector){
        var style = "";
        for (var i in document.styleSheets) {
            var rules = document.styleSheets[i].cssRules;
            for (var r in rules) {
                if(rules[r].cssText && rules[r].selectorText){
                    if(rules[r].selectorText.indexOf(selector) > -1){
                        var regex = new RegExp(selector,"g")
                        var text = rules[r].cssText.replace(regex,"");
                        style += text+"\n";
                    }
                }
            }
        }
        $("head").append("<style id="+id+">"+style+"</style>");
    };

    var stopEvent = function(){
        $("#"+id).remove();
    };

    switch(type) {
        case "hover":
            return generateEvent(":hover");
        case "stop":
            return stopEvent();
    }
}

설명

generateEvent는 모든 css 파일을 읽고 : hover를 빈 문자열로 바꾸고 적용합니다. 모든 : hover 스타일이 적용되는 효과가 있습니다. 이제 시뮬레이션을 중지하여 Howered 스타일을 조사하고 초기 상태로 돌아갈 수 있습니다.

시트에서를 가져 와서 element.css (...)를 수행하여 관심있는 요소뿐만 아니라 전체 문서에 대해 호버 효과를 적용하는 이유는 무엇입니까?

이렇게하면 스타일이 인라인으로 적용되고 원래 CSS 호버 스타일에 의해 재정의되지 않을 수있는 다른 스타일이 재정의됩니다.

이제 단일 요소에 대한 호버링을 어떻게 시뮬레이션합니까?

이것은 성능이 좋지 않으므로하지 않는 것이 좋습니다. 필요한 경우 스타일이 요소에 적용되고 해당 스타일 만 사용하는지 element.is (selectorOfInterest)로 확인할 수 있습니다.

Jasmine에서 다음을 수행 할 수 있습니다.

describe("Simulate CSS Event", function() {
    it("Simulate Link Hover", function () {
      expect($("a").css("text-decoration")).toBe("none");
      simulateCssEvent('hover');
      expect($("a").css("text-decoration")).toBe("underline");
      simulateCssEvent('stop');
      expect($("a").css("text-decoration")).toBe("none");
    });
});

1
이 대답은 훌륭합니다! 안타깝게도 Chrome이 교차 출처 요청에 대한 액세스를 제한하기 때문에 다른 호스트에서 제공 한 스타일 시트가있는 페이지의 최신 버전 Chrome에서는 실패합니다. 이것을 지원하는 솔루션에 대한 내 대답을 참조하십시오 :)
FThompson

6

내가 보통이 경우 일은 같은 자바 스크립트를 사용하여 클래스를 추가 .. 및 연결이다 CSS는 AS를 :hover이 클래스에

사용해보십시오

theElement.addEventListener('onmouseover', 
    function(){ theElement.className += ' hovered' });

또는 이전 브라우저의 경우 :

theElement.onmouseover = function(){theElement.className += ' hovered'};

물론 onmouseout요소를 떠날 때 "hovered"클래스를 제거하려면 을 사용해야 합니다.


이것은 OP가 요구하는 것을 수행하지 않을 것입니다. 최신 이벤트 처리기 첨부 기술을 사용하는 것이 좋습니다.
Pointy

죄송합니다, 오해 질문
Yotam 오메르

@Pointy 질문은 순수한 자바 스크립트를 요구합니다. 그렇지 않으면 이벤트를 어떻게 첨부 할 수 있습니까?
Yotam Omer

2
충분하지? "순수한"JavaScript이며 실제로 이벤트에 대한 핸들러로 함수를 첨부합니다. Internet Explorer에서는 (거의) 동등한 attachEvent()것이 사용됩니다.
Pointy

언급할만한 가치가 있습니다. IE9 및 10을 지원 addEventListener하며 이벤트를 첨부하는 가장 좋은 방법입니다. shimming attachEvent은 IE8 (이하)에서만 필요합니다. Yotam, onmouseover속성을 직접 설정하여 (이벤트 리스너를 추가하는 대신) 다른 핸들러를 추가하면 현재 설정된 이벤트를 재정의합니다. 차이점에 대한 이 질문 을 참조하십시오 .
Benjamin Gruenbaum 2013-06-21

4

CSS 의사 클래스를 요소에 적용 할 수있는 라이브러리 인 pseudo : styler를 사용할 수 있습니다 .

(async () => {
  let styler = new PseudoStyler();
  await styler.loadDocumentStyles();
  document.getElementById('button').addEventListener('click', () => {
    const element = document.getElementById('test')
    styler.toggleStyle(element, ':hover');
  })
})();

면책 조항 : 저는이 도서관의 공동 저자입니다. 특히 페이지의 CSS 규칙을 제어 할 수없는 Chrome 확장 프로그램에서 사용하기 위해 교차 출처 스타일 시트를 추가로 지원하도록 설계했습니다.


1
이것은 window.getComputedStyle(<youElement>)의사 스타일을 설정 한 후 함께 결합하더라도 실제로 꽤 잘 작동하는 것 같습니다 . 감사!
Daniel Veihelmann

2

DOM 조작 후 CSS를 검사하고 싶다고 가정하고 있지만 마우스를 devtools로 다시 이동하자마자 이벤트는 더 이상 해당 html 요소에서 활성화되지 않습니다. 자바 스크립트 이벤트를 위해 devtools에서 : hover 옵션과 같은 것을 원할 것입니다. 존재하지 않지만 시뮬레이션 할 수 있습니다.

  1. devtools를 열고 클릭하여 활성화하십시오.
  2. 관심있는 요소에서 이벤트를 트리거합니다.
  3. 마우스를 움직이지 않고 ctrl + shift + p로 devtools 명령 패널을 열고 키보드로 '자바 스크립트 비활성화'를 선택합니다.

자바 스크립트가 비활성화 되었기 때문에 요소를 다시 수정할 기회가 없습니다. devtools로 이동하여 마치 마우스를 가리 키거나 클릭하거나 다른 작업을 수행하는 것처럼 CSS와 HTML을 검사 할 수 있습니다. 완료되면 명령 패널로 다시 이동하여 'JavaScript 활성화'를 선택하십시오.


깔끔한 기술,하지만 난 당신의 의도를 오해하지 않는 한,이 않습니다 이미 DevTools로 존재! Chrome / Chromium과 Firefox의 devtools 모두 :hov스타일 검사기 상단 ( "필터"입력 상자 옆)에 버튼이 있습니다. 클릭 :hov팽창을 체크 박스의 시리즈를 각각 pseudoclass으로 표시 : :active, :focus, :focus-within, :hover,와 :visited. 그리고 이러한 상자 중 하나를 선택하면 검사중인 요소에서 해당 가상 클래스가 활성화됩니다.
안녕하세요
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.