Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   задать hover для элемента (https://javascript.ru/forum/dom-window/10051-zadat-hover-dlya-ehlementa.html)

bushstas 17.06.2010 10:54

задать hover для элемента
 
Допустим есть элемент <a id="some">
Так вот возможно ли задать средствами JS ему :hover
как этот в css
#some:hover {color:#---}

chippolino 17.06.2010 11:36

Конечно можно. Вот один из вариантов:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN">
<html><head><title>New</title>
<script type="text/javascript">

window.onload = function(){
	
	var style = document.createElement('style');
	style.type = 'text/css';
	
	var h = '#some:hover{color:#f00}';
	var hover = document.createTextNode(h);

	var head = document.getElementsByTagName('head')[0];

	style.appendChild(hover);
	head.appendChild(style);
		
}

</script>
</head><body>

<h1><a id="some" href="#">test</a></h1>
 
</body></html>

bushstas 17.06.2010 11:42

ясно, значит нужно добавить стиль в Head
спасибо!

chippolino 17.06.2010 12:16

<script type="text/javascript">
//можно сымитировать :hover c помощью событий onmouseover и onmouseout
window.onload = function(){

	var some = document.getElementById('some');
	some.style.color = 'lightblue';//задаем цвет по умолчанию
	some.onmouseover = function(){
		some.style.color = '#f00';
	}
	some.onmouseout = function(){
		some.style.color = 'lightblue';
	}
}

</script>

bushstas 17.06.2010 12:39

Я сделал может и криво но по-своему :)
<a id="some" onmouseover="hover('some','c14141')" onmouseout="nohover()"> Наведи на меня </a>

function hover(id,c){
// узнаем цвет до наведения и запоминаем
var color=document.getElementById(id).style.color;
if (color=="unfefined" || color==""){
var par=document.getElementById(id)
while(color=="undefined"  || color==""){par=par.parentNode; color=par.style.color}
colorBefore=color}
else {colorBefore=color}
document.getElementById(id).style.color="#"+c
Hovered=id
}
function nohover(){
if (colorBefore==""){colorBefore="#000000"}
document.getElementById(Hovered).style.color=colorBefore
Hovered=""
}

тока если ни у одного из родителей не будет задан в стилях color будет плохо :)

еще бы улучшить чтобы не передовать id элемента а вычислять в самой функции :)

Skipp 17.06.2010 12:43

bushstas,
можно и без id
<a onmouseover="hover(this,'c14141')"  onmouseout="nohover()"> Наведи на меня </a>

bushstas 17.06.2010 12:48

спасибо Skipp мне вот этот this пока с трудом дается оказывается все просто :)

Skipp 17.06.2010 12:51

bushstas,
В данном случае this передаёт ссылку на элемент <a>

А вообще интересно, что этой функцией вы хотите сделать, вникать в код не хочется, суть в чём.
Может что попроще подскажу.

bushstas 17.06.2010 12:57

этой функцией я хочу изменять цвет шрифта элементов <a> при наведении на них, чтобы не прописывать в css для каждого hover, просто передовать цвет в функцию hover().
та узнает цвет текста до наведения из стиля, если не указан из стиля родителя и так далее вверх по дереву, запомнит, перекрасит текст в переданный цвет

функция nohover() перекрасит текст обратно в цвет до наведения :)

Skipp 17.06.2010 13:03

bushstas,
Похимичте с этим
<a id="some" onmouseover="this.style.color='#c14141'" onmouseout="..."> Наведи на меня </a>

Vulkan 17.06.2010 15:14

Зачем такой огромный код для такой задачи? То что предложил Skipp намного оптимальнее.

paveljava5 17.06.2010 16:00

Цитата:

Сообщение от bushstas
функция nohover() перекрасит текст обратно в цвет до наведения

, а если в браузере пользователя отключен ява скрипт??

Skipp 17.06.2010 16:02

paveljava5,
Зачем задавать такой вопрос, если ответ очевиден:)

dpts 27.11.2019 10:40

А у меня обратная задача
 
Собственно сабж - узнать стили элемента, когда он :hover.
То-есть, существует какой-то элемент, допустим
<input id="inp1">
, который чем-то стилизуется, например бутстрапом или еще чем-то неизвестным.

Мне надо js-ом добавлять на страничку, допустим кастомный селект, который внешне будет стилизован как этот инпут с id="inp1".

