What I want to achieve is to make "select to inspect" type of functionality, just like the browsers have. It should only have the functionality of creating a temporary element that will be overlayed over the element that my mouse is hovering on.
I have created a screencast to show you what it should be like, and what I currently have.
Link to video on google drive
My code
function create_div(){
let style = `
background-color: rgba(130, 180, 230, 0.5);
outline: solid 1px #0F4D9A;
box-sizing: border-box;
position: absolute;
display: block;
z-index: 999999;
`
let e = document.createElement('DIV')
e.setAttribute('id', 'tester')
e.setAttribute('style', style)
document.body.appendChild( e )
}
create_div()
$( "body" ).mousemove(function( event ) {
$( '#tester' ).css({'display' : 'none'})
let target = $( event.target )
$( '#tester' ).css({'display' : 'block', "width": target.width(),
'height': target .height(), 'top' : target .offset().top,
'left' : target .offset().left});
})
This is my code written with jQuery
It creates a DIV on the page and then, on mousemove event, I set its values (height, width, and the position)
to be the same as the element that I am hovering on. But what I get is some glitchy windows when I hover over.
What am I missing here?
You need to add pointer-events: none; to the #tester's CSS - it will make DIV transparent for mouse events. It is to unglitch from mouseover-ing
To kill another possible glitch-source, let's just save somewhere last target you have processed, so it will be no need to resize/redraw #tester again.
It will result in:
function create_div(){
$("body").append(
$("<div id=\"tester\"></div>").css({
"background-color": "rgba(130, 180, 230, 0.5)",
"outline": "solid 1px #0F4D9A",
"box-sizing": "border-box",
"position": "absolute",
"display": "block",
"z-index": "999999",
"pointer-events": "none"
})
);
}
$(document).ready(create_div);
$("body").mousemove(function( event ) {
let target = $(event.target)
if (target.length === 0){
$("#tester").css({
"display" : "none"
});
$("#tester").data("target", null);
}else if(
$("#tester").data("target") === null ||
$("#tester").data("target") !== target
){
$("#tester").data("target", target);
$("#tester").css({
"display" : "block",
"width" : target.width(),
"height" : target.height(),
"top" : target.offset().top,
"left" : target.offset().left
});
}
// else {leave #tester with no changes}
});
Related
I'm using a WordPress plugin (open source) that will allow you to add an expandable widget for a WooCommerce product category.
This is the JS:
// mtree.js
// Requires jquery.js and velocity.js (optional but recommended).
// Copy the below function, add to your JS, and simply add a list <ul class=mtree> ... </ul>
;(function ($, window, document, undefined) {
// Only apply if mtree list exists
if($('ul.mtree').length) {
// Settings
var collapsed = true; // Start with collapsed menu (only level 1 items visible)
var close_same_level = true; // Close elements on same level when opening new node.
var duration = mtree_options.duration; // Animation duration should be tweaked according to easing.
var listAnim = true; // Animate separate list items on open/close element (velocity.js only).
var easing = mtree_options.easing_type; // Velocity.js only, defaults to 'swing' with jquery animation.
// Set initial styles
$('.mtree ul').css({'overflow':'hidden', 'height': (collapsed) ? 0 : 'auto', 'display': (collapsed) ? 'none' : 'block' });
// Get node elements, and add classes for styling
var node = $('.mtree li:has(ul)');
node.each(function(index, val) {
$(this).children(':first-child').css('cursor', 'pointer')
$(this).addClass('mtree-node mtree-' + ((collapsed) ? 'closed' : 'open'));
$(this).children('ul').addClass('mtree-level-' + ($(this).parentsUntil($('ul.mtree'), 'ul').length + 1));
});
// Set mtree-active class on list items for last opened element
$('.mtree li > *:first-child').on('click.mtree-active', function(e){
if($(this).parent().hasClass('mtree-closed')) {
$('.mtree-active').not($(this).parent()).removeClass('mtree-active');
$(this).parent().addClass('mtree-active');
} else if($(this).parent().hasClass('mtree-open')){
$(this).parent().removeClass('mtree-active');
} else {
$('.mtree-active').not($(this).parent()).removeClass('mtree-active');
$(this).parent().toggleClass('mtree-active');
}
});
// Set node click elements, preferably <a> but node links can be <span> also
node.children(':first-child').on('click.mtree', function(e){
// element vars
var el = $(this).parent().children('ul').first();
var isOpen = $(this).parent().hasClass('mtree-open');
// close other elements on same level if opening
if((close_same_level || $('.csl').hasClass('active')) && !isOpen) {
var close_items = $(this).closest('ul').children('.mtree-open').not($(this).parent()).children('ul');
// Velocity.js
if($.Velocity) {
close_items.velocity({
height: 0
}, {
duration: duration,
easing: easing,
display: 'none',
delay: 100,
complete: function(){
setNodeClass($(this).parent(), true)
}
});
// jQuery fallback
} else {
close_items.delay(100).slideToggle(duration, function(){
setNodeClass($(this).parent(), true);
});
}
}
// force auto height of element so actual height can be extracted
el.css({'height': 'auto'});
// listAnim: animate child elements when opening
if(!isOpen && $.Velocity && listAnim) el.find(' > li, li.mtree-open > ul > li').css({'opacity':0}).velocity('stop').velocity('list');
// Velocity.js animate element
if($.Velocity) {
el.velocity('stop').velocity({
//translateZ: 0, // optional hardware-acceleration is automatic on mobile
height: isOpen ? [0, el.outerHeight()] : [el.outerHeight(), 0]
},{
queue: false,
duration: duration,
easing: easing,
display: isOpen ? 'none' : 'block',
begin: setNodeClass($(this).parent(), isOpen),
complete: function(){
if(!isOpen) $(this).css('height', 'auto');
}
});
// jQuery fallback animate element
} else {
setNodeClass($(this).parent(), isOpen);
el.slideToggle(duration);
}
// We can't have nodes as links unfortunately
e.preventDefault();
});
// Function for updating node class
function setNodeClass(el, isOpen) {
if(isOpen) {
el.removeClass('mtree-open').addClass('mtree-closed');
} else {
el.removeClass('mtree-closed').addClass('mtree-open');
}
}
// List animation sequence
if($.Velocity && listAnim) {
$.Velocity.Sequences.list = function (element, options, index, size) {
$.Velocity.animate(element, {
opacity: [1,0],
translateY: [0, -(index+1)]
}, {
delay: index*(duration/size/2),
duration: duration,
easing: easing
});
};
}
// Fade in mtree after classes are added.
// Useful if you have set collapsed = true or applied styles that change the structure so the menu doesn't jump between states after the function executes.
if($('.mtree').css('opacity') == 0) {
if($.Velocity) {
$('.mtree').css('opacity', 1).children().css('opacity', 0).velocity('list');
} else {
$('.mtree').show(200);
}
}
}
}(jQuery, this, this.document));
I've added a background image using CSS and :before but the image is not clickable.
Is there a way to add it on the JS so that it can be clicked as well?
I've tried to see where to add some code but actually I'm clueless, should it be between lines 29 and 37?
You can see it in: https://tester.medicalfa.gr/test/katastima/
Ok I fixed it via css, the arrows now appears like they are clickable.
The solution is to remove the code I had added:
ul.mtree.default li.mtree-open:before {
display: inline-block;
margin-left: 200px;
background: url("../images/arrow-down.svg") no-repeat center center;
background-size: 20px 20px;
}
I removed the :before as it adds the arrow behind the text and now appears after the text as it's supposed to.
The code looks like this now:
ul.mtree.default li.mtree-open {
display: block ;
background: url("../images/arrow-down.svg") no-repeat center center;
background-size: 15px 15px;
background-position:top right;
}
I'm trying to change the design of my hamburger navigation as the user scrolls. I feel I have come semi close https://jsfiddle.net/g95kk7yh/6/
$(document).ready(function(){
var scroll_pos = 0;
$(document).scroll(function() {
scroll_pos = $(this).scrollTop();
if(scroll_pos > 10) {
$(".navigation").css('background', 'rgba(255, 0, 0, 0.5)');
$(".navigation span").css('background', '#bdccd4');
} else {
$(".navigation").css('background', 'transparent');
$(".navigation span").css('background', '#fff');
}
});
});
Here is what I'm trying to achieve
The main problem I'm having is assigning the correct width and height of the red box without repositioning the navigation menu as a whole.
Also is it possible to only have these changes at 600px and under (as you can see this is when the hamburger menu shows).
I have used #potatopeelings post and have changed few lines and added.
.myClass {
margin-right: -25px;
width: 85px;
height: 85px;
background-color: rgba(255, 0, 0, 0.5);
}
Fiddle: https://jsfiddle.net/moj7z2b4/2/
This covers only the 2nd part of the question (thanks #webeno and #MarcusPorter for catching that). Refer to 7urkm3n's solution for an answer that covers both parts of the question.
Instead of changing the CSS properties in your script, just add / remove a class that has the properties you need.
...
if(scroll_pos > 10) {
$(".navigation").addClass('myClass')
} else {
$(".navigation").removeClass('myClass')
}
...
Then wrap your class CSS rules with
#media screen and (max-width: 600px) {
.myClass {
...
}
.myClass span {
...
}
}
so that these rules only apply on screen size < 600px
Fiddle - https://jsfiddle.net/moj7z2b4/
I have come across this problem as well, it was when I was creating the 'preloader' thing for my website. Anyway, the way I resolved my problem was to change background-color with backgroundColor. Make sure backgroundColor isn't in quotation marks, just type it in as you would do with a variable or a function, etc.
From jQuery API Docs:
Also, jQuery can equally interpret the CSS and DOM formatting of multiple-word properties. For example, jQuery understands and returns the correct value for both .css({ "background-color": "#ffe", "border-left": "5px solid #ccc" }) and .css({backgroundColor: "#ffe", borderLeft: "5px solid #ccc" }). Notice that with the DOM notation, quotation marks around the property names are optional, but with CSS notation they're required due to the hyphen in the name.
This code should work but I haven't tested it. I changed your .css('property', 'value') to .css({'property': 'value'});
$(document).ready(function() {
var scroll_pos = 0;
$(document).scroll(function() {
scroll_pos = $(this).scrollTop();
if (scroll_pos > 10) {
$(".navigation").css({
backgroundColor: 'rgba(255, 0, 0, 0.5)'
});
$(".navigation span").css({
'background': '#bdccd4'
});
} else {
$(".navigation").css({
backgroundColor: 'transparent'
});
$(".navigation span").css({
'background': '#fff'
});
}
});
});
in my website, there are projects icons that have a layer on mouseover, that displays titles.
What I looking for is to have that layer constantly there when viewing the site on mobiles.
There is this piece of javascript code that apparently deals with that effect:
/* Set Default Text Color for all elements */
$(".ut-hover").each(function(index, element) {
var text_color = $(this).closest('.ut-portfolio-wrap').data('textcolor');
$(this).find(".ut-hover-layer").css({ "color" : text_color });
$(this).find(".ut-hover-layer").find('.portfolio-title').attr('style', 'color: '+text_color+' !important');
});
$('.ut-hover').on('mouseenter touchstart', function() {
var hover_color = $(this).closest('.ut-portfolio-wrap').data('hovercolor'),
hover_opacity = $(this).closest('.ut-portfolio-wrap').data('opacity');
$(this).find(".ut-hover-layer").css( "background" , "rgba(" + hover_color + "," + hover_opacity+ ")" );
$(this).find(".ut-hover-layer").css( "opacity" , 1 );
});
$('.ut-hover').on('mouseleave touchend', function() {
$(this).find(".ut-hover-layer").css( "opacity" , 0 );
});
The css of the layer containing the text is "ut-hover-layer"
I need to modify that script so that IF the site is seen on a mobile screen, the "ut-hover-layer" is visible on load and always stays, so no mouseover is supposed to happen.
Anyone would have a solution to achieve that ?
if that can help, here is the link to the site
Thanks in advance !
According to to another answer on stack (What is the best way to detect a mobile device in jQuery?) You should detect if the device on which your page is displayed is a smartphone and if so, you should set ut-hover-layers opacity to 1 like this:
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( navigator.userAgent ) ) {
jQuery( '.ut-hover-layer' ).each( function() {
jQuery( this ).css( 'opacity', '1' ).css( 'background' , 'rgba( 242, 35, 244, 0.8 )' );
});
}
However I think if You try to detect smartphone this way:
if( jQuery( window ).width() < 768 ) {
jQuery( '.ut-hover-layer' ).each( function() {
jQuery( this ).css( 'opacity', '1' ).css( 'background' , 'rgba( 242, 35, 244, 0.8 )' );
});
}
it will still work.
Also pure js way
if( document.body.clientWidth < 768 ) {
var elems = document.getElementsByClassName( 'ut-hover-layer' ),
i = 0;
for( ; i < elems.length; i += 1 ) {
elems[i].style.background = 'rgba( 242, 35, 244, 0.8 )';
elems[i].style.opacity = '1';
}
}
Another option is going for a media query and putting this to your css:
#media screen and (max-width: 1024px) and (min-width: 481px)
.ut-hover-layer {
opacity: 1!important;
top: 50%;
background: rgba(242, 35, 244, 0.8);
}
}
But then You will have some useless handler in your code.
I hope I understand You correctly and this helps.
I want to create a transparent highlight to cover a particular DOM element.
My highlight will occasionally be switched from one element to another.
The basic implementation is easy: create an empty <div class='highlight'/> with css attributes for background-color and opacity.
But having it follow another element seems hard, because the highlighted element could move or resize or show or hide, and I'm not sure how to have the highlight follow it.
There must be someone who's done this before -- Firebug seems to have the effect I want, but I don't know how to delve into the Firebug source code + find the relevant piece.
Any suggestions?
Any reason you can't use the jQuery highlight effect?
Simple HTML element at the top of your DOM:
<div id="highlighter" class="highlight"></div>
Style it with abstracted CSS:
div {
border:1px solid #CCC;
position:relative;
}
#highlighter {
display:none;
border:none;
}
.highlight {
z-index:999999;
background-color:yellow;
opacity:.5;
-moz-opacity:.5;
position:absolute;
width:100%;
height:100%;
}
The JQuery is a little more complicated if you want the highlighter to tag along with your animated divs:
$('div').not('.highlight').on('click', function() {
var $this = $(this);
if($this.find('.highlight').length > 0) {
$this.find('.highlight').remove();
} else {
$('#highlighter').clone().appendTo($this).
width($this.width()).
height($this.height()).
css({
'top': '0px',
'left': '0px'
}).
show();
}
});
(function morph(){
$('div').not('.highlight').each(function(){
var $this = $(this);
$this.animate({
'top' : someVal + 'px',
'left' : someVal + 'px',
'width': someVal + 'px',
'left' : someVal + 'px',
}, {
duration: 1000,
step: function(){
// Here we tell the highlighter to sync up with the morphed parent.
$this.find('.highlight').width($this.width()).height($this.height());
},
complete: morph
});
});
}());
Demo: http://jsfiddle.net/AlienWebguy/7t4jT/
_createInput: function(){
var self = this;
var input = document.createElement("input");
input.setAttribute('type', 'file');
input.setAttribute('name', this._settings.name);
if(this._settings.multiple) input.setAttribute('multiple', 'multiple');
addStyles(input, {
'position' : 'absolute',
// in Opera only 'browse' button
// is clickable and it is located at
// the right side of the input
'right' : 0,
'margin' : 0,
'padding' : 0,
'fontSize' : '480px',
// in Firefox if font-family is set to
// 'inherit' the input doesn't work
'fontFamily' : 'sans-serif',
'cursor' : 'pointer'
});
var div = document.createElement("div")
div.className = 'tooltip';
div.id = 'ajaxupload-div';
div.title = 'Attach a picture';
addStyles(div, {
'display' : 'block',
'position' : 'absolute',
'overflow' : 'hidden',
'margin' : 0,
'padding' : 0,
'opacity' : 0,
// Make sure browse button is in the right side
// in Internet Explorer
'direction' : 'ltr',
//Max zIndex supported by Opera 9.0-9.2
'zIndex': 2147483583
});
// Make sure that element opacity exists.
// Otherwise use IE filter
if ( div.style.opacity !== "0") {
if (typeof(div.filters) == 'undefined'){
throw new Error('Opacity not supported by the browser');
}
div.style.filter = "alpha(opacity=0)";
}
addEvent(input, 'change', function(){
if ( ! input || input.value === ''){
return;
}
// Get filename from input, required
// as some browsers have path instead of it
var file = fileFromPath(input.value);
if (false === self._settings.onChange.call(self, file, getExt(file))){
self._clearInput();
return;
}
// Submit form when value is changed
if (self._settings.autoSubmit) {
self.submit();
}
});
addEvent(input, 'mouseover', function(){
addClass(self._button, self._settings.hoverClass);
});
addEvent(input, 'mouseout', function(){
removeClass(self._button, self._settings.hoverClass);
removeClass(self._button, self._settings.focusClass);
if (input.parentNode) {
// We use visibility instead of display to fix problem with Safari 4
// The problem is that the value of input doesn't change if it
// has display none when user selects a file
input.parentNode.style.visibility = 'hidden';
}
});
addEvent(input, 'focus', function(){
addClass(self._button, self._settings.focusClass);
});
addEvent(input, 'blur', function(){
removeClass(self._button, self._settings.focusClass);
});
div.appendChild(input);
document.body.appendChild(div);
this._input = input;
},
This JS starting at var div = document.createElement("div") produces this div tag:
<div style="display: block; position: absolute; overflow: hidden; margin: 0pt; padding: 0pt; opacity: 0; direction: ltr; z-index: 2147483583; left: 102px; top: 323.5px; width: 102px; height: 28px; visibility: hidden;">
I see where all the other attributes get changed, but how the heck can I change 'visibility: hidden;" ???
It's making me crazy please help.
Find the below section in your code i have star commented where you can modify:
addStyles(div, {
'display' : 'block', /*You cane set display none here to hide the div.*/
'position' : 'absolute',
'overflow' : 'hidden',
'margin' : 0,
'padding' : 0,
'opacity' : 0,
// Make sure browse button is in the right side
// in Internet Explorer
'direction' : 'ltr',
//Max zIndex supported by Opera 9.0-9.2
'zIndex': 2147483583,
'visibility':'hidden' /* If you don't set display none , you can set your style attribute you want to change like visibility here also */
});
Ok, to make it visible find the below code and try setting visibility there:
if (input.parentNode) {
// We use visibility instead of display to fix problem with Safari 4
// The problem is that the value of input doesn't change if it
// has display none when user selects a file
input.parentNode.style.visibility = 'hidden'; /* try setting visibility='visible' here */
}
If that doesn't work then check if any css is overriding the style property of the div by inspecting the div in your browser.
if jQuery is an option, I know there's the command $('#div').css('attribute','value');
visibility hidden is set when you "mouseout" off that input
addEvent(input, 'mouseout', function(){
removeClass(self._button, self._settings.hoverClass);
removeClass(self._button, self._settings.focusClass);
if (input.parentNode) {
// We use visibility instead of display to fix problem with Safari 4
// The problem is that the value of input doesn't change if it
// has display none when user selects a file
input.parentNode.style.visibility = 'hidden';
}
});
you can either remove that event binding or change the statement to input.parentNode.style.visibility = 'visible';