I want either remove or reset a style applied on a particular DOM node using JS.
node.style.webkitTransitionDuration = '5000ms';
node.style.webkitTransformOrigin = '200px 200px';
node.style.webkitTransform = 'rotateZ(25rad)';
I want to reset/set webkitTransform time and again on a fire of an event
Tried like this
node.style.webkitTransform = 'rotateZ(0rad)';
node.style.webkitTransform = 'rotateZ(25rad)';
But its not working.
P.S. Can not use any framework.
Here's an example that should fit your needs. It toggles when you click on the document. Note: it of course only works in Webkit-based browsers.
animateNode(document.getElementById("test"), "5000ms", "200px 200px", "rotateZ(25rad)");
var toggle = toggleValue();
function animateNode(node, duration, origin, transform)
{
node.style['webkitTransitionDuration'] = duration;
node.style['webkitTransformOrigin'] = origin;
node.style['webkitTransform'] = transform;
}
function toggleValue() {
var num = 1;
return function ()
{
return ++num;
};
}
document.onclick = function()
{
var toggleNum = toggle();
if(toggleNum % 2 === 0)
{
animateNode(document.getElementById("test"), "5000ms", "200px 200px", "rotateZ(0rad)");
}else if(toggleNum % 2 === 1)
{
animateNode(document.getElementById("test"), "5000ms", "200px 200px", "rotateZ(25rad)");
}
}
http://jsfiddle.net/GdGw7/3/
If you are looking to remove the rule from the element then this should work:
node.style.webkitTransform = '';
You say you don't want to use a framework. but if it is OK (according to your comment) to do so:
You can use jQuery:
so you can do in jQuery:
$('selector').css({
webkitTransitionDuration = '5000ms',
webkitTransformOrigin = '200px 200px',
webkitTransform = 'rotateZ(25rad)'
})
you can clear out the style element with:
$('selector').attr('style','');
add class:
$('selector').addClass('newClass');
remove class:
$('selector').removeClass('rClass');
Related
So I have created this javascript that animates a certain place using it's ID.
The problem is that there are many of those on the site and meaning this I'd have to duplicate this function a lot of times just to replace the x in getElementById("x").
So here is the code I fully done by myself:
var popcount = 0;
var opanumber = 1;
var poptimeout;
function pop() {
if (popcount < 10) {
popcount++;
if (opanumber == 1) {
document.getElementById("nav1").style.opacity = 0;
opanumber = 0;
poptimeout = setTimeout("pop()", 50);
}
else {
document.getElementById("nav1").style.opacity = 1;
opanumber = 1;
poptimeout = setTimeout("pop()", 50);
}
}
else {
popcount = 0;
document.getElementById("nav1").style.opacity = 1;
}
}
function stoppop() {
clearTimeout(poptimeout);
popcount = 0;
document.getElementById("nav1").style.opacity = 1;
}
I would gladly appreciate any information on how I could solve this situation and also any tutorials about using classes and "this".
Something like this; rather than hard code a value into a function it is better to pass the value in so you can reuse the function on more than one thing. In this case you can now call startPop and stopPop with the name of a CSS class.
var popTimeout;
function setOpacity(className, value) {
Array.prototype.forEach.call(
document.getElementsByClassName(className),
function(el) {
el.style.opacity = value;
}
);
}
function pop(className, popCount, opaNumber) {
if (popCount < 10) { //Must be even number so you end on opacity = 1
setOpacity(className, opaNumber);
popTimeout = setTimeout(function() {
pop(className, popCount++, 1-opaNumber);
}, 50);
}
}
function startPop(className) {
pop(className, 0, 0);
}
function stopPop(className) {
clearTimeout(popTimeout);
setOpacity(className, 1);
}
In case you are wondering about the 1 - opaNumber; this is a simpler way of switching a value between 1 and 0. As 1-1=0 and 1-0=1.
Well you started out with recognizing where you have the problem and that's already a good thing :)
To make your code a bit more compact, and get as many things as possible out of the local scope, you could check the following implementation.
It is in a sense a small demo, where I tried adding as much comments as possible.
I edited a bit more after realizing you rather want to use classnames instead of id's :) As a result, I am now rather using the document.querySelectorAll that gives you a bit more freedom.
Now you can call the startPop function with any valid selector. If you want to pop purely on ID, you can use:
startPop('#elementId');
or if you want to go for classes
startPop('.className');
The example itself also add's another function, nl trigger, that shows how you can start / stop the functions.
I also opted to rather use the setInterval method instead of the setTimeout method. Both callback a function after a certain amount of milliseconds, however setInterval you only have to call once.
As an extra change, stopPop also now uses the document.querySelectorAll so you have the same freedom in calling it as the startPop function.
I added 2 more optional parameters in the startPop function, namely total and callback.
Total indicates the maximum times you wish to "blink" the element(s), and the callback provides you with a way to get notified when the popping is over (eg: to update potential elements that started the popping)
I changed it a bit more to allow you to use it for hovering over an element by using the this syntax for inline javascript
'use strict';
function getElements( className ) {
// if it is a string, assume it's a selector like #id or .className
// if not, assume it's an element
return typeof className === "string" ? document.querySelectorAll( className ) : [className];
}
function startPop(className, total, callback) {
// get the element once, and asign a value
var elements = getElements( className ),
current = 0;
var interval = setInterval(function() {
var opacity = ++current % 2;
// (increase current and set style to the left over part after dividing by 2)
elements.forEach(function(elem) { elem.style.opacity = opacity } );
// check if the current value is larger than the total or 10 as a fallback
if (current > (total || 10)) {
// stops the current interval
stopPop(interval, className);
// notifies that the popping is finished (if you add a callback function)
callback && callback();
}
}, 50);
// return the interval so it can be saved and removed at a later time
return interval;
}
function stopPop(interval, className) {
// clear the interval
clearInterval(interval);
// set the opacity to 1 just to be sure ;)
getElements( className ).forEach(function(elem) {
elem.style.opacity = 1;
});
}
function trigger(eventSource, className, maximum) {
// get the source of the click event ( the clicked button )
var source = eventSource.target;
// in case the attribute is there
if (!source.getAttribute('current-interval')) {
// start it & save the current interval
source.setAttribute('current-interval', startPop(className, maximum, function() {
// completed popping ( set the text correct and remove the interval )
source.removeAttribute('current-interval');
source.innerText = 'Start ' + source.innerText.split(' ')[1];
}));
// change the text of the button
source.innerText = 'Stop ' + source.innerText.split(' ')[1];
} else {
// stop it
stopPop(source.getAttribute('current-interval'), className);
// remove the current interval
source.removeAttribute('current-interval');
// reset the text of the button
source.innerText = 'Start ' + source.innerText.split(' ')[1];
}
}
<div class="nav1">
test navigation
</div>
<div class="nav2">
Second nav
</div>
<div class="nav1">
second test navigation
</div>
<div class="nav2">
Second second nav
</div>
<a id="navigation-element-1"
onmouseover="this.interval = startPop( this )"
onmouseout="stopPop( this.interval, this )">Hover me to blink</a>
<button type="button" onclick="trigger( event, '.nav1', 100)">
Start nav1
</button>
<button type="button" onclick="trigger( event, '.nav2', 100)">
Start nav2
</button>
If you do want to take it back to using IDs, then you will need to think about popTimeout if you run this on more than one element at a time.
function setOpacity(id, value) {
document.getElementById(id).style.opacity = value;
}
function runPop(id) {
function pop(id, popCount, opaNumber) {
if (popCount < 10) { //Must be even number so you end on opacity = 1
setOpacity(id, opaNumber);
popTimeout = setTimeout(function() {
pop(id, popCount++, 1-opaNumber);
}, 50);
}
}
var popTimeout;
pop(id, 0, 0);
return function() {
clearTimeout(popTimeout);
setOpacity(id, 1);
}
}
var killPop = [];
function startPop(id) {
killPop[id] = runPop(id);
}
function stopPop(id) {
killPop[id]();
}
It works on the premade divs but on the newly made one, it doesn't work. How do I fix that?
Here's the code on the event for changing the zIndex:
$(".widget").mousedown(function (event) {
var ws = document.getElementById("widget-workspace");
var list = ws.children, x=0;
for(x=0;x<ws.children.length;x++){
console.log(ws.children[x].id);
$("#"+ws.children[x].id).css("zIndex", 99);
}
$(this).css("zIndex", 100);
});
Now, here's the code for adding the div:
document.getElementById("widget-dialog-button").onclick = function () {
var ws = document.getElementById("widget-workspace");
var list = ws.children;
var x, w = document.getElementById("select-widget");
var widget = w.options[w.selectedIndex].value;
var c = document.getElementById("select-widget-color");
var color = c.options[c.selectedIndex].value;
var left = 0, top = 25, docWidth = ws.offsetWidth, check;
for(x=0; x < list.length; x++){
docWidth -= 325;
left += 325;
if(docWidth < 325){
check = false;
docWidth = ws.offsetWidth;
left = 0;
top += 210;
}else{
check = true;
}
}
x-=2;
var iDiv = document.createElement('div');
iDiv.id = 'widget_'+x;
iDiv.className = 'widget';
iDiv.style.backgroundColor = color;
iDiv.style.left = left;
iDiv.style.top = top;
ws.appendChild(iDiv);
$(function() {
$( ".widget" ).draggable();
});
};
If you guys need anything else, feel free to ask.
The answer is quite simple :
"It works on the premade divs but on the newly made one, it doesn't work. How do I fix that?"
It's normal :
$(".widget").mousedown(...);
// should be read as (except that a new var is not created)
var $currentlyExistingWidgets = $(".widget");
$currentlyExistingWidgets.mousedown(...);
To each element of class widget currently existing, you bind an event.
If you want to bind events to elements not existing... You have to reconider your way of thinking and then bind an event listener to a container always existing, with an event delegation mechanism and proper filtering.
For example the following code should catch the event for all .widget, created before or after :
// http://api.jquery.com/on/
$('body').on('mousedown', '.widget', function() { ... });
If you want to search and learn, the key concepts are event bubbling and event delegation.
The way you're attaching the mousedown listener means that only the element that exist at that point will be listened to. Use the on method:
// May want to use something other than body
$('body').on('mousedown', '.widget', function() {
console.log('go');
});
Docs
I don't know much about jQuery but I've been using the following javascript code to make a table keep the scroll bar location upon pageback:
<script type="text/javascript">
window.onload = function () {
var strCook = document.cookie;
if (strCook.indexOf("!~") != 0) {
var intS = strCook.indexOf("!~");
var intE = strCook.indexOf("~!");
var strPos = strCook.substring(intS + 2, intE);
document.getElementById("grdWithScroll").scrollTop = strPos;
}
}
function SetDivPosition() {
var intY = document.getElementById("grdWithScroll").scrollTop;
document.cookie = "yPos=!~" + intY + "~!";
}
</script>
and
<div id="grdWithScroll" onscroll="SetDivPosition()">
It works great for a single div. But how could I extend this for use with a second div section?
Instead of using document.getElementById, you can asign the same class name to all the divs for which you want this functionality, and then user the jQuery selector $(".scrollgrid") to select the multiple divs, and store the scroll tops. If you do not want to use jQuery, you can look at the custom functions that people have written to select the elements by class name. Here is an example.
http://www.netlobo.com/javascript_getelementsbyclassname.html
Instead of a single div id, you could use class attribute to define all the divs you want the feature to be used on.
<div id="grdWithScroll" class="coolScroll" onscroll="SetDivPosition()">
</div>
<div id="abcWithScroll" class="coolScroll" onscroll="SetDivPosition()">
</div>
Use jQuery (or other libraries) to easily select all divs with said class and access the scrollTop attribute
$('.coolScroll').each( function()
{
// do something with scrollTop
}
You could also use the class selector to set the onscroll function.
$('.coolScroll').attr( 'onscroll' , 'javascript:SetDivPosition()' );
Found what I was looking for here:
http://social.msdn.microsoft.com/Forums/nb-NO/jscript/thread/ad18ed20-8ae2-4c13-9a51-dcb0b1397349
<script language="javascript" type="text/javascript">
//This function sets the scroll position of div to cookie.
function setScrollPos() {
var div1Y = document.getElementById('div1').scrollTop;
var div2Y = document.getElementById('div2').scrollTop;
document.cookie = "div1Pos=!*" + div1Y + "*!" +
" div2Pos=|*" + div2Y + "*|";
}
///Attaching a function on window.onload event.
window.onload = function () {
var strCook = document.cookie; if (strCook.indexOf("!~") != 0) {
var intS = strCook.indexOf("!~");
var intE = strCook.indexOf("~!");
var strPos = strCook.substring(intS + 2, intE);
document.body.scrollTop = strPos;
}
/// This condition will set scroll position of <div> 1.
if (strCook.indexOf("iv1Pos=!*") != 0) {
var intdS = strCook.indexOf("iv1Pos=!*");
var intdE = strCook.indexOf("*!");
var strdPos = strCook.substring(intdS + 9, intdE);
document.getElementById('div1').scrollTop = strdPos;
}
/// This condition will set scroll position of <div> 2.
if (strCook.indexOf("iv2Pos=!*") != 0) {
var intdS = strCook.indexOf("iv2Pos=|*");
var intdE = strCook.indexOf("*|");
var strdPos2 = strCook.substring(intdS + 9, intdE);
document.getElementById('div2').scrollTop = strdPos2;
}
}
</script>
I wrote this code for 508 compliance but after the users tabs off of it I want the element to go way how can I do this? here is the below:
handleInteraction:function(focusable){
this.setElements();
var totalAllowed = (this.elements.totalChar[0].innerHTML);
var value = this.obj.value;
var chars = value.length;
var charsLeft = parseInt(totalAllowed) - parseInt(chars);
if (charsLeft >= 0 || (typeof focusable=='boolean' && focusable==false)){
this.elements.leftChar[0].innerHTML = charsLeft;
this.elements.charLeftp.removeClass("error");
}
else {
this.obj.value = value.substring(0, totalAllowed);
this.elements.leftChar[0].innerHTML = 0;
this.elements.charLeftp.addClass("error")
var divNA = dojo.byId("max-"+this.obj.id);
if (divNA){
dojo.destroy(divNA);
}
divNA = dojo.create("a",{"id":"max-"+this.obj.id,"class":"hide-fromsighted","innerHTML":"<h5>This textarea has reached the maximum allowed number of characters. Please navigate backwards!</h5>","tabindex":"-1"});
dojo.place(divNA,this.obj,'after');
divNA.focus();
/*
* Here apply the onblur event to kill the <a>
*/
}
I'm assuming you are using the Dojo Toolkit. You can destroy the <a> tag with dojo.destroy and you can use dojo.stopEvent to stop that <a> event propagation.
http://www.dojotoolkit.org/reference-guide/dojo/destroy.html#dojo-destroy
http://www.dojotoolkit.org/reference-guide/dojo/stopEvent.html#dojo-stopevent
what about:
divNA.onblur = function() { divNA.destroy(); }
Would that work?
How can I do this?
I tried
$('link[title="mystyle"]').remove();
and although the element is removed, the styles are still applied to the current page (in both Opera and Firefox).
Is there any other way?
To cater for ie you have to set the stylesheet to be disabled as it keeps the css styles in memory so removing the element will not work, it can also cause it to crash in some instances if I remember correctly.
This also works for cross browser.
e.g
document.styleSheets[0].disabled = true;
//so in your case using jquery try
$('link[title=mystyle]')[0].disabled=true;
I managed to do it with:
$('link[title="mystyle"]').attr('disabled', 'disabled');
it seems this is the only way to remove the styles from memory.
then I added:
$('link[title="mystyle"]').remove();
to remove the element too.
To disable your selected stylesheet:
$('link[title="mystyle"]').prop('disabled', true);
If you never want that stylesheet to be applied again, you can then .remove() it. But don’t do that if you want to be able to re-enable it later.
To re-enable the stylesheet, do this (as long as you didn’t remove the stylesheet’s element):
$('link[title="mystyle"]').prop('disabled', false);
In the code above, it is important to use .prop, not .attr. If you use .attr, the code will work in some browsers, but not Firefox. This is because, according to MDN, disabled is a property of the HTMLLinkElement DOM object, but not an attribute of the link HTML element. Using disabled as an HTML attribute is nonstandard.
no jQuery solution
if you can add id to your link tag
<link rel="stylesheet" href="css/animations.css" id="styles-animations">
document.getElementById("styles-animations").disabled = true;
if you know index position of your css file in document
document.styleSheets[0].disabled = true; // first
document.styleSheets[document.styleSheets.length - 1].disabled = true; // last
if you want to disable style by name you can use this function
/**
* #param [string] [styleName] [filename with suffix e.g. "style.css"]
* #param [boolean] [disabled] [true disables style]
*/
var disableStyle = function(styleName, disabled) {
var styles = document.styleSheets;
var href = "";
for (var i = 0; i < styles.length; i++) {
href = styles[i].href.split("/");
href = href[href.length - 1];
if (href === styleName) {
styles[i].disabled = disabled;
break;
}
}
};
note: make sure style file name is unique so you don't have "dir1/style.css" and "dir2/style.css". In that case it would disable only first style.
Using pure javascript:
var stylesheet = document.getElementById('stylesheetID');
stylesheet.parentNode.removeChild(stylesheet);
To remove a stylesheet:
$('link[src="<path>"]').remove();
To Replace a stylesheet:
$('link[src="<path>"]').attr('src','<NEW_FILE_PATH>');
If you want to do it only with the href attribute:
$('link[href="https://example.com/mycss.css"]').remove()
ES6 solution:
const disableStyle = styleName => {
const styles = document.styleSheets;
let href = "";
for (let i = 0; i < styles.length; i++) {
if (!styles[i].href) {
continue;
}
href = styles[i].href.split("/");
href = href[href.length - 1];
if (href === styleName) {
styles[i].disabled = true;
break;
}
}
};
Use it like disableStyle("MyUnwantedFile.css");.
Here's both an add & remove using the disabling principle mentioned in a number of these other posts to prevent cross browser issues. Note how my add checks to see if the sheet already exists, in which case it just enables it. Also, in contrast to some answers, this is designed to work using the url to a .css file as the sole argument to the functions (insulating the client from the use of id or title attributes).
function element( id ){ return document.getElementById( id ); }
function addStyleSheet( url ){
var id = _styleSheetUrlToId( url );
if( !_enableStyleSheet( id ) ) {
var link = document.createElement("link");
link.href = url;
link.type = "text/css";
link.rel = "stylesheet";
link.id = id;
document.getElementsByTagName("head")[0].appendChild( link );
}
}
function removeStyleSheet( url )
{ _enableStyleSheet( _styleSheetUrlToId( url ), false ); }
// "protected" function
function _styleSheetUrlToId( url ){
var urlParts = url.split("/");
return urlParts[urlParts.length-1].split(".")[0]
+ "-style";
}
// "protected" function
// returns if the sheet was found
function _enableStyleSheet( id, enable ) {
if( typeof(enable) == "undefined" ) enable = true;
var sheet = element( id );
if( sheet ) {
sheet.disabled = !enable;
return true;
}
return false;
}