Стили инпута не :hover-ные считываются getComputedStyle().
Вопрос, где взять стили этого инпута при :hover.

Skipp 27.11.2019 12:05

Вариантов не много, на скорую руку накатал только такой:

<html>
	<head>
		<style>
			body > a {
				color: red;
			}
			
			body > a:hover {
				color: blue !important;
			}
			
			@media (max-width: 991.98px) {
				body > a:hover {
					color: green;
				}
			}
			
			body > a:hover {
				color: yellow;
			}
		</style>
	</head>
	<body>
		<a href="javascript:void(0)">Link</a>
		
		<script>
			window.getPseudoStyles = function(element, pseudo) {
				if(!document.styleSheets) return;
				
				for(var i = document.styleSheets.length - 1; i > -1; i--) {
					var
						rules			= document.styleSheets[i].cssRules ? document.styleSheets[i].cssRules : document.styleSheets[i].rules;
						
					for(var j = rules.length - 1; j > -1; j--) {
						if(rules[j].selectorText) {
							var
								match = rules[j].selectorText.match(new RegExp('^(.+)(' + pseudo + ')$'));
							if(match && match.length === 3 && document.querySelector(match[1]).isEqualNode(element))
								return rules[j].style;
						}
					}
				}
				return;
			}
		
		
			var
				a = document.querySelector('body > a');
			
			alert(getPseudoStyles(a, ':hover').color);
		</script>
	</body>
</html>


Но не работает с медиа, для этого надо дописывать, но получится ещё больший велосипед чем это.
Вообще не представляю задачу при которой потребуется данное решение, обычно подход идёт совсем с другой стороны.

Так же, в данном случаи берётся последний из вариантов применённых стилей с псевдо классом, как делает это браузер, по сути предыдущие не нужны, но есть но, !important и тут он получается игнорируется, по этому дополнительных изменений функции не избежать.

dpts 27.11.2019 12:23

Цитата:

Сообщение от Skipp (Сообщение 516272)
Вариантов не много, на скорую руку накатал только такой:

<html>
	...
</html>


Но не работает с медиа, для этого надо дописывать, но получится ещё больший велосипед чем это.
Вообще не представляю задачу при которой потребуется данное решение, обычно подход идёт совсем с другой стороны.

Так же, в данном случаи берётся последний из вариантов применённых стилей с псевдо классом, как делает это браузер, по сути предыдущие не нужны, но есть но, !important и тут он получается так же игнорируется, по этому дополнительных изменений функции не избежать.

Нене. Не то.
Давайте посмотрим на начальную задачу. там сказано, что стили инпута устанавливаются чем-то не известным например бутстрапом подключенным с cdn-а или любым другим css-фреймворком (или своим css файлом, который лежит не известно где, как называется, и т.д. в нем может и не быть отдельного класса для инпута может и не быть прописан :hover для инпута), то-есть парсить стили или css файлы - не вариант.

Задача - вполне понятная - воткнуть свой кастомный селект в любой html с минимальными затратами на написание css для кастомного селекта, чтобы он при этом не выбивался из общей стилистики html документа, в том числе по поведению.

Например мы пльзуем бутстрап, при наведеннии на инпут бутстрапов css подсвечивает инпут (меняет цвет рамки, добавляет тень и т.д.)

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

Skipp 27.11.2019 12:43

Во первых, ваш вопрос:
Цитата:

Сообщение от dpts (Сообщение 516271)
Вопрос, где взять стили этого инпута при :hover.

Во вторых, какая разница откуда подключаются стили и какие фрейморков? Чем они отличаются от кастомных?
В третьих, я больше чем уверен, что вы пошли не той дорогой для решения задачи, почему нельзя просто клонировать элемент, не добавляя какие-то свои стилевые правила?

<html>
	<head>
		<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.0/css/bootstrap.min.css" integrity="sha384-SI27wrMjH3ZZ89r4o+fGIJtnzkAnFs3E4qz9DIYioCQ5l9Rd/7UAa8DHcaL8jkWt" crossorigin="anonymous">
	</head>
	<body>
		<a href="javascript:void(0)">Link</a>
		
		<script>
			window.getPseudoStyles = function(element, pseudo) {
				if(!document.styleSheets) return;
				
				for(var i = document.styleSheets.length - 1; i > -1; i--) {
					var
						rules			= document.styleSheets[i].cssRules ? document.styleSheets[i].cssRules : document.styleSheets[i].rules;
						
					for(var j = rules.length - 1; j > -1; j--) {
						if(rules[j].selectorText) {
							var
								match = rules[j].selectorText.match(new RegExp('(?:^|,)([^,]+)(' + pseudo + ')(?:$|,)'));
							if(match && match.length === 3)
								var
									el = document.querySelector(match[1]);
								if(el && el.isEqualNode(element))
									return rules[j].style;
						}
					}
				}
				return;
			}
		
		
			var
				a = document.querySelector('body > a');
			
			alert(getPseudoStyles(a, ':hover').color);
		</script>
	</body>
