Подтвердить что ты не робот

Как смоделировать мышь в чистом JavaScript, который активирует CSS ": hover"?

Я пытаюсь найти код для симуляции mouseover в Chrome, но, несмотря на то, что прослушиватель "mouseover" запускается, объявление CSS "hover" никогда не устанавливается!

Я тоже пробовал:

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

Но ничто не изменяет элемент на то, что объявлено в его объявлении hover.

Возможно ли это?

4b9b3361

Ответ 1

Вы не можете. Это не доверенное событие.

События, которые генерируются пользовательским агентом либо в результате взаимодействия с пользователем, либо как прямой результат изменений в DOM, доверяются пользовательским агентом с привилегиями, которые не предоставляются событиям, генерируемым script через метод DocumentEvent.createEvent( "Событие" ), модифицированный с помощью метода Event.initEvent() или отправленный методом EventTarget.dispatchEvent(). Атрибут isTrusted доверенных событий имеет значение true, а недоверенные события имеют значение атрибута isTrusted false.

Большинство ненадежных событий не должны запускать действия по умолчанию, за исключением щелчков или событий DOMActivate.

Вы должны добавить класс и добавить/удалить его в события mouseover/mouseout вручную.

Ответ 2

Фон

Я наткнулся на этот вопрос, пытаясь написать автоматизированные тесты, чтобы убедиться, что определенный набор элементов на данной странице все получает некоторый набор свойств css, заданных css для событий наведения.

В то время как вышеприведенный ответ прекрасно объясняет, почему невозможно просто вызвать событие наведения JS, а затем принять доказательство некоторого значения интереса 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 считывает все css файлы, заменяет: навевает пустую строку и применяет ее. Это приводит к тому, что применяются все стили hover. Теперь можно исследовать сдержанный стиль и вернуться в исходное состояние, остановив симуляцию.

Почему мы применяем эффект наведения для всего документа, а не только для интересующего элемента, получая его из листов, а затем выполняем элемент element.css(...)?

Сделано так, что стиль будет применен inline, это переопределит другие стили, которые не могут быть переопределены исходным стилем css hover.

Как мне теперь смоделировать наведение для одного элемента?

Это не работает, так что лучше не делать. Если нужно, вы можете проверить с помощью element.is(selectorOfInterest), если стиль применяется для вашего элемента и использовать только эти стили.

Пример

В жасмине вы можете, например, теперь выполните:

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

Ответ 3

Вы можете смоделировать событие mouseover следующим образом:

HTML

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

JavaScript

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

Ответ 4

В этом случае я обычно добавляю класс с использованием javascript.. и прикрепляя тот же CSS как :hover к этому классу

Попробуйте использовать

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

Или для старых браузеров:

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

вы должны использовать onmouseout, чтобы удалить "зависающий" класс, когда вы покидаете элемент...

Ответ 5

Вы можете использовать pseudo: styler, библиотеку, которая может применять псевдоклассы CSS к элементам.

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

Отказ от ответственности: я соавтор этой библиотеки. Мы разработали его для дополнительной поддержки таблиц стилей перекрестного происхождения, особенно для использования в расширениях Chrome, где вам, вероятно, не хватает контроля над правилами CSS страницы.

Ответ 6

SCSS

.hover {
    @extend :hover;
}