Rendering HTML Within <script> Tag - javascript

I'm injecting some HTML into my page using this code:
<script>
window.onload = function() {
addHeader();
};
</script>
<script>function addHeader(){$("#header-nav-studio").after('<li id="header-nav-products" class="has-subnav"> Pricing  <span class="arrow-down"></span> <div class="header-subnav"> <ul> <li> Apparel Pricing</li><li> Sticker Pricing</li><li> Pinback Button Pricing</li></ul> </div></li>')}</script>
It works, loads everything directly after the "#header-nav-studio" DIV. Only problem is, it's not rendering the HTML within the script properly. It's supposed to generate a "Pricing" dropdown menu. Instead it only works as a link. You can see the example HERE
Is there a way to load the html properly within the script tag or load it from an external source? Thanks so much!

Looks like you need to bind mouseover event on DOM element you have dynamically added that triggers your submenu appearance.
On li element with class has-subnav, there is mouseover event listener, that toggles css class active on it.
You need to change your javascript, so the event is attached even for dynamically created elements. You can use $.on() on parent selector to attach handler.
$('body').on('mouseover', '.has-subnav', function() {
$(this).addClass('.active');
});
//and to remove class on mouseout
$('body').on('mouseover', '.has-subnav', function() {
$(this).removeClass('.active');
});

In the example you shared, the pricing menu item has id same as products menu item. Two nodes having same id can have unexpected results. I would say change the id first to say 'header-nav-pricing' and try your code again.

Related

Delete a selected div

Script explanation : I have a text area which user is typing notes and those notes are added to the DOM (as div elements) . I created an icon inside that divs that when you click on it i want the parent of the icon that is clicked to be removed from the DOM . I achieve this with JQuery , but i cant do it in pure JS. The code i use to achieve this in:
$('.fa-window-close').on('click', function(event){
event.preventDefault();
console.log($(this).parents('div')[0]);
$(this).parents('div')[0].remove();
});
Iam posting a link from gist, its a part code of my project so you can understand what iam trying to achieve.
https://gist.github.com/Clickys/43856fe26ee4c061cf910a9211f0c142
Basically what i want to achieve is , lets assume that we have a button that is creating divs elements inside DOM. Each of this div has an icon(fontawesome) that if we click on it , the selected target should be removed from the DOM(the target div) but not the other divs . I tried to use event.target and a lot of things but sadly i couldn't solve this with pure JS.
I tried this
closeTolPos.addEventListener('click', function(e){
var parentEl = e.currentTarget.parentNode.parentNode;
parentEl.removeChild(this.parentElement);
console.log(this.parentElement);
});
But it seems that when there are more than 1 element , it doesnt work . It only works if there is one element.
We make some changes and now the code works:
(function() {
document.addEventListener('click',function(e) {
if (e.target.closest('.notesDecoration')) {
e.target.closest('.notesDecoration').parentNode.removeChild(e.target.parentNode);
}
});
})();
Now click event is binded to a document, so the element exists, when the page is loaded. Then I check if the clicked element was the element, which was recently created and added to DOM.

Google Tag Manager click event not bubbling up to parent