</html>

Подправил скрипт, не учёл групповые правила.

dpts 27.11.2019 12:54

Цитата:

Сообщение от Skipp (Сообщение 516278)
Во первых, ваш вопрос:

Во вторых, какая разница откуда подключаются стили и какие фрейморков? Чем они отличаются от кастомных?
В третьих, я больше чем уверен, что вы пошли не той дорогой для решения задачи, почему нельзя просто клонировать элемент, не добавляя какие-то свои стилевые правила?

Подправил скрипт, не учёл групповые правила.

Что клонировать чтобы не добавлять свои стилевые правила, input?
Ну так я и получу клонированный инпут, а мне надо взять от этого инпута стили и прикрутить часть из них к div,
в котором input и кнопка, открывающая список опций, часть к инпуту в диве, часть к кнопке.
(размеры, отступы, стили текста, бэкграунд и бордер и т.д.). через .getComputedStyle() на старте все это берется без вопросов,
Но у "эталонного" инпута могут быть еще и стили прописанные на :hover и/или :focus (изменения стиля бордера, например,) вот их я также хочу прочитать, чтобы это изменение прикрутить к div, а не к input? который получен путем клонирования.

Чот тупанул я. Спасибо буду пробовать.

dpts 28.11.2019 05:35

Uncaught DOMException: Failed to read the 'cssRules' property from 'CSSStyleSheet': Cannot access rules
at window.getPseudoStyles (http://localhost:73/getPseudoStyles/:14)
at http://localhost:73/getPseudoStyles/:35

Причем Ошибка выдается, если:
1. вообще никаких стилей не подключать
2. если кроме бутстрапа пытаться подключить
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
или/и
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700,800&display=swap&subset=cyrillic" rel="stylesheet">

laimas 28.11.2019 09:01

Хром?

dpts 28.11.2019 09:20

Цитата:

Сообщение от laimas (Сообщение 516346)
Хром?

он самый.
то же самое в Опере 64.0.3417.92
а в IE работает )

При этом, если normalise.css и гуглошрифты подключить раньше бутстрапа - то работает )

laimas 28.11.2019 09:53

В Хроме то-ли до как раз 64, то-ли в нем, то-ли после него, не помню, была изменена политика CORS, из-за чего и проблемы. Но в своем проекте css ведь и у себя можно держать, и ошибок не будет.

dpts 28.11.2019 10:13

Цитата:

Сообщение от laimas (Сообщение 516348)
В Хроме то-ли до как раз 64, то-ли в нем, то-ли после него, не помню, была изменена политика CORS, из-за чего и проблемы. Но в своем проекте css ведь и у себя можно держать, и ошибок не будет.

Так в том и вопрос, что "а если не свой проект"?

Основной-то замысел как-раз в том, чтобы можно было с минимальными затратами по времени на разбирание сторонних css максимально приближенный по внешнему виду и реакции на ховеры/фокусы к подключенным в проекте css

Если "что-то у себя держать" - то можно просто под каждый проект прописывать руками стили и все, а я хочу от этого избавиться по максимуму.

laimas 28.11.2019 10:16

Цитата:

Сообщение от dpts
"а если не свой проект"?

А если не свой, то будет запрещен доступ ко всему.

dpts 28.11.2019 10:25

Цитата:

Сообщение от laimas (Сообщение 516350)
А если не свой, то будет запрещен доступ ко всему.

Логично. Но исходя и этой логики, получается, что нефиг рыпаться, курите сторонние css и пишите руками стили. )))

Под не свой, я не имел в виду, что мне надо что-то насильно воткнуть в какой-то HTML каким-то посторонним скриптом.

Есть HTML c подключенными стилями, я в этом же HTML скриптом из этого-же HTML пытаюсь почитать стили и никак иначе. Считается-ли это сторонним проектом? Не думаю.

