The idea is pretty simple, yet I cannot figure it out. Basically I want to save an element that was clicked in the sessionStorage. However, this is not easy because sessionStorage only takes strings.
I am attatching a click event to all my navigation buttons. (This does not work of course)
navButtons.addEventListener("click", function () {
sessionStorage['active-nav'] = $(this);
});
How would I save a DOM element and access it later?
EDIT
Basically when the page is reloaded, I want to keep track which element was clicked before and the apply some CSS to it once the new page is loaded. For example changing the background color of that element to orange, etc.
Therefore, I need to somehow save some information about that element in the sessionStorage and access the element/ find the element, once the page is reloaded. I used the approach of adding an Id to all elements and then using the javascript function document.getElementById("test"), to find it. However, there are quite a few navigation elements, so adding Ids to all of them would probably not be the cleanest solution. What would be the best way of solving this wihtout adding Ids to everything?
I'd say you should either:
Store it's id, then use document.querySelector() to reselect it using the stored id.
Produce & store a reverse selector, by using a library such as SimmerJS, then use document.querySelector() to reselect it using the stored selector.
Reverse selectors avoid the need to add explicit ids to all relevant elements.
Here's how reverse selectors work:
window.simmer = window.Simmer.configure({ depth: 10 })
document
.querySelector('.container')
.addEventListener('click', e => {
console.log(simmer(e.target))
})
<script src="https://cdn.jsdelivr.net/npm/simmerjs#0.5.6/dist/simmer.js"></script>
<div class="container">
<div class="left">
<button> Click Me </button>
</div>
<div class="right">
<button> Click Me </button>
</div>
</div>
Then save the produced selector and use it again to reselect the element on page load. No explicit ids needed.
Saving selectors avoids serialising & rehydrating HTML, so you don't loose any event listeners attached to the element, plus they won't take up a lot of storage space in case you plan to do this for a lot of elements.
You can set the sessionStorage value to .outerHTML of the element.
sessionStorage['active-nav'] = this.outerHTML;
If more data than only the HTML is needed you can store a JSON string at sessionStorage, where one of the values is the .outerHTML.
navButtons.addEventListener("click", function () {
sessionStorage.setItem('div', this.outerHTML);
});
Save using the outerHTML property of the element
To get the same element
var element=sessionStorage.getItem('div');
Related
There is a website with the following div:
<div class="x" style="user-select: none; filter: blur(4px);">
under this div there are a lot of other divs. I would like to know if there is any possibility to delete only this DIV with javascript. So only that one gets deleted and all the divs underneath remain.
I want to get rid of this DIV becouse this div blurs an part of the website text. Just changing the blur(4px) wont work the website has some kind of protection what refreshes this part back to original.
the reason i am searching for an possibility in javascript is because i want to automate this in the browser.(Just deleting DIV manually under developer mode works)
so far i got the following:
var div = document.getElementsByClassName('page-content');
div.remove(); //(but this does not work)
getElementsByClassName() returns a collection. Only single objects have remove() method. You have to apply one of the following:
Use brackets to specify an index of the object you want to get:
div[0].remove()
Use item() method passing the index as well:
div.item(0).remove()
Both ways are equivalent.
As an alternative, you may call querySelector() method:
const div = document.querySelector('.page-content')
It returns a single object (according to the passed CSS selector) so you can use:
div.remove()
Edit:
To remove only the covering div, you may use replaceWith() method and pass the child nodes of that div as an argument:
div.replaceWith(...div.childNodes)
If you want to keep only element nodes, use children property:
div.replaceWith(...div.children)
Using and html element's addEventListener has several advantages over using inline events, like onclick.
However, to store the element including its inline event is straight forward, for example, by embedding it in a parent element and storing the parent's innerHTML.
Is it possible to do something similar when using event listeners?
Edit:
I realized that my question is not sufficiently explained. So here some additions.
By "store" I mean a way to get the information holding the element and the event listener.
The analogue with inline events is easy: just embed in a parent element and save the parent's innerHTML (string) somewhere, for example in a database, and recreate the element later by loading the string and applying it to the innerHTML of some element.
But how would one do the analogue with elements when using event listeners? One cannot just use the innerHTML since then the events are not stored.
I hope this clarifies my question a bit.
Edit 2
With the help of comments I have made some unsuccessful attempts.
It is possible to get store the information of an element using createDocumentFragment() or element.cloneNode(true).
However, the first method does not work for external storage since, if I understood correctly, will contain only a pointer. Here is an example:
https://jsfiddle.net/hcpfv5Lu/
The second method does not work either. I am not fully sure why, but if I JSON.stringify the clone it "vanishes". Here is an example:
https://jsfiddle.net/3af001tq/
You could use a document fragment to store the DOM node in a JavaScript variable which can then be appended to a DOM element when required.
https://developer.mozilla.org/en/docs/Web/API/Document/createDocumentFragment
Yes.
You can use something like.
<ul>
<li id="list">Some data</li>
<li>Dumy</li>
</ul>
then in your javascript file,
document.getElementById("list").addEventListener("click", function(){
var htmlMarkUp = this.parentNode.innerHTML;
});
This would store the html content of ul in var htmlMarkUp.
This is my jquery scenario:
User click on div
It triggers an ajax call to save some data on DB
when callback received, we show an update msg <--everything good
until here
Now, when user click on the same element, it shows the information
from the DB, the same should happen with the other divs!
Noticed that when you click, the same text that you saved later is showing up in all the divs!!! it is not refreshing, but the actual source IS showing
the changes!
It looks like only the DOM is not reflecting the changes!
I am trying to put the text in the divs using .text();
All the divs are using the same element id!, I am just updating its data!
Thanks,
Marco
All the divs are using the same element id! - never ever should two elements have the same ID, because it breaks the principles on which HTML is built on and 3rd party libraries rely on.
If you need to target multiple elements use classes.
In case your elements have the class yourClass and you want to set them the text "foo", then
var yourResponseText = "foo";
$('.yourClass').text(yourResponseText);
Especially if you use jQuery - the ID selector is implemented in such way, that when it finds an element with that ID it doesn't look for another - the settings will only affect the first (from the viewpoint of DOM) element. On the other hand, when you're using the class selector, then simply said you're doing a forEach cycle through the elements with that class.
I am new to JavaScript and jQuery so let me know if I'm way off base.
I am using the cookie plugin from here: https://github.com/carhartl/jquery-cookie.
I have a page with dynamic links. They send the user to the same page they are already on with some GET information in the URL. I want to be able to highlight the previous link clicked.
My idea was to store the element that is clicked in a cookie and then add a class to that element.
Setting the cookie
$("td.column1").on({
click: function () {
$.cookie('productCookie', this); //How do I store 'this' into the cookie?
}
});
Getting the cookie
var productValue = $.cookie('productCookie');
$(productValue).addClass("select singleselected");
Code without cookies
I know from experience that this line of code worked before I added the links, which is also before the page was being redrawn.
$(this).addClass("select singleselected");
I've tried looking into how the this keyword works but I'm afraid I'm not sure what selector the addClass method is getting or how to get the current element.
Solution Used
function getParameters(geturl, columnNumber) {
var url = geturl,
urlRegExp = new RegExp(url.replace(/\/$/, ''));
$(columnNumber).each(function () {
if (urlRegExp.test(this.href)) {
$(this).addClass("singleselected select");
}
});
}
Check this thread out: jQuery add class .active on menu
The basic idea is that you parse the current url and find the anchor tag that is active based on the url.
If your elements have IDs, you can save the element's ID in a cookie and highlight it on the next pageload. Cookie (and localStorage, for that matter) can only store strings, or things that can be serialized to a string. HTML elements are not serializable.
Cookies hold strings. You will need to store some string-based indicator for which link was clicked.
It could be an id or a row number in your table or something like that. Then, when you read the cookie upon page load, you can find the DOM element that matches that indicator and change it accordingly.
You cannot store a DOM element reference in a cookie as DOM element references are not strings and they are not persistent from one page load to the next. A specific DOM element reference only exists during a given page.
If you show the actual HTML that covers what you want to save, we could make a more specific reference about what would make sense to save in the cookie. If it's a table, perhaps a row/column count (converted to string form). If every link has a unique id, then the easiest is to just store the id.
Given the following markup.
<div id="example">
<div>
<div>
<input type='hidden'></input>
</div>
</div>
</div>
How can I quickly get the hidden input element given I have the ID for the top most div element with the ID 'example'?
I can hack away at it so I can just iterate through each child element until I hit the input, however, I'd like to improve on that and utilize Prototype and simply jump to that hidden input given the div.
Thanks!
Prototype provides a whole bunch of ways to do this:
// This, from Bill's answer, is probably the fastest, since it uses the
// Browser's optimized selector engine to get straight to the element
$$('#example input[type=hidden]').first();
// This isn't bad either. You still use the browser's selector engine
// To get straight to the #example element, then you must traverse a
// (small) DOM tree.
//
// element.down(selector) selects the first node matching the selector which
// is an decendent of element
$('example').down('input');
// Here, you'll get an array containing all the inputs under 'example'. In your HTML
// there is only one.
$('example').select('input')
// You can also use element.select() to combine separate groups of elements,
// For instance, if you needed all the form elements:
$('example').select('input', 'textarea', 'select');
$$('#example input[type=hidden]').first()
I prefer the direct approach
document.forms[0].fieldName.value
Which is less code, no need to use jQuery and is more friendly to code design.