The goal here is to pass an element (one that is specifically being clicked on) using DOM Manipulation I wanted the svg element to appear with it's all it's applied styles. As of right now, the svg appears without any styling.
I'm thinking there's a way you can pass the clicked element with all of its stylings using this.getAttribute or this.content but those methods come back as undefined, which is why I currently use this.innerHtml (that at least gets clicked element and I can use DOM Manipulation with it).
added eventListeners to each svg element, paired with a function. this.innerHTML seemed to have worked (just the element and none of it's styling).
svg.addEventListener('click', function)
in the function below I used .content and getAttribute where it returned undefined
function () {
var clickedSVG = this.innerHTML
document.getElementById('container2').innerHTML = clickedSVG```
If you want to apply styles to an element on a click event you are going to want to add a class to the element using the classList property. Below is an example where you toggle an elements color on a click event.
First you create the HTML element you would like to toggle and give it an ID along with its default class:
<svg id="icon" class="not-clicked"></svg>
Then you create two CSS classes, one for the default stylings and another for the stylings to be applied on the click event:
.not-clicked {
background-color: black;
}
.clicked {
background-color: red;
}
Then you create a javascript function where you define what you want to happen to your element on the click event, and then call that function with an event listener:
function changeColor(el) {
if (el.classList.contains('not-clicked')) {
el.classList.add('clicked');
el.classList.remove('not-clicked')
} else {
el.classList.add('not-clicked');
el.classList.remove('clicked')
}
}
document.getElementById('icon').addEventListener('click', (e) => {
changeColor(e.target)
});
Related
Suppose I want to transform all (existing and dynamically created) <a> tags having a data-params property, e.g. by setting the href attribute.
It seems that this code:
$('body').on('change', 'a[data-params]', function() { ... })
only works on dynamically created elements, not existing elements.
On the other hand, this code:
$('a[data-params]').each(function(index) { ... });
only works on existing elements.
So if I want both (existing and dynamically created), I need both codes, ideally defining my transformation function first, then:
$('a[data-params]').each(function(index) { processDataParams(this); });
$('body').on('change', 'a[data-params]', function() { processDataParams(this); });
or am I missing some simpler way to do this?
$('a[data-params]') returns all nodes with this data attribute. Always.
I think that the problem is before, in the creation of dinamic elements. Avoid use the jQuery data method when you add the elements, because it does not update the DOM (don't adds the desired data-params attribute).
// Add some elements to the current doc
['magenta', 'olive'].forEach(color => {
$('<a>', {html:color})
// .data('params', color) <-- this don't updates de DOM, 👎 jQuery
.attr('data-params', color)
.appendTo('#root')
})
// Element unable to find with $('a[data-params]')
$('<a>', {html: 'This elemnt won\'t update'})
.data('params', 'purple')
.appendTo('#root')
function transform() {
$('a[data-params]').each((i, node) => {
$(node).css('color', $(node).data('params'))
$(node).attr('href', '#' + $(node).data('params'))
})
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div style="display: flex; flex-direction: column" id="root">
<a data-params='red'>red</a>
<a data-params='blue'>blue</a>
<a data-params='green'>green</a>
</div>
<hr>
<button onclick="transform()">Transform Elements</button>
Edited with the corrections of #Spectric and #RokoC.Buljan. Thanks to all.
You can use Jquery Event Delegation to run code (an event listener) on all child (internal) elements of an element, whether or not they already exist (because its set on the parent, which does already exist). You can read more about Event Delegation in JQuery's docs - https://learn.jquery.com/events/event-delegation/
Example:
$('ul').on('click', 'li', function(event) {
//code that will run on al <li> element clicks
});
this code is set on ul element, and allows an event listener to be set for all current and future li elements that are within the ul.
When adding a dynamically added element, how can I get attributes for that element (when clicking on it, for example)? I figured out that I need to delegate an event, but I still can't access any of the attributes of that event.
This JSFiddle shows the issue problem: https://jsfiddle.net/wgc499n9/
$(this).data('index') comes up as 'undefined' - I think $(this) is referencing 'document' instead of .remove_link; even the event data doesn't seem to have any useful information in it. $(this).attr('id') also comes up as 'undefined'.
In the end, I just need to be able to click that remove link to remove the row it's on. How can I accomplish that? I even tried inline JS, but that caused even stranger behavior.
P.S. I also learned that my dynamically added data-index attribute is not stored in the DOM; jQuery stores it separately, so its containing element has to be accessed by using .find()...but I can't figure out how to use .find() to access the specific individual elements I need.
Use element event(e) parameter instead this:
let i = 0;
$('#add').on('click', () => {
$('#container').append(`<div>row #${(i+1)} <a "href="#" data-index="${i}" class="remove_link">remove</a></div>`);
i++;
})
$(document).on('click', '.remove_link', (e) => {
//alert(JSON.stringify(e));
alert($(e.target).data('index'));
})
.remove_link {
color: red;
font-size: 0.8em;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<button id="add">Add row</button>
<div id="container"></div>
For more detail read difference b/w $(this) ans event.target.
In your event handler, this represent window. You have access to e.target to get the clicked element.
This should works:
$('#container').on('click', '.remove_link', (e) => {
alert($(e.target).data('index'));
})
This question already has answers here:
Setting CSS pseudo-class rules from JavaScript
(12 answers)
Closed 6 years ago.
I can use CSS to style an element so that it changes appearance when active. For instance:
.test:active {
background-color: yellow;
}
But how do I do this in javascript if I want to apply it to a specific element, not by class? I can set the background color for the default state using:
document.getElementById("myid").style.backgroundColor = "yellow"
But I can't do this:
document.getElementById("myid").style.active.backgroundColor = "yellow"
I don't want the javascript to respond to the element being active or not - I want to do a static initialization in javascript that then makes a specific element have a different color when it is active.
If the element was guaranteed to have an id I could use javascript to append a style sheet rule which used the #id selector, but I don't have this guarantee. All I can be sure of is I will get a reference to an element and I need to style it so that it has a different color when active.
You could use event listeners with the specific element.
When defining element, try this. You can of course make it a button or whatever:
<!-- in this case, using 'this' will refer to the element at hand. this way the element is targeted even if it has no ID or class -->
<input onfocus="elemFocused(this)" onblur="elemBlurred(this)">
This makes it so that when you focus the element (make it active), it runs the focused function. When it blurs (you select a different input or something), it runs the blurred function. In javascript:
function elemFocused(element){
element.style.backgroundColor = 'yellow'; // sets BG color to yellow
}
function elemBlurred(element){
element.style.backgroundColor = 'initial';// sets BG color to default; you can change if needed
}
I'm not certain that you have programatic access to the ':active' style directly, but you do have access to the active event so you can replicate it with something like this:
In your CSS add a css class to handle your active state, something like:
.active{
background-color: red;
}
Then just add the class on that event:
document.getElementById("myid").onfocus = function(){
this.className += "active";
};
document.getElementById("myid").onblur = function(){
this.className = "/*replace this with the original classes*/";
};
I have a list of buttons that is created by the DOM which references an array. When a button in the list is clicked, I want to retrieve the String that is displayed on the Button.
I have tried the following code to reference the string value, but get undefined:
this.String; inside the function when the button is clicked to retreive the string.
How can I properly retrieve the string.
The click handling function is:
$('.timeButtons').click(function() {
confirmation.push(this.textContent);
})
This is how the list of buttons is created:
var populateList=function(array){
var list = document.createElement('ul');
list.className="delete";
for(var i = 0; i < array.length;- i++) {
var item = document.createElement('li');
var itemButton=document.createElement('button');
itemButton.style.cssText='background:#f85a5a; border:none; width:200px; height:50px; margin-bottom:50px; align:center; border-radius:25px; color:#ffffff;'
itemButton.appendChild(document.createTextNode(array[i]));
item.appendChild(itemButton);
list.appendChild(item);
}
return list;
}
Assuming that this is a reference to the button element in question, you can use this.textContent to get the button's text. (Or .innerHTML.)
Demo: http://jsfiddle.net/w0ntsrLx/
Or since in your edited question you seem to be using jQuery, use the .text() method. In a comment you say that the containing div has the "timeButtons" class, so bind a delegated handler to that div as follows:
$(".timeButtons").on("click", "button", function(e) {
confirmation.push($(this).text());
});
Demo: http://jsfiddle.net/w0ntsrLx/1/
That way the function will only be called if the click is on a button element within the .timeButtons div, and this will be the clicked button. The click handler that you show in your question with $(".timeButtons").click(...) is bound to the div and doesn't in any way test for the buttons, so within the handler this will be the div, not the clicked button.
Check this out
Assuming you want pure javascript code,
Whenever an event is triggered, an object is passed back in callback (generally being named as 'event'). this object has many properties including source element, position of click and many more.
get the element using event.srcElement
You can use element.innerHTML or element.innerText to find out the content of the Button.
There is a difference between using innerText and innerHTML, but in your case, both can be used.
Also, you can use jquery too to easily append child, create elements and binding events.
Update: Everyone that contributed, it's well appreciated, you all are very kind and generous and all of you deserve my dear respect. Cheers.
Note: I'm making a simple jQuery tooltip plugin, the tooltip will fire on mouseover. The mouseover will create an instance of the div tool-tip that will be specific to each anchor that launched the div tool-tip. So each anchor with the class .c_tool will have its own created div that will erase after mouseout. Anyway all those details are irrelevant. What is important is how to create a div with .append() or .add() on and then find a way to call it and apply actions to that div without setting an identifier (id), class, or any means to identify it.
I know theres a way you could find the div by counting, so if you gave every created div the same class and then counted them to find that one, however I don't know if this is the most efficient method that is why I'm asking for help.
I'm not going to post the whole plugin script thats unnecessary, so I'll paste a simplified version.
hover me
hover me
$(document).ready(function() {
obj = $('a.c_tool');
obj.mouseover(function() {
/// append div to body it will be specific to each item with class c_tool, however I don't want to set an ID, or CLASS to the appended div
}).mouseout(function() {
/// remove added div without setting ID or class to it.
});
});
Working example:
http://jsfiddle.net/xzL6F/
$(document).ready(function() {
var tooltip;
obj = $('a.c_tool');
obj.mouseover(function() {
var element = $('<div>', {
html: "I'm a tooltip"
});
tooltip = element.appendTo($("body"));
/// append div to body it will be specific to each item with class c_tool, however I don't want to set an ID, or CLASS to the appended div
}).mouseout(function() {
tooltip.remove();
/// remove added div without setting ID or class to it.
});
});
To create a new DOM node you can use the jQuery constructor, like
$(document).ready(function() {
obj = $('a.c_tool');
obj.mouseover(function() {
if(!$.data(this, 'ref')) {
$.data(this, 'ref', $ref = $('<div>', {
html: 'Hello World!'
}).appendTo(document.body));
}
}).mouseout(function() {
$.data(this, 'ref').remove();
});
});
.appendTo() returns the DOM node of invocation (in this case, the newly created DIV) as jQuery object. That way you can store the reference in a variable for instance and access it later.
Referring your comment:
To remove all stored references, you should do this:
$('a.c_tool').each(function(index, node) {
$.removeData(node, 'ref');
});
you can use $.append(
);
http://api.jquery.com/append/
and to find the DOM created dynamically u can use
$("#dynamicallyCreatedDOMid").live("yourCustomTrigger",function(){
});
http://api.jquery.com/live/