Skipp 28.11.2019 10:25

Да, чёртова политика безопасности, в аднном случаи по моему вообще не оправданная.

Я всё так и не пойму, почему нельзя клонировать объекты?

laimas 28.11.2019 10:28

Цитата:

Сообщение от dpts
Но исходя и этой логики, получается, что нефиг рыпаться

А ваша логика разве не странная? Что вам мешает поместить нужный файл у себя, а там уж как душа желает, либо лениться что-то прописать и насиловать файл, либо ...
Попробуйте подключение через прокси.

Skipp 28.11.2019 10:32

Насчёт логики согласен, думаю проблема в подходе к решению задачи.

<html>
	<head>
		<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.0/css/bootstrap.min.css" integrity="sha384-SI27wrMjH3ZZ89r4o+fGIJtnzkAnFs3E4qz9DIYioCQ5l9Rd/7UAa8DHcaL8jkWt" crossorigin="anonymous">
	</head>
	<body>
		<a href="javascript:void(0)">Link</a>
		<script>
			document.body.append(document.querySelector('body > a').cloneNode(true));
		</script>
	</body>
</html>

Правда js события не подцепятся.

dpts 28.11.2019 10:50

Цитата:

Сообщение от laimas (Сообщение 516353)
А ваша логика разве не странная? Что вам мешает поместить нужный файл у себя, а там уж как душа желает, либо лениться что-то прописать и насиловать файл, либо ...
Попробуйте подключение через прокси.

Моя странная логика отказа от клонирования описана выше.
Но опишу ее еще раз:
1. Я делаю кастомный селект, размеченный условно:
<div>
    <input>
    <button></button>
</div>

2. На странице есть, допустим
<input id="inp1" class="form-control">
, который я беру за "эталонный".
3. я от эталонного инпута беру стили .getComputedStyle() и приделываю часть из них к div, часть к input, часть к button. Все стает хорошо и ровненько содержимое из пункта 1 вписывается в стилистику эталонного инпута.

Теперь мне надо от эталонного инпута hover и focus прочитать, чтобы и их прикрутить.

Если я склонирую Инпут, то я склонирую именно Инпут и ничто другое.

Ничто не мешает под каждый проект писать эти стили в принципе. Но с таким подходом можно и счеты использовать.

Дело не в лени, если это действительно нельзя сделать - то вопросов нет, если можно сделать. то почему не сделать?

Skipp 28.11.2019 10:57

Отлично, теперь полностью понятен смысл.
Над этим надо подумать, каких-то простых решений нету, но всегда есть обходные пути.

laimas 28.11.2019 11:35

Цитата:

Сообщение от dpts
На странице есть, допустим
<input id="inp1" class="form-control">

Ну если знаем класс и стили его, которые хотим использовать, то зачем получать сами стили, вместо использования его класса?

Skipp 28.11.2019 11:40

Цитата:

Сообщение от laimas (Сообщение 516358)
Ну если знаем класс и стили его, которые хотим использовать, то зачем получать сами стили, вместо использования его класса?

Потому что структура и элементы отличаются.
Допустим у этого input стиль прописан по правилу:
input.from-control
или вообще
#inp1
В таком случаи к допустим button ты его не применишь.

laimas 28.11.2019 11:53

Цитата:

Сообщение от Skipp
Потому что структура и элементы отличаются.

Ну еще и правила не правила подходят/нужны так? Так что тогда искусственный интеллект нужен или все-таки перед использованием нужен визуальный анализ?

dpts 28.11.2019 12:00

Цитата:

Сообщение от laimas (Сообщение 516358)
Ну если знаем класс и стили его, которые хотим использовать, то зачем получать сами стили, вместо использования его класса?

Потомучто например:
1. это может быть не бутстрап
2. это может быть и бутстрап но класс не прописан
3. это может быть свой класс.
4. это могут быть 15 (условно) классов, какой из них брать?
5. вы предлагаете класс единичного инпута применить к div внутри которого input и button?
- А вы уверены, что .form-control{display:flex;} например?

И на самом деле - еще вагон и маленькая тележка вопросов, неизбежно возникающих в этом случае.
Такчто мы не знаем класс

dpts 28.11.2019 12:04

Цитата:

Сообщение от laimas (Сообщение 516361)
Ну еще и правила не правила подходят/нужны так? Так что тогда искусственный интеллект нужен или все-таки перед использованием нужен визуальный анализ?

