I have an IMG element c. The following works to change its cursor (in Chrome):
c.style.cursor='-webkit-zoom-out';
But if I try to add compatibility for other browsers, as in the following, it breaks:
c.style.cursor='-webkit-zoom-out, -moz-zoom-out';
(And I haven't even gotten to trying to link a .cur for IE-compatibility....) What's the correct syntax to add multiple values to a style element?
You have to add them separately:
c.style.cursor = '-webkit-zoom-out';
c.style.cursor = '-moz-zoom-out';
Unfortunately zoom-in and zoom-out are not supported by Internet Explorer yet. See the MDN Cursor: Browser compatibility.
Demo
Try before buy
Alternatively you can create a CSS class that sets the correct styles and add or remove this class using JavaScript if you need to toggle it.
Related
I started using cypress nowadays to learn better and deeper. I am faced with a problem that I can't handle. The problem is some kind of GUI effect working with mouse hover. While hovering my mouse on the element I can't see any information change into DOM. There are just ::before and ::after words appearing. I think I have to solve that problem with some javascript tricks. unfortunately, I am new to javascript and I don't have any idea if you help me I would be very happy. Thank you! (I want to assert in some way that grey background and plus icon is shown or not)
generically look like that
after the mouse hovers this grey background and plus icon comes
you can see elements DOM here
you can see the changes after the mouse hovers element
You can use the cypress-real-events plugin.
To install use the command:
npm i cypress-real-events
Then inside your cypress/support/e2e.{js,ts}, write:
import "cypress-real-events/support";
And in your code you can directly write:
cy.get("selector").realHover('mouse')
//Add assertions
Note: Since the above plugin uses Chrome DevTools Protocols to simulate native events, hence this will only work with Chromium-based browsers, so no firefox.
Into cypress' test try to use the method cy.wait("time here") following hover command.
This is very simple but for visual test this is so useful.
In order to access the :before or :after of an element, we have to do a little Cypress and JavaScript magic. This is answer is mostly from this link.
cy.get('.myClass')
.then($els => {
// get Window reference from element
const win = $els[0].ownerDocument.defaultView
// use getComputedStyle to read the pseudo selector
const before = win.getComputedStyle($els[0], ':before')
// read the value of the `content` CSS property
const contentValue = before.getPropertyValue('content')
// The above lines are just how we tell Cypress to get the `:before` value.
// There isn't a ton to understand outside of really diving into how elements and windows work together
expect(content).to.equal('foo');
})
So, using that same example, we can check for any CSS property on the element. For example, font-size:
cy.get('.myClass')
.then($els => {
const win = $els[0].ownerDocument.defaultView
const before = win.getComputedStyle($els[0], ':before')
const fontSize = before.getPropertyValue('font-size') // instead of `'font-size'`, you can substitute any CSS property
expect(fontSize).to.equal('20');
})
This can also be applied to :after, changing out ($els[0], ':before') with ($els[0], ':after').
Looking at your screenshots, I think you have a gray overlay element covering the original incident element.
The only code I can suggest is from the limited information is
cy.get('#IN-578')
.trigger('mouseover')
.should('not.be.visible')
The overlay has opacity 50%, so you can still see the incident details but from Cypress point of view the incident is covered so it will not be "visible".
If you don't have any luck with 'mouseover', try .realHover() from cypress-real-events.
After the above code, you should look for the overlay element in DOM and the + icon in the middle, select that icon and click it to take the action.
When setting multiple transform properties on DOM element style, the browser is not showing all set properties (both -webkit-, ms, and regular) - for example :
element.style.tranform = 'rotate(90deg)';
element.style.webkitTranform = 'rotate(90deg)';
element.style.msTranform = 'rotate(90deg)';
will produce the following inline style attribute
<div style="transform:rotate(90deg)" ></div>;
This means that the browser is not settings ALL of the properties, instead it is taking only one of them.
This is a problem, because we have to send the HTML as is to the server side in order to produce PDF. so, instead we have found a workaround which works (kind of) - using element.setAttribute('style','transform...-webkit- etc...');
The above approach works, but we have to reconstruct the style attribute each time, and the transform must be applied only AFTER all of the other properties have been set, which is not so elegant.
Does anyone knows how to work around this?
Thanks in advance!
I think you've already found your workaround: Using setAttribute. It's not pretty, but with prefixed properties, you can't trust the HTML from browser X will work in browser Y, since there's no reason browser X would include invalid (from its perspective) properties when generating the text for the style attribute's value.
With your workaround, you'll need to be careful of at least two things:
That you test carefully in your target browsers. I think all browsers faithfully retain what you set with setAttribute (subject to #2 below), but...test. :-)
Be sure nothing in your code sets a style via the style object after you've done the setAttribute thing, since that will make the browser drop the (from its perspective) invalid style text. For instance, on Chrome, Firefox, Edge and Safari (at least), the following drops the invalid foo: bar style when I set fontWeight:
var element = document.getElementById("element");
element.setAttribute("style", "foo: bar");
console.log("before using style:", element.getAttribute("style"));
element.style.fontWeight = "bold";
console.log("after using style: ", element.getAttribute("style"));
<div id="element"></div>
I'm using the CSS content attribute to pass some values from my LESS stylesheet to JavaScript (to use some colors defined in LESS in Canvas elements).
To make my life easier I decided to place these values in a easy way to parse them in JavaScript.
LESS code:
div#colorChart-critical {
content:'#{critical-highest},#{critical-veryhigh},#{critical-high},#{critical-low},#{critical-medium},#{critical-verylow}';
}
which when compiled brings the following CSS:
div#colorChart-critical6 {
content: '#ff0000,#ff7200,#fffc00,#0000ff,#a200ff,#00ff00';
}
Then I try to read them using jQuery:
$("div#colorChart-critical").css("content").split(",");
The problem is that in IE9 calling $("div#colorChart-critical").css("content") is returning the string "normal" for some reason. Opera, Firefox, Safari and Chrome works fine.
Why does this happen in IE9?
Any work-around this issue on IE9? If not any other CSS atribute I can put random texts in?
I could use something like:
background: url(#ff0000,#ff7200,#fffc00,#0000ff,#a200ff,#00ff00);
But this would generate errors on the console.
It's because content as defined in CSS2.1 doesn't work on elements, only on the :before and :after pseudo-elements. IE9 is simply following the CSS2.1 spec here, which mandates that content on elements be computed to normal, always.
I don't know why other browsers would return the value you have defined, especially considering that .css() makes use of getComputedStyle() on those browsers. If they're implementing CSS2.1 content, then they're violating CSS2.1 by not computing the value to normal. If they're preparing for a late CSS3 implementation, whatever that may be, then it would make sense that they implement it on actual elements somehow... shame on them either way.
Which brings me to another point: if you're not actually trying to use CSS to modify the content of an element, don't use content, even if the fact that it's not defined for use with elements is the reason you're making use of this technique in the first place. You can try assigning those colors to certain classes, creating a hidden element and querying that element's color styles instead.
BoltClock answer shows the cause of my problems. I found a work-around by using the font-family instead of the content CSS property.
My LESS code:
div#colorChart-maincolors {
font-family: '#{colorChart1},#{colorChart2},#{colorChart3},#{colorChart4},#{colorChart5},#{colorChart6}';
}
Which compiled into CSS gives:
div#colorChart-maincolors {
font-family: '#c0392b,#2980b9,#2ecc71,#f1c40f,#ecf0f1,#34495e';
}
The string can be acquired using:
removeQuotes= function(string) {
return string.replace(/^['"]+|\s+|\\|(;\s?})+|['"]$/g, '');
};
removeQuotes($("#colorChart-maincolors").css("font-family")); //add a .split(',') to get the colors as an array
The function removeQuotes is necessary because each browser adds a different kind of quotes into the return of getComputedStyle (and by extension the jQuery .css() method). IE9 adds a double quote, Webkit adds a single quote.
See this post on CSS tricks: http://css-tricks.com/making-sass-talk-to-javascript-with-json/ for more information.
you can use replace(/["']/g, "") to remove extra quotation from string
""string"" will be change to "string"
I need to make my application run on all browsers and I have a div for which I set the css class in Javascript using the syntax
divNew.className = "highlightItem";
It works ok on IE, but when it comes to Firefox, Opera and Chrome it's not working at all. I have also tried other versions such as
var theDiv = document.getElementById(divNew);
theDiv.setAttribute("class", "highlightItem");
theDiv.setAttribute("className", "highlightItem");
with no success. Setting all the attributes through style isn't working either.
Are there any other ways of setting the css class for a div so that it works on the above mentioned browsers? Thanks a lot!
On this line:
var theDiv = document.getElementById(divNew);
You need the id of your div there as a string:
var theDiv = document.getElementById("my-div-ID");
Other than that it should work.
If you want to save yourself time with cross-browser issues look into jQuery - you would just do:
$("#my-div-ID").addClass("highlightItem");
I'm programmatically changing the option children of a select element with jQuery.
The changes are being applied to the DOM, but are not visible on the screen.
This is what I get on the screen:
And this is what I see when I inspect the select element:
Here is the code that I use to update the select element:
select.empty();
$.each(this.entries, function() {
var option = $$("<option/>");
option.attr("value", this.value);
option.text(this.label);
select.append(option);
});
This clearly seems like a bug to me. Can anybody tell me what is wrong with this or indicate a workaround ?
Note: for reasons beyond my control, the page is in quirks mode.
The documentation for the SelectElement is here: https://developer.mozilla.org/en-US/docs/DOM/HTMLSelectElement
You can add options like this:
$("#sel")[0].options.add(new Option("test", "123")); //haven't tested all browsers
The docs say that you call add on the select element itself, passing in an option node:
$("#sel")[0].add($("<option>").val("456").prop("text", "Test2")[0], null);
both tested (and working) in IE8 here: http://jsfiddle.net/82gCq/2/
Note — The docs for HTMLOptionsCollection does not specify an add method, so it is not standardized, and its implementation will be left to the browser (if they implement it at all).
The good news is that $("#sel")[0].add(new Option("test3", "789")); works in IE8, and should work in other browsers as well.
Try changing
var option = $$("<option/>");
to
var option = $("<option></option>");
I removed the double dollar sign (I believe that was a typo), and changed the option element to not use the self-closing syntax. I've run into issues using self-closing tags on certain elements (script,textarea,iframe), this could be another example of where a self-closing tag could be a problem.