I'm setting up Google Tag Manager on a client's site and I'm having trouble getting click event tags to fire.
I have the trigger set to fire on the button's CSS selector.
The button itself has some child elements, including an svg icon. When the svg is clicked, the click is registered in the data layer, but the tag is not fired. The tag only fires when I select the button itself.
I also tried removing event listeners in my own scripts that were attached to these buttons in case a return false; or e.stopPropagation() was blocking it, but this didn't change anything.
I had the understanding that GTM listens for click events that bubble up to the document. If this is the case my tag should fire when a child is clicked, right? Or am I misunderstanding something?
Alternatively, should I push the event to the dataLayer in my scripts rather than using a click trigger?
screenshots
10 gtm.click correctly fired the tag
9 gtm.click was the child svg that did not
The last screenshot is the firing rule for my trigger.
I've encountered this type of problem a lot. It happens with <i> tags for things like glyphicons as well. Simply add CSS pointer-events:none; to that SVG (unless you require that SVG to be clickable and not just the parentElement). The pointer-events:none on the SVG will mean that when it is clicked the click event registers on the parent element.
Best way would be to have the client developers add the JS. the more hacky way would be to run something like this in a custom HTML tag via GTM
jQuery('a.link-youre-tracking svg').css('pointer-events','none)
Grate solution/idea to use:
pointer-events:none
But what happens when you have complex div (20 classes and 15 elements inside) and you wrap this div with a link <a> tag (For blog postcard for example).
For now GTM lack of a normal solution for this issue :( For complex structure you should add "extra div" for pointer-events (Work fine but "not elegant").
<a class="track-this-click-by-gtm" href="url">
<div style="pointer-events:none">
extra unwanted div
<i></i>
<p>hello</p>
<ul><li>hello2</li></ul>
<date>2019</date>
lorem
</div>
</a>
As said before the “Just Links” trigger will bubble to the parent <a>, so using that instead of “All Elements” should solve any issues you have with clicks registering on children of an <a>. But what if you’re trying to register clicks on a parent <button>, for example? Then you could use a Custom JavaScript variable called “Find closest” with this function:
function () {
return function (target, selector) {
while (!target.matches(selector) && !target.matches('body')) {
target = target.parentElement;
}
return target.matches(selector) ? target : undefined;
}
}
And then use that function in another Custom JavaScript variable like this:
var elementFound = {{Find closest}}({{Click Element}}, 'button');
Read Simo Ahava’s article on this for more info.

ID assigned to click event not working in backbone.js?

Below is my html and I have given ids to my all li's ..
<ul id="color_wrap">
<li id="block4"></li>
</ul>
I'm novice to backbone.js. In my js file and in backbone.view part I have declared my code as shown below.
I have given width and height to that li and when I click on it does not work. I want to make all li's clickable please help me where it is wrong, why its not working.
When I click on li having id block4 it should call chooseColor function.
var SearchView = Backbone.View.extend({
el: $("#search_container"),
events: {
"click #block4": "chooseColor",
"focusout #search_input": "setDefaults"
},
chooseColor:function() {
alert("hi");
}
});
As per your JSFiddle, it's not working because you are binding your events to SearchView that has search_container as root element. block4 is not a child of search_container and will never be matched. I would suggest to create another View that represent color_wrap. Your click event, if declared in such a view, will work.
The problem is that all events added in the events block only listen to the element of the view not all elements in the page. So in your case # block4 is not a child element in the view.el element.
Take a look at the documented source code of backbone. There can you see that it use jQueries $el.on on the views element to bind the events.

dynamically adding a class to parent container from a dynamically added container using jquery

I have a method to dynamically add a container which is attached to the target container . When the action has been performed i removed the action container but now I have to add a class to parent container but problem is it is getting set (class name to parent container ) but it gets removed itself. For more clarification I am adding an sample code
<div class="main">
<ul>
<li>some contents</li>
................
................
</ul>
<ul class="dynamic_container">
<li>actions</li>
................
</ul>
</div>
dynamic_container is added when user mouseover the main class container and this get removed once action has been executed . But now it gets added(class name) but it gets removed too .
I believe this is basically because $(e.target) get removed ....
Any advice/suggestion will be appreciated . Thanks in advance.
edit :
$(e.target).parents('.main').addClass('current'); (this code does not able to add class to .main div) . This code is executed from ul.dynamic_container (which is added to the dom on mouseover on div.main)
edit 2:
jsfiddle link: this is the structure (not the actual code)
http://jsfiddle.net/CASy6/
Thanks for posting the fiddle. Now we can identify some problems that are preventing it from working.
The first problem is that when you try to move the mouse over the buttons, they disappear. If you add some console.log statements to the mouseover and mouseout handler functions, you will see that they get called way too much. This is due to the way these events work in a situation with nested elements.
jQuery provides a good solution to this problem: the mouseenter and mouseleave events. Read about them in the API docs, specifically the section describing the difference between mouseover and mouseenter.
See this fix implemented in this version of the jsFiddle: http://jsfiddle.net/CASy6/1/. With this, you can now actually click on the buttons, and also, a whole bunch of unnecessary .append() and .remove() calls are avoided.
The next problem is that no handler is called when you click a button.
The reason for this is that you set up the handlers by calling e.g.
$('li.first').on('click', function(e){ ... });
when the page loads, but at that moment, the selector li.first matches nothing, because you haven't appended the buttons to one of the divs yet. So handlers are only attached at page load, and they have nothing to attach to.
One solution for this problem is to use delegated events (see docs). This means we attach a handler to a container element (which is always present, including at page load), and handle events that bubble up from a descendant element.
In this case, we can attach a delegated event handler to the .main divs, which handles a click coming from one of the buttons:
$('div.main').on('click', 'button.first', function(e){
$(this).closest('.main').addClass('current');
alert('first action');
});
The second argument button.first is a selector which determines which descendant events will be handled by this handler. (I fixed the appended html so the class attribute is attached to the button element instead of the li element; it was inconsistent between the two buttons.)
See these fixes in action here: http://jsfiddle.net/CASy6/2/

Using jQuery on dynamically added content

I am newbie to jQuery and javascript. In my application I have a list of users. When a particular user is clicked from the list, a div element is replaced with details about the user dynamically. When another user is clicked, again I replace the same div element with this user details. So at a time only one user details can be seen.
I use jquery, so my code to the above description looks like.
$('table#moderate_users tr').click(function() {
$.get('/moderate/user/'+uid, function(data){ $('div.user_info').html(data);
});
});
This works perfect and the content is inserted dynamically.
I have a dropdown(html select tag) in the dynamically added content. So I get the dropdown only when i click on a user from the list and it changes repectively when I click on another user. I wanted to find the value of the select tag using jquery whenever it is changed. So I wrote
$('select#assign_role').change(function(){
alert(this.val());
});
Since this dropdown is added after document.ready, adding this script inside document.ready function never worked. I also tried to insert the above script along the with the user details which is dynamically added.For my surprise this script is not inserted into the document at all, while the rest of the HTML content are inserted perfect. I am not aware if i can add insert javascript after the document has loaded. I am not aware how i could use jQuery to find out the value of the select tag which is added dynamically.
Thanks.
you want jQuery's "live" functionality:
$('select#assign_role').live('change',function(){
alert($(this).val());
});
also notice I changed alert(this.val()); to alert($(this).val()); considering that this inside a jQuery event handler references the actual dom element, not a jQuery object.
From the looks of your code, it seems that you are inserting a chunk of HTML into that div. So even if you wire your event to the dropdown after the page load, it will not work, since all of your event binding will be ignored when you insert new HTML code into div.
Try moving your code inside the function that inserts HTML. Something like this:
$('table#moderate_users tr').click(function() {
$.get('/moderate/user/'+uid, function(data){
$('div.user_info').html(data);
$('select#assign_role').change(function(){
alert(this.val());
});
});
});
On IE the live function doesn't work for onchange on <select> elements.
http://www.neeraj.name/blog/articles/882-how-live-method-works-in-jquery-why-it-does-not-work-in-some-cases-when-to-use-livequery
You will need to either add the select then do a setTimeout and then bind with the jquery.bind type of functionality, or, what I have done, is when you create the element then just set the onchange event handler there directly.
If you don't need to support IE then the live function works great.

Categories