programing

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

nasanasas 2020. 11. 14. 10:17
반응형

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


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

나는 또한 시도했다 :

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

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

이것이 가능한가?


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

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

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

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


다음과 같이 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);

배경

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

위의 답변이 완벽하게 설명하지만 JS에서 단순히 hover 이벤트를 트리거 한 다음 관심있는 CSS 값을 증명하는 것이 불가능한 이유는 "활성화되는 순수 JavaScript에서 마우스 오버를 시뮬레이션하는 방법 CSS ": 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 reads all css files, , replaces :hover with an empty string and applies it. This has the effect, that all :hover styles are applied. Now one can probe for a howered style and set back to initial state by stopping the Simulation.

Why do we apply the hover effect for the whole document and not just for the element of interest by getting the from the sheets and then perform a element.css(...)?

Done as that, the style would be applied inline, this would override other styles, which might not be overriden by the original css hover-style.

How would I now simulate the hover for a single element?

This is not performant, so better don't. If you must, you could check with the element.is(selectorOfInterest) if the style applies for your element and only use those styles.

Example

In Jasmine you can e.g. now perform:

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");
    });
});

What I usually do in this case is adding a class using javascript.. and attaching the same CSS as the :hover to this class

Try using

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

Or for older browsers:

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

you will ofcourse have to use onmouseout to remove the "hovered" class when you leave the element...


You can use pseudo:styler, a library which can apply CSS pseudo-classes to elements.

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

Disclaimer: I am a coauthor of this library. We designed it to additionally support cross-origin stylesheets, specifically for use in Chrome extensions where you likely lack control over the CSS rules of the page.

참고URL : https://stackoverflow.com/questions/17226676/how-do-i-simulate-a-mouseover-in-pure-javascript-that-activates-the-css-hover

반응형