I've got this button:
<button class="dijitStretch dijitButtonNode dijitButtonContents dijitButton jStopThreads dijitButton" dojoattachevent="onclick:_onButtonClick,onmouseenter:_onMouse,onmouseover:_onMouse,onmouseout:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse" dojoattachpoint="focusNode,titleNode" type="button" wairole="button" waistate="labelledby-jStopThreads_label" role="button" aria-labelledby="jStopThreads_label" id="jStopThreads" tabindex="0" widgetid="jStopThreads" aria-valuenow="" aria-disabled="false" style="position: absolute; left: 76px; top: 528px; z-index: 3; width: 104px; height: 20px;"><span class="dijitInline " dojoattachpoint="iconNode"><span class="dijitToggleButtonIconChar">✓</span></span><span class="dijitButtonText" id="jStopThreads_label" dojoattachpoint="containerNode">
When I physically click on that button, the desired event triggers right, but It doesn't when I do using jQuery this way:
$('.jStopThreads').trigger("click");
or
$('.jStopThreads').click();
The button clicks because it focuses, but the event associated isn't triggered? How is this possible???
That's because jQuery can only trigger events, which were added via jQuery.
So, if you would add the event via jQuery like this:
$('.jStopThreads').click(function() {
// the content of your function
});
It could later be called via the jQuery functions trigger() or click()
It looks like you're using a library, Dojo, to attach your click event. Do it in jQuery:
function clickHandler(e) {
alert('clicked!');
}
$('.jStopThreads').on('click', clickHandler);
$('.jStopThreads').trigger("click");
http://jsfiddle.net/
Related
I have a Javascript application which allows users to enable/disable controls at runtime. I have been successful in disabling/enabling nested inputs and buttons, but so far I have had no success in disabling an onclick event in a Div, so that the circled icon will not be selectable:
The generated HTML looks like:
<div id="56f81c3d-9666-4dab-8f35-d36e894f426f" class="field alert-success">
<div class="field-name">By default I am disabled - Single Photo</div>
<div id="56f81c3d-9666-4dab-8f35-d36e894f426fPhoto" class="clearfix" style="cursor: pointer; max-width: 100%; max-height: 100%;" onclick="ffffield.getFieldHandler('PhotoPicker').showPhotoCapture(this, '56f81c3d-9666-4dab-8f35-d36e894f426f');">
<img class="pull-right" src="/MySite.Web/Content/device/images/chevronRight.png" style="width: 20px; position:relative; top: 7px;">
<img class="pull-right" src="/MySite.Web/Content/device/images/photoPickerPlaceholder#2x.png" style="width: 40px; position:relative; top: -5px;">
</div>
</div>
</div>.
In this snippet, it is the "onclick" that I need to disable. I am not picky - it can be disabling the pointer or the onclick.
I have tried the following attempts to make this work:
$("#56f81c3d-9666-4dab-8f35-d36e894f426f").children().off('click');
and
$("#56f81c3d-9666-4dab-8f35-d36e894f426f input").prop("disabled", true);
and
$("#"#56f81c3d-9666-4dab-8f35-d36e894f426f input").attr("disabled", true);
and
$(""#56f81c3d-9666-4dab-8f35-d36e894f426f input").attr("disabled", "disabled");
based on some other stackoverflow questions.
.off() can only disable event listeners that were added with .on() (or other jQuery methods, since they all call .on() internally). To remove an event listener that was added using the onclick attribute, you need to reassign the onclick property:
$("#56f81c3d-9666-4dab-8f35-d36e894f426f").children().prop('onclick', null);
Try this code:
function disableDiv( div ) {
div.addEventListener( "click", function ( event ) {
event.stopPropagation();
}, true );
}
// call the disable div handler
disableDiv( document.getElementById( "56f81c3d-9666-4dab-8f35-d36e894f426f" ) );
This question already has answers here:
How to stop events bubbling in jQuery? [duplicate]
(5 answers)
Closed 7 years ago.
I am trying to call a jQuery function when clicked only on parent element.
<div id="clcbox" class="click-img">
<img id="fire" onclick="createFirework()" src="img/clicker.png" />
</div>
I have an img tag inside a div. When I click on the div it should call one function and when I click on the img I want to call another function. How can I do this?
$('.click-img, .wishes').click(function () {
$('.flipWrapper').find('.card').toggleClass('flipped');
return false;
});
When I click the div I should call the above function. However now when I click on the image, it is also calling this function and createFirework().
The issue is due to event bubbling. If you attach your events in an unobtrusive manner you can easily stop this behaviour.
<div id="clcbox" class="click-img">
<img id="fire" src="img/clicker.png" />
</div>
$('#fire').click(function(e) {
e.stopPropagation();
createFirework();
});
$('.click-img, .wishes').click(function (e) {
$('.flipWrapper').find('.card').toggleClass('flipped');
e.preventDefault();
});
First off, don't mix inline (onclick) event handlers and jQuery event handlers. Once, you've got a jQuery event handler in place of your createFirework method, you simply stopPropagation to stop it calling the handler on the outer div.
Below is an example
$('.outer').click(function(e){
alert("You clicked text in the div");
});
$('.inner').click(function(e){
alert("You clicked the button, but the div event handler will not fire");
e.stopPropagation();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="outer">
<span>here is some text inside the div, click it</span>
<button class="inner">Click me</button>
</div>
You need to use stopPropagation function:
http://www.w3schools.com/jquery/event_stoppropagation.asp
In your case you need to add this on image click event:
$('.click-img, .wishes').click(function (event) {
event.stopPropagation();
$('.flipWrapper').find('.card').toggleClass('flipped');
return false;
});
It looks like you need to stop the click event from the image bubbling up the DOM chain.
$('.click-img, .wishes').click(function (e) {
$('.flipWrapper').find('.card').toggleClass('flipped');
e.stopPropagation();
});
When you click on the image, that event is passed up to it's parent, in this case the <div>. That is by behavior. To stop that from ocurring, you call the stopPropagation() function that is part of the incoming event argument for the click event.
You can use Event.stopPropagation(), to stop the click event bubble to its parents, but you also need to add a param event, so your function can access it without browser issue.
// VVVV pass `event` as createFirework's param.
<img id="fire" onclick="createFirework(event)" src="http://placehold.it/50x50" />
But I'd suggest that answers that separate js part and html part would be better. Just like Jamiec's.
function createFirework(event) {
console.log('inner');
event.stopPropagation();
}
$('.click-img, .wishes').click(function () {
console.log('outer');
return false;
});
#clcbox {
width: 100px;
height: 100px;
border: solid 1px black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="clcbox" class="click-img">
<img id="fire" onclick="createFirework(event)" src="http://placehold.it/50x50" />
</div>
I am trying to create a popup section that contains a form for someone to enter their email address when someone clicks on a link that says 'Mailing List.' The trouble is that when I click the link, the section doesn't appear. It works when I set it to hover but not click. I've run out of ideas on how to debug this. What am I missing?
HTML
<form class="mailing-list-input pull-right">
<input type="text" placeholder="Email Address" class="mailing-list-input">
<button class="mailing-list-btn">
<img src="/assets/arrow.png" style="height: 12px; width: 12px; margin-right: 6px;">
</button>
</form>
<footer class="footer footer-style">
<section class="container pull-right">
<ul class="list-inline btm-list">
<li class="btm-menu-width">
<a href="/" class="btm-menu-heading mailing-list">
Mailing List
</a>
</li>
</ul>
</section>
</footer>
CSS for .mailing-list-input
.mailing-list-input {
margin-right: 10rem;
display: none;
z-index: 98;
position: fixed;
bottom: 5rem;
right: 0;
}
Jquery File
$(document).ready(function() {
$(".mailing-list").click(function() {
$(".mailing-list-input").css('display', 'block');
},
function() {
$(".mailing-list-input").css('display', 'none')
})
})
The click function only accepts a single handler function. To achieve the behaviour you want, use a single handler and toggle() the element. Try this:
$(".mailing-list").click(function(e) {
e.preventDefault();
$(".mailing-list-input").toggle();
});
Example fiddle
Note I also added preventDefault() to stop the default link behaviour.
Based on what the OP appears to be trying to do this should be the Javascript:
$(".mailing-list").click(function(e) {
e.preventDefault();
if ($(".mailing-list-input").css('display') === 'block') {
$(".mailing-list-input").css('display', 'none');
} else {
$(".mailing-list-input").css('display', 'block');
}
});
The click handler callback takes an argument that is the event object, you can call preventDefault on that object to stop the event from continuing through its lifecycle. Then if you want the link to toggle the element on every click you check to see if the element is visible or not and set its value accordingly.
Here is a working fiddle
I have two buttons (on and off). When I click "on," I want to turn on the function called turnToolOn, and when I click "off," I want to turn off the function. I have this now:
$("body").on("click", "#turnOn", turnToolOn);
$("body").off("click", "#turnOff", turnToolOn);
The on() function is working, but I can't seem to get my function to stop executing when I click "off."
You need to wrap your on/off events in a "click" event, and use the ID of the actual element you're using as the button to activate it.
So, if you have a button <button id="turnOn">On</button> and <button id="turnOff">Off</button>:
$( "#turnOn" ).click(function() {
$( "body" )
.on( "click", turnToolOn )
});
$( "#turnOff" ).click(function() {
$( "body" )
.off( "click", turnToolOn )
});
Read more at the jQuery API Docs site for the off() event handler!
As said in the comments, the calls you have only enable/disable certain event listeners in the DOM. If you need functions that start/stop something, you need to define them. Assuming that turnToolOn does what you expect it to do, you need to write its "counter" function (say turnToolOff) and use that as a handler attached to your off button:
$("body").on("click", "#turnOn", turnToolOn);
$("body").on("click", "#turnOff", turnToolOff); /// <--- here it is
And if you don't plan to remove/add on/off buttons dynamically (you can't have more than one anyway since you're using IDs), you can drop the delegated event handler (on()) and use regular binding after the DOM is ready.
Here is a super simple example that uses this to toggle a class of an element:
$("body").on("click", "#turnOn", turnToolOn);
$("body").on("click", "#turnOff", turnToolOff);
function turnToolOn() {
$('#el').addClass('on');
}
function turnToolOff() {
$('#el').removeClass('on');
}
#el {
width: 50px;
height: 50px;
background: #eee;
}
#el.on {
background: #0c0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<button id="turnOn">On</button><button id="turnOff">Off</button>
<br />
<div id="el"></div>
And here is what on/off functions can do (binding/unbinding event handlers), so you can understand it better:
$("body").on("click", "#turnOn", turnToolOn);
$("body").on("click", "#turnOff", turnToolOff);
function turnToolOn() {
$("body").on("click", "#trigger", triggerCall);
alert('trigger handler attached');
}
function turnToolOff() {
$("body").off("click", "#trigger", triggerCall);
alert('trigger handler detached');
}
function triggerCall() {
$('#el').toggleClass('on');
}
#el {
width: 50px;
height: 50px;
background: #eee;
}
#el.on {
background: #0c0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<button id="turnOn">On</button><button id="turnOff">Off</button>
<button id="trigger">Trigger</button>
<br />
<div id="el"></div>
In the following example, when I mouse over the 'X' button, the list-item hover style gets enabled as well, I do not want this to happen.
Is it possible to have a hover style on the button independent of the hover style on the list-group-item? Something like prevent the 'hover' propagation?
Is there any other way to achieve that? Maybe assembling all of this HTML/CSS/JS in a different way?
Working sample here
<ul class="list-group">
<li class="list-group-item">
Lalalalaiaia
<button class="btn btn-default btn-xs pull-right remove-item">
<span class="glyphicon glyphicon-remove"></span>
</button>
</li>
<li class="list-group-item">
Panananannaeue
<button class="btn btn-default btn-xs pull-right remove-item">
<span class="glyphicon glyphicon-remove"></span>
</button>
</li>
</ul>
CSS
.list-group-item:hover {
background: #fafafa;
cursor: pointer;
}
JavaScript
$('.list-group-item').on('click', function(){
console.log('clicked item');
});
$('.remove-item').on('click', function(e){
console.log('clicked remove-item btn');
e.stopPropagation();
});
UPDATE
The problem seems to be that when hovering the inner X button, the mouse actually doesn't leave the 'list-group-item' element, thus, it keeps the hover state.
I was able to solve it by manually dispatching mouseenter and mouseleave on the 'list-group-item' in the mouseleave and mouseenter event of the 'remove-item' button, respectively, without the need to use 'event.stopPropagation()' (except for the button click handler).
The drawback is that I need a mouseenter and a mouseleave event handler for both elements. Preferably I'd use only CSS, but that seems to be impossible.
I'm just not sure whether this is a clean solution, what do you think?
Working sample here
CSS
.list-group-item.mouseover {
background: #fafafa;
cursor: pointer;
}
.list-group-item .remove-item.mouseover {
background: #aaf;
cursor: pointer;
}
JavaScript
// LIST-ITEM EVENT HANDLERS
$('.list-group-item').on('mouseenter', function(e){
$(this).addClass('mouseover');
}).on('mouseleave', function(e){
$(this).removeClass('mouseover');
});
$('.list-group-item').on('click', function(){
console.log('clicked item');
});
// LIST-ITEM REMOVE BUTTON EVENT HANDLERS
$('.remove-item').on('mouseenter', function(e){
$(this).addClass('mouseover');
$(this).parent().mouseleave();
}).on('mouseleave', function(e){
$(this).removeClass('mouseover');
$(this).parent().mouseenter();
});
$('.remove-item').on('click', function(e){
console.log('clicked remove-item btn');
e.stopPropagation();
});
This is impossible to do with CSS only, except the not-so-clean way described by #Pointy.
You can do this with javascript by using event.stopPropagation(). So your hover style should become a class that you toggle on mouseover.
This question is a duplicate of css :hover only affect top div of nest
You can make a negation caluse like Pointy suggests but a more solid solution involves adding an extra node. The idea is that the row and the button become proper siblings since you can't style a TextNode.
<ul class="list-group">
<li class="list-group-item">
<div>Lalalalaiaia</div>
<button class="btn btn-default btn-xs pull-right remove-item">
<span class="glyphicon glyphicon-remove"></span>
</button>
</li>
<li class="list-group-item">
<div>Panananannaeue</div>
<button class="btn btn-default btn-xs pull-right remove-item">
<span class="glyphicon glyphicon-remove"></span>
</button>
</li>
</ul>
Now you can do:
.list-group-item div:hover {
background: #fafafa;
cursor: pointer;
}
You will need some extra trickery to get the button in the right place, like:
// untested
.list-group-item {
position: relative;
}
.list-group-item button {
position: absolute;
top: 5px;
left: 5px;
}
Ok so there is actually a solution that only requires the use of CSS (no HTML or JS stuff)
The following selector will only select those elements with the class "parent" on hover, which do not have a child with the class "child" that is also being hovered on.
.parent:has(:not(.child:hover)):hover {}
The only problem I can see with the :has() selector/pseudo class is browser support (especially older versions) - so before you use it check the currerrent compatibility lists to see if it fits your requirements.
I could not find an answer that worked in all cases, and was also simple to implement. Sadly, there appears to be no consistent solution that is purely CSS and/or requires special arrangements of the HTML.
Here is a jQuery solution that seems to work in all cases.
Any element with .ui-hoverable will receive a .ui-hover class that does not propagate. So you can stack .ui-hoverable elements and only the top-most under the mouse will have the .ui-hover class.
$('.ui-hoverable').each(function() {
var el = $(this);
el.on('mousemove', function () {
var parent = $(event.target).closest('.ui-hoverable');
if(parent.length && parent[0] == el[0]) {
el.addClass('ui-hover');
return;
}
el.removeClass('ui-hover');
});
el.on('mouseleave', function () {
el.removeClass('ui-hover');
});
});
This works because the mousemove event searches for the closest .ui-hoverable and if it is not the current element the .ui-hover is removed. So the top most will receive the .ui-hover and an element under it will have it removed.
Enjoy, report any problems.
Thanks,