1

I have an <ul> element and within it some <li> elements. The list item contains some content before the actual item by removing the standard dot with an x using list-style-type: none; and :before

HTML

<ul id="list1" class="basic">
    <li>space</li>
    <li>planet</li>
    <li>planet2</li>
</ul>

CSS

ul li:before {
    content:"x";
    position:relative;
    left:-25px;
}

JQuery

$("#list1").sortable();
$("#list1").disableSelection();

$("#list1").on("click", "li", function () {
    $(this).remove();
});

The idéa here is that when i click on the "x", the list item should be removed. But it does not matter where a user clicks since the remove function applies to the whole element.

So the question is: Is it possible to make only the "x" clickable to remove the whole item?

Full code on the JSfiddle:

https://jsfiddle.net/L15kygu4/

EDIT: It seems like th best way of accomplishing this is by making a <span> element and attach a click event to it rather than using pseudo-elements.

BorisMeister
  • 87
  • 1
  • 9
  • I have to remove the first second functions, because JSFiddle says that they doesn't exist. After removing then, the script works fine for me. If I click on a X, the LI on the side will removed. – Cagatay Ulubay Jun 18 '15 at 13:07
  • @CagatayUlubay you can click in any place of li and it remove – Grundy Jun 18 '15 at 13:08
  • 1
    Same procedure for before: http://stackoverflow.com/questions/17788990/access-the-css-after-selector-with-jquery – Wa Kai Jun 18 '15 at 13:10

4 Answers4

1

So the reason why the hole part is clickable is, because the X is part of the whole LI-Tag and you have no access to the :before and :after pseudo-element.

You can use following technique: Access the css ":after" selector with jQuery

Or you can just put another element in listen to it like following:

HTML

<div id="divlist1">
    <ul id="list1" class="basic">
        <li><span>x</span>space</li>
        <li><span>x</span>planet</li>
        <li><span>x</span>planet2</li>
    </ul>
</div>

Javascript / jQuery

$("#list1 span").on("click", function () {
    $(this).parent().remove();
});

JSFiddle: https://jsfiddle.net/L15kygu4/3/

Community
  • 1
  • 1
Cagatay Ulubay
  • 2,491
  • 1
  • 14
  • 26
  • This was exactly want i needed to know. Smart to use an span since it simulates the same effect and works better! Since there are two good answer here i would like to know the difference between the two, which one is more consistent? – BorisMeister Jun 18 '15 at 13:41
  • The difference is that you add the X with javascript which is unnecessary IMHO. I mean the closing X is something that should ALWAYS be there, so why don't just have it plain in html, but insert it exlusive with Javascript? It's better to have more text than actual code, google will love it if you have more text than code. But not only google, also the user will love it, if they are not depended on Javascript. Doing the "other way" will motivate you to do it in future too, but doing it right before will lead you to do the right way inbefore. What ever, if you like the other way, do it~ – Cagatay Ulubay Jun 18 '15 at 14:23
  • I played around with the code you provided and I managed to make it dynamic as well. Im actually changing the correct answer since it is more reliable. – BorisMeister Jun 18 '15 at 14:40
1

You can insert the X as a span with a given class using Jquery's .prepend() function. Then you can attach a click event handler to it, find the parent li element, and remove it.

You can't do this using the psuedo elements in css, because you can't insert html as a psuedo element. Since you can only insert text, not tags, you have nothing to register a click event handler for. The better solution is to add the 'X' using Jquery's DOM Manipulation Functions.

DOM Outer Manipulation Functions
DOM Inner Manipulation Functions

Updated JS Fiddle

JQUERY

$().ready(function () {
    //insert an X before the li element.
    $("#list1 li").prepend('<span class="del_x">X</span>');
    //attach click event handler to the X spans
    $(".del_x").click(function(){
       //find parent li element and remove
       $(this).parent('li').remove(); 
    });
});

CSS

.del_x{
    position: relative;
    left: -25px;
    cursor: pointer;
}
Brino
  • 2,442
  • 1
  • 21
  • 36
0

I dont think you can plave a click event on pseudo-elements as they are not part of the DOM.You can bind events to their parent elements.

Pseudo Elements has no HTMLElementNode object that represents it

Abhinav
  • 8,028
  • 12
  • 48
  • 89
0

A quick and dirty way to do this is (since you know the buttons are positioned to the left) is to compare where the click fell with the left offset of your element:

if ( event.clickX < $(this).offset().left ) $(this).remove();

NOTE: offset is a pretty heavy function. Don't use this if you're concerned about performance. If the elements are statically positioned (ie. they don't move around) you can improve this by only calculating the .offset() once and storing it in an outside variable.

Here's the fiddle updated: https://jsfiddle.net/tLtb3k43/

blgt
  • 8,135
  • 1
  • 25
  • 28
  • Which version of JQuery does this function works on? It does not work for me and i am using 1.8.3 – BorisMeister Jun 18 '15 at 14:16
  • The code itself should work regardless of jQuery version (later than 1.2). I swapped the version in the fiddle to 2.0.2 since the original fiddle you posted returned a `.sortable is undefined` error (in my browser at least). Maybe it's a jsfiddle bug. eg. https://jsfiddle.net/tLtb3k43/1/ – blgt Jun 18 '15 at 14:22