Вот визуально как-раз и проанализировано уже, и по-этому вопрос и появился.
Вы смотрите на вопрос только с точки зрения js профи, не глядя на внешний вид результата.
Я наоборот, обращаюсь к js профи, чтобы понять как прийти к нужному визуальному результату.

Вы конечно можете предложить склонировать инпут, чтобы ховеры и фокусы применялись к инпуту а не к диву, а кнопку положить слоем выше с абсолютным позиционированием в правом верхнем углу.

Но, не забывайте, что:
1. div-то в документе и фоном документа может быть все, что угодно.
2. у эталонного дива может быть background:none; соответственно и диву и инпуту и кнопке надо такой же бэкграунд (пока не страшно).
3. а давайте теперь диву и инпуту из пункта 2 выставим ширину 100 пикселей, и в инпут закопипастим пару параграфов Лоремов. Станет страшно.

И это просто пример на вскидку. Даже сильно не выдумывая и глубоко не копая.

laimas 28.11.2019 12:21

Цитата:

Сообщение от dpts
вы предлагаете класс единичного инпута применить к div внутри которого input и button?
- А вы уверены, что .form-control{display:flex;} например?

Я не понимаю душевных терзаний, ибо если бы JS за вас думал, догадывался чего вы хотите, искал, подбирал, выбраковывал лишнее, тогда понятно. В противном случае не понятно к чему все это.

dpts 28.11.2019 12:26

Цитата:

Сообщение от laimas (Сообщение 516364)
Я не понимаю душевных терзаний, ибо если бы JS за вас думал, догадывался чего вы хотите, искал, подбирал, выбраковывал лишнее, тогда понятно. В противном случае не понятно к чему все это.

Ответ истинного Профессионала. Браво. Спасибо.

Я в курсе, что я дебил, но я пытаюсь учиться. И спрашиваю чтобы понять и научиться, а не для того, чтобы потрясти воздух "душевными терзаниями".
И именно потому, что: "JS за вас думал, догадывался чего вы хотите, искал, подбирал, выбраковывал лишнее", - до сих пор не случилось, предлагаемое Вами клонирование не проходит, а про display:flex - это всего-лишь "посмотреть на полшага вперед", именно про тот визуальный анализ, которым Вы же и козырнули.

laimas 28.11.2019 12:40

Цитата:

Сообщение от dpts
Я в курсе, что я дебил, но я пытаюсь учиться.

Я ведь не называл никого дебилом. Но, если учесть, что JS конечно же не может догадаться чего от него хотят, а значит придется все селекторы, правила, условия описывать, то это уже не хилая работа будет. Зачем же тратить на это время вместо того чтобы явно прописать необходимые стили, вот это не понятно.

dpts 28.11.2019 12:57

Цитата:

Сообщение от laimas (Сообщение 516367)
Я ведь не называл никого дебилом. Но, если учесть, что JS конечно же не может догадаться чего от него хотят, а значит придется все селекторы, правила, условия описывать, то это уже не хилая работа будет. Зачем же тратить на это время вместо того чтобы явно прописать необходимые стили, вот это не понятно.

Да не вопрос. Можно прописать свои селекторы.
Но опять же с точки зрения визуального анализа:
1. если это уже прописано - берем написанное.
2. если не прописано - берем свое.
3. я и не хочу обходить и описывать ВСЕ селекторы, я хочу посмотреть на 1 элемент с известным id (я не в курсе механизмов какими JS добирается до стилей этого элемента, вполне возможно, что он обходит все селекторы, которые есть, а не только селекторы этого элемента)
Потому и спросил изначально.
Решение предложенное Skipp - вполне себе нормальное решение, если бы не политика безопасности.

laimas 28.11.2019 13:21

Цитата:

Сообщение от dpts
я и не хочу обходить и описывать ВСЕ селекторы, я хочу посмотреть на 1 элемент с известным id

Как по уму - в отладчике браузера выбираем элемент, смотрим правила, копируем и вставляем себе.

На JS - сначала смотрим правила, затем пишем что-то для JS и нагружаем его, боремся попутно с проблемами возможными, ковыряемся в стилях в поиске, затем применяем.

Я может быть не понимаю, может быть в этом есть какой-то скрытый глубокий смысл, но я не вижу вообще в этом никакого смысла. Ну коли охота, то она же пуще неволи.


Часовой пояс GMT +3, время: 10:04.